예제 #1
0
파일: environ.go 프로젝트: dennwc/cayley
func toQuadValue(o interface{}) (quad.Value, bool) {
	var qv quad.Value
	switch v := o.(type) {
	case quadValue:
		qv = v.v
	case quad.Value:
		qv = v
	case string:
		qv = quad.Raw(v)
	case bool:
		qv = quad.Bool(v)
	case int:
		qv = quad.Int(v)
	case int64:
		qv = quad.Int(v)
	case float64:
		if float64(int(v)) == v {
			qv = quad.Int(int64(v))
		} else {
			qv = quad.Float(v)
		}
	case time.Time:
		qv = quad.Time(v)
	default:
		return nil, false
	}
	return qv, true
}
예제 #2
0
파일: quadstore.go 프로젝트: dennwc/cayley
func toQuadValue(v value) quad.Value {
	if v == nil {
		return nil
	}
	switch d := v.(type) {
	case string:
		return quad.Raw(d) // compatibility
	case int64:
		return quad.Int(d)
	case float64:
		return quad.Float(d)
	case bool:
		return quad.Bool(d)
	case time.Time:
		return quad.Time(d)
	case bson.M: // TODO(dennwc): use raw document instead?
		so, ok := d["val"]
		if !ok {
			glog.Errorf("Error: Empty value in map: %v", v)
			return nil
		}
		s := so.(string)
		if len(d) == 1 {
			return quad.String(s)
		}
		if o, ok := d["iri"]; ok && o.(bool) {
			return quad.IRI(s)
		} else if o, ok := d["bnode"]; ok && o.(bool) {
			return quad.BNode(s)
		} else if o, ok := d["lang"]; ok && o.(string) != "" {
			return quad.LangString{
				Value: quad.String(s),
				Lang:  o.(string),
			}
		} else if o, ok := d["type"]; ok && o.(string) != "" {
			return quad.TypedString{
				Value: quad.String(s),
				Type:  quad.IRI(o.(string)),
			}
		}
		return quad.String(s)
	case []byte:
		var p proto.Value
		if err := p.Unmarshal(d); err != nil {
			glog.Errorf("Error: Couldn't decode value: %v", err)
			return nil
		}
		return p.ToNative()
	default:
		panic(fmt.Errorf("unsupported type: %T", v))
	}
}
예제 #3
0
파일: quad.go 프로젝트: dennwc/cayley
// ToNative converts protobuf Value to quad.Value.
func (m *Value) ToNative() (qv quad.Value) {
	if m == nil {
		return nil
	}
	switch v := m.Value.(type) {
	case *Value_Raw:
		return quad.Raw(v.Raw)
	case *Value_Str:
		return quad.String(v.Str)
	case *Value_Iri:
		return quad.IRI(v.Iri)
	case *Value_Bnode:
		return quad.BNode(v.Bnode)
	case *Value_TypedStr:
		return quad.TypedString{
			Value: quad.String(v.TypedStr.Value),
			Type:  quad.IRI(v.TypedStr.Type),
		}
	case *Value_LangStr:
		return quad.LangString{
			Value: quad.String(v.LangStr.Value),
			Lang:  v.LangStr.Lang,
		}
	case *Value_Int:
		return quad.Int(v.Int)
	case *Value_Float_:
		return quad.Float(v.Float_)
	case *Value_Boolean:
		return quad.Bool(v.Boolean)
	case *Value_Time:
		var t time.Time
		if v.Time == nil {
			t = time.Unix(0, 0).UTC()
		} else {
			t = time.Unix(v.Time.Seconds, int64(v.Time.Nanos)).UTC()
		}
		return quad.Time(t)
	default:
		panic(fmt.Errorf("unsupported type: %T", m.Value))
	}
}
예제 #4
0
파일: quadstore.go 프로젝트: dennwc/cayley
func (qs *QuadStore) NameOf(v graph.Value) quad.Value {
	if v == nil {
		glog.V(2).Info("NameOf was nil")
		return nil
	}
	hash := v.(NodeHash)
	if !hash.Valid() {
		glog.V(2).Info("NameOf was nil")
		return nil
	}
	if val, ok := qs.ids.Get(hash.String()); ok {
		return val.(quad.Value)
	}
	query := `SELECT
		value,
		value_string,
		datatype,
		language,
		iri,
		bnode,
		value_int,
		value_bool,
		value_float,
		value_time
	FROM nodes WHERE hash = $1 LIMIT 1;`
	c := qs.db.QueryRow(query, hash.toSQL())
	var (
		data   []byte
		str    sql.NullString
		typ    sql.NullString
		lang   sql.NullString
		iri    sql.NullBool
		bnode  sql.NullBool
		vint   sql.NullInt64
		vbool  sql.NullBool
		vfloat sql.NullFloat64
		vtime  pq.NullTime
	)
	if err := c.Scan(
		&data,
		&str,
		&typ,
		&lang,
		&iri,
		&bnode,
		&vint,
		&vbool,
		&vfloat,
		&vtime,
	); err != nil {
		glog.Errorf("Couldn't execute value lookup: %v", err)
		return nil
	}
	var val quad.Value
	if str.Valid {
		if iri.Bool {
			val = quad.IRI(str.String)
		} else if bnode.Bool {
			val = quad.BNode(str.String)
		} else if lang.Valid {
			val = quad.LangString{
				Value: quad.String(unescapeNullByte(str.String)),
				Lang:  lang.String,
			}
		} else if typ.Valid {
			val = quad.TypedString{
				Value: quad.String(unescapeNullByte(str.String)),
				Type:  quad.IRI(typ.String),
			}
		} else {
			val = quad.String(unescapeNullByte(str.String))
		}
	} else if vint.Valid {
		val = quad.Int(vint.Int64)
	} else if vbool.Valid {
		val = quad.Bool(vbool.Bool)
	} else if vfloat.Valid {
		val = quad.Float(vfloat.Float64)
	} else if vtime.Valid {
		val = quad.Time(vtime.Time)
	} else {
		qv, err := proto.UnmarshalValue(data)
		if err != nil {
			glog.Errorf("Couldn't unmarshal value: %v", err)
			return nil
		}
		val = qv
	}
	if val != nil {
		qs.ids.Put(hash.String(), val)
	}
	return val
}
예제 #5
0
파일: graphtest.go 프로젝트: dennwc/cayley
func TestLoadTypedQuads(t testing.TB, gen DatabaseFunc, conf *Config) {
	qs, opts, closer := gen(t)
	defer closer()

	w := MakeWriter(t, qs, opts)

	values := []quad.Value{
		quad.BNode("A"), quad.IRI("name"), quad.String("B"), quad.IRI("graph"),
		quad.IRI("B"), quad.Raw("<type>"),
		quad.TypedString{Value: "10", Type: "int"},
		quad.LangString{Value: "value", Lang: "en"},
		quad.Int(-123456789),
		quad.Float(-12345e-6),
		quad.Bool(true),
		quad.Time(time.Now()),
	}

	err := w.AddQuadSet([]quad.Quad{
		{values[0], values[1], values[2], values[3]},
		{values[4], values[5], values[6], nil},
		{values[4], values[5], values[7], nil},
		{values[0], values[1], values[8], nil},
		{values[0], values[1], values[9], nil},
		{values[0], values[1], values[10], nil},
		{values[0], values[1], values[11], nil},
	})
	require.Nil(t, err)
	for _, pq := range values {
		got := qs.NameOf(qs.ValueOf(pq))
		if !conf.UnTyped {
			if pt, ok := pq.(quad.Time); ok {
				var trim int64
				if conf.TimeInMcs {
					trim = 1000
				} else if conf.TimeInMs {
					trim = 1000000
				}
				if trim > 0 {
					tm := time.Time(pt)
					seconds := tm.Unix()
					nanos := int64(tm.Sub(time.Unix(seconds, 0)))
					if conf.TimeRound {
						nanos = (nanos/trim + ((nanos/(trim/10))%10)/5) * trim
					} else {
						nanos = (nanos / trim) * trim
					}
					pq = quad.Time(time.Unix(seconds, nanos).UTC())
				}
			}
			if eq, ok := pq.(quad.Equaler); ok {
				assert.True(t, eq.Equal(got), "Failed to roundtrip %q (%T), got %q (%T)", pq, pq, got, got)
			} else {
				assert.Equal(t, pq, got, "Failed to roundtrip %q (%T)", pq, pq)
				if !conf.NoHashes {
					assert.Equal(t, pq, qs.NameOf(qs.ValueOf(quad.Raw(pq.String()))), "Failed to exchange raw value %q (%T)", pq, pq)
				}
			}
		} else {
			assert.Equal(t, quad.StringOf(pq), quad.StringOf(got), "Failed to roundtrip raw %q (%T)", pq, pq)
		}
	}
	require.Equal(t, int64(7), qs.Size(), "Unexpected quadstore size")
}