Beispiel #1
0
// ToNative converts protobuf Quad to quad.Quad.
func (m *Quad) ToNative() (q quad.Quad) {
	if m == nil {
		return
	}
	if m.SubjectValue != nil {
		q.Subject = m.SubjectValue.ToNative()
	} else if m.Subject != "" {
		q.Subject = quad.Raw(m.Subject)
	}
	if m.PredicateValue != nil {
		q.Predicate = m.PredicateValue.ToNative()
	} else if m.Predicate != "" {
		q.Predicate = quad.Raw(m.Predicate)
	}
	if m.ObjectValue != nil {
		q.Object = m.ObjectValue.ToNative()
	} else if m.Object != "" {
		q.Object = quad.Raw(m.Object)
	}
	if m.LabelValue != nil {
		q.Label = m.LabelValue.ToNative()
	} else if m.Label != "" {
		q.Label = quad.Raw(m.Label)
	}
	return
}
Beispiel #2
0
func TestRemoveQuad(t *testing.T) {
	qs, w, _ := makeTestStore(simpleGraph)

	err := w.RemoveQuad(quad.MakeRaw(
		"E",
		"follows",
		"F",
		"",
	))

	if err != nil {
		t.Error("Couldn't remove quad", err)
	}

	fixed := qs.FixedIterator()
	fixed.Add(qs.ValueOf(quad.Raw("E")))

	fixed2 := qs.FixedIterator()
	fixed2.Add(qs.ValueOf(quad.Raw("follows")))

	innerAnd := iterator.NewAnd(qs)
	innerAnd.AddSubIterator(iterator.NewLinksTo(qs, fixed, quad.Subject))
	innerAnd.AddSubIterator(iterator.NewLinksTo(qs, fixed2, quad.Predicate))

	hasa := iterator.NewHasA(qs, innerAnd, quad.Object)

	newIt, _ := hasa.Optimize()
	if newIt.Next() {
		t.Error("E should not have any followers.")
	}
}
Beispiel #3
0
func TestMultipleConstraintParse(t *testing.T) {
	qs, _ := graph.NewQuadStore("memstore", "", nil)
	w, _ := graph.NewQuadWriter("single", qs, nil)
	for _, tv := range []quad.Quad{
		quad.MakeRaw("i", "like", "food", ""),
		quad.MakeRaw("i", "like", "beer", ""),
		quad.MakeRaw("you", "like", "beer", ""),
	} {
		w.AddQuad(tv)
	}
	query := `(
		$a
		(:like :beer)
		(:like "food")
	)`
	it := BuildIteratorTreeForQuery(qs, query)
	if it.Type() != graph.And {
		t.Errorf("Odd iterator tree. Got: %#v", it.Describe())
	}
	if !it.Next() {
		t.Error("Got no results")
	}
	out := it.Result()
	if out != qs.ValueOf(quad.Raw("i")) {
		t.Errorf("Got %d, expected %d", out, qs.ValueOf(quad.Raw("i")))
	}
	if it.Next() {
		t.Error("Too many results")
	}
}
func TestSQLLinkIteration(t *testing.T) {
	if *postgres_path == "" {
		t.SkipNow()
	}
	db, err := newQuadStore(*postgres_path, nil)
	qs := db.(*QuadStore)
	if err != nil {
		t.Fatal(err)
	}
	it := NewSQLLinkIterator(qs, quad.Object, quad.Raw("Humphrey Bogart"))
	for it.Next() {
		fmt.Println(it.Result())
	}
	it = NewSQLLinkIterator(qs, quad.Subject, quad.Raw("/en/casablanca_1942"))
	s, v := it.sql.buildSQL(true, nil)
	t.Log(s, v)
	c := 0
	for it.Next() {
		fmt.Println(it.Result())
		c += 1
	}
	if c != 18 {
		t.Errorf("Not enough results, got %d expected 18", c)
	}
}
Beispiel #5
0
func TestIterators(t *testing.T) {
	qs, opts, closer := makeGAE(t)
	defer closer()

	graphtest.MakeWriter(t, qs, opts, graphtest.MakeQuadSet()...)

	require.Equal(t, int64(11), qs.Size(), "Incorrect number of quads")

	var expected = []quad.Quad{
		quad.MakeRaw("C", "follows", "B", ""),
		quad.MakeRaw("C", "follows", "D", ""),
	}

	it := qs.QuadIterator(quad.Subject, qs.ValueOf(quad.Raw("C")))
	graphtest.ExpectIteratedQuads(t, qs, it, expected)

	// Test contains
	it = qs.QuadIterator(quad.Label, qs.ValueOf(quad.Raw("status_graph")))
	gqs := qs.(*QuadStore)
	key := gqs.createKeyForQuad(quad.MakeRaw("G", "status", "cool", "status_graph"))
	token := &Token{quadKind, key.StringID()}

	require.True(t, it.Contains(token), "Contains failed")

	// Test cloning an iterator
	var it2 graph.Iterator
	it2 = it.Clone()
	x := it2.Describe()
	y := it.Describe()

	require.Equal(t, y.Name, x.Name, "Iterator Clone was not successful")
}
Beispiel #6
0
func TestInterestingQuery(t *testing.T) {
	if *postgres_path == "" {
		t.SkipNow()
	}
	db, err := newQuadStore(*postgres_path, nil)
	if err != nil {
		t.Fatal(err)
	}
	qs := db.(*QuadStore)
	a := NewSQLLinkIterator(qs, quad.Object, quad.Raw("Humphrey Bogart"))
	b := NewSQLLinkIterator(qs, quad.Predicate, quad.Raw("name"))
	it1, err := intersect(a.sql, b.sql, qs)
	if err != nil {
		t.Error(err)
	}
	it2, err := hasa(it1.sql, quad.Subject, qs)
	if err != nil {
		t.Error(err)
	}
	it2.Tagger().Add("hb")
	it3, err := linksto(it2.sql, quad.Object, qs)
	if err != nil {
		t.Error(err)
	}
	b = NewSQLLinkIterator(db.(*QuadStore), quad.Predicate, quad.Raw("/film/performance/actor"))
	it4, err := intersect(it3.sql, b.sql, qs)
	if err != nil {
		t.Error(err)
	}
	it5, err := hasa(it4.sql, quad.Subject, qs)
	if err != nil {
		t.Error(err)
	}
	it6, err := linksto(it5.sql, quad.Object, qs)
	if err != nil {
		t.Error(err)
	}
	b = NewSQLLinkIterator(db.(*QuadStore), quad.Predicate, quad.Raw("/film/film/starring"))
	it7, err := intersect(it6.sql, b.sql, qs)
	if err != nil {
		t.Error(err)
	}
	it8, err := hasa(it7.sql, quad.Subject, qs)
	if err != nil {
		t.Error(err)
	}
	s, v := it8.sql.buildSQL(true, nil)
	it8.Tagger().Add("id")
	t.Log(s, v)
	for it8.Next() {
		t.Log(it8.Result())
		out := make(map[string]graph.Value)
		it8.TagResults(out)
		for k, v := range out {
			t.Log("%s: %v\n", k, v)
		}
	}
}
Beispiel #7
0
func TestBuildIntersect(t *testing.T) {
	a := NewSQLLinkIterator(nil, quad.Subject, quad.Raw("Foo"))
	b := NewSQLLinkIterator(nil, quad.Predicate, quad.Raw("is_equivalent_to"))
	it, err := intersect(a.sql, b.sql, nil)
	if err != nil {
		t.Error(err)
	}
	s, v := it.sql.buildSQL(true, nil)
	t.Log(s, v)
}
Beispiel #8
0
func hasaWithTag(qs graph.QuadStore, tag string, target string) *HasA {
	and := NewAnd(qs)

	obj := qs.FixedIterator()
	obj.Add(qs.ValueOf(quad.Raw(target)))
	obj.Tagger().Add(tag)
	and.AddSubIterator(NewLinksTo(qs, obj, quad.Object))

	pred := qs.FixedIterator()
	pred.Add(qs.ValueOf(quad.Raw("status")))
	and.AddSubIterator(NewLinksTo(qs, pred, quad.Predicate))

	return NewHasA(qs, and, quad.Subject)
}
Beispiel #9
0
func TestBuildHasa(t *testing.T) {
	a := NewSQLLinkIterator(nil, quad.Subject, quad.Raw("Foo"))
	a.Tagger().Add("foo")
	b := NewSQLLinkIterator(nil, quad.Predicate, quad.Raw("is_equivalent_to"))
	it1, err := intersect(a.sql, b.sql, nil)
	if err != nil {
		t.Error(err)
	}
	it2, err := hasa(it1.sql, quad.Object, nil)
	if err != nil {
		t.Error(err)
	}
	s, v := it2.sql.buildSQL(true, nil)
	t.Log(s, v)
}
Beispiel #10
0
func TestIteratorsAndNextResultOrderA(t *testing.T) {
	qs, _, _ := makeTestStore(simpleGraph)

	fixed := qs.FixedIterator()
	fixed.Add(qs.ValueOf(quad.Raw("C")))

	fixed2 := qs.FixedIterator()
	fixed2.Add(qs.ValueOf(quad.Raw("follows")))

	all := qs.NodesAllIterator()

	innerAnd := iterator.NewAnd(qs)
	innerAnd.AddSubIterator(iterator.NewLinksTo(qs, fixed2, quad.Predicate))
	innerAnd.AddSubIterator(iterator.NewLinksTo(qs, all, quad.Object))

	hasa := iterator.NewHasA(qs, innerAnd, quad.Subject)
	outerAnd := iterator.NewAnd(qs)
	outerAnd.AddSubIterator(fixed)
	outerAnd.AddSubIterator(hasa)

	if !outerAnd.Next() {
		t.Error("Expected one matching subtree")
	}
	val := outerAnd.Result()
	if qs.NameOf(val) != quad.Raw("C") {
		t.Errorf("Matching subtree should be %s, got %s", "barak", qs.NameOf(val))
	}

	var (
		got    []string
		expect = []string{"B", "D"}
	)
	for {
		got = append(got, qs.NameOf(all.Result()).String())
		if !outerAnd.NextPath() {
			break
		}
	}
	sort.Strings(got)

	if !reflect.DeepEqual(got, expect) {
		t.Errorf("Unexpected result, got:%q expect:%q", got, expect)
	}

	if outerAnd.Next() {
		t.Error("More than one possible top level output?")
	}
}
Beispiel #11
0
func TestLinksToOptimization(t *testing.T) {
	qs, _, _ := makeTestStore(simpleGraph)

	fixed := qs.FixedIterator()
	fixed.Add(qs.ValueOf(quad.Raw("cool")))

	lto := iterator.NewLinksTo(qs, fixed, quad.Object)
	lto.Tagger().Add("foo")

	newIt, changed := lto.Optimize()
	if !changed {
		t.Error("Iterator didn't change")
	}
	if newIt.Type() != Type() {
		t.Fatal("Didn't swap out to LLRB")
	}

	v := newIt.(*Iterator)
	vClone := v.Clone()
	origDesc := v.Describe()
	cloneDesc := vClone.Describe()
	origDesc.UID, cloneDesc.UID = 0, 0 // We are more strict now, so fake UID equality.
	if !reflect.DeepEqual(cloneDesc, origDesc) {
		t.Fatalf("Unexpected iterator description.\ngot: %#v\nexpect: %#v", cloneDesc, origDesc)
	}
	vt := vClone.Tagger()
	if len(vt.Tags()) < 1 || vt.Tags()[0] != "foo" {
		t.Fatal("Tag on LinksTo did not persist")
	}
}
func TestSQLNodeIteration(t *testing.T) {
	if *postgres_path == "" {
		t.SkipNow()
	}
	db, err := newQuadStore(*postgres_path, nil)
	if err != nil {
		t.Fatal(err)
	}
	link := NewSQLLinkIterator(db.(*QuadStore), quad.Object, quad.Raw("/en/humphrey_bogart"))
	it := &SQLIterator{
		uid: iterator.NextUID(),
		qs:  db.(*QuadStore),
		sql: &SQLNodeIterator{
			tableName: newTableName(),
			linkIt: sqlItDir{
				it:  link.sql,
				dir: quad.Subject,
			},
		},
	}
	s, v := it.sql.buildSQL(true, nil)
	t.Log(s, v)
	c := 0
	for it.Next() {
		t.Log(it.Result())
		c += 1
	}
	if c != 56 {
		t.Errorf("Not enough results, got %d expected 56", c)
	}

}
Beispiel #13
0
func TestIteratorsAndNextResultOrderA(t testing.TB, gen DatabaseFunc) {
	qs, opts, closer := gen(t)
	defer closer()

	MakeWriter(t, qs, opts, MakeQuadSet()...)

	require.Equal(t, int64(11), qs.Size(), "Incorrect number of quads")

	fixed := qs.FixedIterator()
	fixed.Add(qs.ValueOf(quad.Raw("C")))

	fixed2 := qs.FixedIterator()
	fixed2.Add(qs.ValueOf(quad.Raw("follows")))

	all := qs.NodesAllIterator()

	innerAnd := iterator.NewAnd(qs)
	innerAnd.AddSubIterator(iterator.NewLinksTo(qs, fixed2, quad.Predicate))
	innerAnd.AddSubIterator(iterator.NewLinksTo(qs, all, quad.Object))

	hasa := iterator.NewHasA(qs, innerAnd, quad.Subject)
	outerAnd := iterator.NewAnd(qs)
	outerAnd.AddSubIterator(fixed)
	outerAnd.AddSubIterator(hasa)

	require.True(t, outerAnd.Next(), "Expected one matching subtree")

	val := outerAnd.Result()
	require.Equal(t, quad.Raw("C"), qs.NameOf(val))

	var (
		got    []string
		expect = []string{"B", "D"}
	)
	for {
		got = append(got, qs.NameOf(all.Result()).String())
		if !outerAnd.NextPath() {
			break
		}
	}
	sort.Strings(got)

	require.Equal(t, expect, got)

	require.True(t, !outerAnd.Next(), "More than one possible top level output?")
}
Beispiel #14
0
func (m *Quad) Upgrade() {
	if m.SubjectValue == nil {
		m.SubjectValue = MakeValue(quad.Raw(m.Subject))
		m.Subject = ""
	}
	if m.PredicateValue == nil {
		m.PredicateValue = MakeValue(quad.Raw(m.Predicate))
		m.Predicate = ""
	}
	if m.ObjectValue == nil {
		m.ObjectValue = MakeValue(quad.Raw(m.Object))
		m.Object = ""
	}
	if m.LabelValue == nil && m.Label != "" {
		m.LabelValue = MakeValue(quad.Raw(m.Label))
		m.Label = ""
	}
}
Beispiel #15
0
func (qs *store) valueAt(i int) quad.Value {
	if !qs.parse {
		return quad.Raw(qs.data[i])
	}
	iv, err := strconv.Atoi(qs.data[i])
	if err == nil {
		return quad.Int(iv)
	}
	return quad.String(qs.data[i])
}
Beispiel #16
0
func TestTreeConstraintParse(t *testing.T) {
	qs, _ := graph.NewQuadStore("memstore", "", nil)
	w, _ := graph.NewQuadWriter("single", qs, nil)
	w.AddQuad(quad.MakeRaw("i", "like", "food", ""))
	w.AddQuad(quad.MakeRaw("food", "is", "good", ""))
	query := "(\"i\"\n" +
		"(:like\n" +
		"($a (:is :good))))"
	it := BuildIteratorTreeForQuery(qs, query)
	if it.Type() != graph.And {
		t.Errorf("Odd iterator tree. Got: %#v", it.Describe())
	}
	if !it.Next() {
		t.Error("Got no results")
	}
	out := it.Result()
	if out != qs.ValueOf(quad.Raw("i")) {
		t.Errorf("Got %d, expected %d", out, qs.ValueOf(quad.Raw("i")))
	}
}
Beispiel #17
0
// GetNativeValue returns the value stored in Node.
func (m *NodeData) GetNativeValue() quad.Value {
	if m == nil {
		return nil
	} else if m.Value == nil {
		if m.Name == "" {
			return nil
		}
		return quad.Raw(m.Name)
	}
	return m.Value.ToNative()
}
Beispiel #18
0
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 {
			clog.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 {
			clog.Errorf("Error: Couldn't decode value: %v", err)
			return nil
		}
		return p.ToNative()
	default:
		panic(fmt.Errorf("unsupported type: %T", v))
	}
}
Beispiel #19
0
func TestHorizonInt(t testing.TB, gen DatabaseFunc, conf *Config) {
	qs, opts, closer := gen(t)
	defer closer()

	w := MakeWriter(t, qs, opts)

	horizon := qs.Horizon()
	require.Equal(t, int64(0), horizon.Int(), "Unexpected horizon value")

	err := w.AddQuadSet(MakeQuadSet())
	require.Nil(t, err)
	require.Equal(t, int64(11), qs.Size(), "Unexpected quadstore size")

	if qss, ok := qs.(ValueSizer); ok {
		s := qss.SizeOf(qs.ValueOf(quad.Raw("B")))
		require.Equal(t, int64(5), s, "Unexpected quadstore value size")
	}

	horizon = qs.Horizon()
	require.Equal(t, int64(11), horizon.Int(), "Unexpected horizon value")

	err = w.RemoveQuad(quad.MakeRaw(
		"A",
		"follows",
		"B",
		"",
	))
	require.Nil(t, err)
	if !conf.SkipSizeCheckAfterDelete {
		require.Equal(t, int64(10), qs.Size(), "Unexpected quadstore size after RemoveQuad")
	} else {
		require.Equal(t, int64(11), qs.Size(), "Unexpected quadstore size")
	}

	if qss, ok := qs.(ValueSizer); ok {
		s := qss.SizeOf(qs.ValueOf(quad.Raw("B")))
		require.Equal(t, int64(4), s, "Unexpected quadstore value size")
	}
}
Beispiel #20
0
func (qs *store) NameOf(v graph.Value) quad.Value {
	switch v.(type) {
	case Int64Node:
		i := int(v.(Int64Node))
		if i < 0 || i >= len(qs.data) {
			return nil
		}
		return qs.valueAt(i)
	case stringNode:
		if qs.parse {
			return quad.String(v.(stringNode))
		}
		return quad.Raw(v.(stringNode))
	default:
		return nil
	}
}
Beispiel #21
0
func TestMemstore(t *testing.T) {
	qs, _, index := makeTestStore(simpleGraph)
	if size := qs.Size(); size != int64(len(simpleGraph)) {
		t.Errorf("Quad store has unexpected size, got:%d expected %d", size, len(simpleGraph))
	}
	for _, test := range index {
		v := qs.ValueOf(quad.Raw(test.query))
		switch v := v.(type) {
		default:
			t.Errorf("ValueOf(%q) returned unexpected type, got:%T expected int64", test.query, v)
		case iterator.Int64Node:
			if int64(v) != test.value {
				t.Errorf("ValueOf(%q) returned unexpected value, got:%d expected:%d", test.query, v, test.value)
			}
		}
	}
}
Beispiel #22
0
func TestZeroRune(t *testing.T) {
	qs, opts, closer := makePostgres(t)
	defer closer()

	w := graphtest.MakeWriter(t, qs, opts)

	obj := quad.String("AB\u0000CD")
	if !utf8.ValidString(string(obj)) {
		t.Fatal("invalid utf8")
	}

	err := w.AddQuad(quad.Quad{
		Subject:   quad.IRI("bob"),
		Predicate: quad.IRI("pred"),
		Object:    obj,
	})
	require.Nil(t, err)
	require.Equal(t, obj, qs.NameOf(qs.ValueOf(quad.Raw(obj.String()))))
}
Beispiel #23
0
func TestLoadOneQuad(t testing.TB, gen DatabaseFunc) {
	qs, opts, closer := gen(t)
	defer closer()

	w := MakeWriter(t, qs, opts)

	err := w.AddQuad(quad.MakeRaw(
		"Something",
		"points_to",
		"Something Else",
		"context",
	))
	require.Nil(t, err)
	for _, pq := range []string{"Something", "points_to", "Something Else", "context"} {
		got := quad.StringOf(qs.NameOf(qs.ValueOf(quad.Raw(pq))))
		require.Equal(t, pq, got, "Failed to roundtrip %q", pq)
	}
	require.Equal(t, int64(1), qs.Size(), "Unexpected quadstore size")
}
Beispiel #24
0
func TestDeletedFromIterator(t testing.TB, gen DatabaseFunc) {
	qs, opts, closer := gen(t)
	defer closer()

	w := MakeWriter(t, qs, opts, MakeQuadSet()...)

	// Subject iterator.
	it := qs.QuadIterator(quad.Subject, qs.ValueOf(quad.Raw("E")))

	ExpectIteratedQuads(t, qs, it, []quad.Quad{
		quad.MakeRaw("E", "follows", "F", ""),
	})

	it.Reset()

	w.RemoveQuad(quad.MakeRaw("E", "follows", "F", ""))

	ExpectIteratedQuads(t, qs, it, nil)
}
Beispiel #25
0
// 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))
	}
}
Beispiel #26
0
func TestLinksTo(t *testing.T) {
	qs := &store{
		data: []string{1: "cool"},
		iter: NewFixed(Identity),
	}
	qs.iter.(*Fixed).Add(Int64Quad(2))
	fixed := NewFixed(Identity)
	val := qs.ValueOf(quad.Raw("cool"))
	if val.(Int64Node) != 1 {
		t.Fatalf("Failed to return correct value, got:%v expect:1", val)
	}
	fixed.Add(val)
	lto := NewLinksTo(qs, fixed, quad.Object)
	if !lto.Next() {
		t.Error("At least one quad matches the fixed object")
	}
	val = lto.Result()
	if val.(Int64Quad) != 2 {
		t.Errorf("Quad index 2, such as %s, should match %s", qs.Quad(Int64Quad(2)), qs.Quad(val))
	}
}
Beispiel #27
0
func TestOptimize(t *testing.T) {
	qs, opts, closer := makeBolt(t)
	defer closer()

	graphtest.MakeWriter(t, qs, opts, graphtest.MakeQuadSet()...)

	// With an linksto-fixed pair
	fixed := qs.FixedIterator()
	fixed.Add(qs.ValueOf(quad.Raw("F")))
	fixed.Tagger().Add("internal")
	lto := iterator.NewLinksTo(qs, fixed, quad.Object)

	oldIt := lto.Clone()
	newIt, ok := lto.Optimize()
	if !ok {
		t.Errorf("Failed to optimize iterator")
	}
	if newIt.Type() != Type() {
		t.Errorf("Optimized iterator type does not match original, got:%v expect:%v", newIt.Type(), Type())
	}

	newQuads := graphtest.IteratedQuads(t, qs, newIt)
	oldQuads := graphtest.IteratedQuads(t, qs, oldIt)
	if !reflect.DeepEqual(newQuads, oldQuads) {
		t.Errorf("Optimized iteration does not match original")
	}

	oldIt.Next()
	oldResults := make(map[string]graph.Value)
	oldIt.TagResults(oldResults)
	newIt.Next()
	newResults := make(map[string]graph.Value)
	newIt.TagResults(newResults)
	if !reflect.DeepEqual(newResults, oldResults) {
		t.Errorf("Discordant tag results, new:%v old:%v", newResults, oldResults)
	}
}
Beispiel #28
0
func TestMemstoreBackedSexp(t *testing.T) {
	qs, _ := graph.NewQuadStore("memstore", "", nil)
	w, _ := graph.NewQuadWriter("single", qs, nil)
	emptyIt := BuildIteratorTreeForQuery(qs, "()")
	if emptyIt.Type() != graph.Null {
		t.Errorf(`Incorrect type for empty query, got:%q expect: "null"`, emptyIt.Type())
	}
	for _, test := range testQueries {
		if test.add.IsValid() {
			w.AddQuad(test.add)
		}
		it := BuildIteratorTreeForQuery(qs, test.query)
		if it.Type() != test.typ {
			t.Errorf("Incorrect type for %s, got:%q expect %q", test.message, it.Type(), test.expect)
		}
		if !it.Next() {
			t.Errorf("Failed to %s", test.message)
		}
		got := it.Result()
		if expect := qs.ValueOf(quad.Raw(test.expect)); got != expect {
			t.Errorf("Incorrect result for %s, got:%v expect %v", test.message, got, expect)
		}
	}
}
Beispiel #29
0
func TestQueryShape(t *testing.T) {
	qs := &store{
		data: []string{
			1: "cool",
			2: "status",
			3: "fun",
			4: "name",
		},
	}

	// Given a single linkage iterator's shape.
	hasa := hasaWithTag(qs, "tag", "cool")
	hasa.Tagger().Add("top")

	shape := make(map[string]interface{})
	OutputQueryShapeForIterator(hasa, qs, shape)

	nodes := shape["nodes"].([]Node)
	if len(nodes) != 3 {
		t.Errorf("Failed to get correct number of nodes, got:%d expect:4", len(nodes))
	}
	links := shape["links"].([]Link)
	if len(nodes) != 3 {
		t.Errorf("Failed to get correct number of links, got:%d expect:1", len(links))
	}

	// Nodes should be correctly tagged.
	nodes = shape["nodes"].([]Node)
	for i, expect := range [][]string{{"tag"}, nil, {"top"}} {
		if !reflect.DeepEqual(nodes[i].Tags, expect) {
			t.Errorf("Failed to get correct tag for node[%d], got:%s expect:%s", i, nodes[i].Tags, expect)
		}
	}
	if !nodes[1].IsLinkNode {
		t.Error("Failed to get node[1] as link node")
	}

	// Link should be correctly typed.
	nodes = shape["nodes"].([]Node)
	link := shape["links"].([]Link)[0]
	if link.Source != nodes[2].ID {
		t.Errorf("Failed to get correct link source, got:%v expect:%v", link.Source, nodes[2].ID)
	}
	if link.Target != nodes[0].ID {
		t.Errorf("Failed to get correct link target, got:%v expect:%v", link.Target, nodes[0].ID)
	}
	if link.LinkNode != nodes[1].ID {
		t.Errorf("Failed to get correct link node, got:%v expect:%v", link.LinkNode, nodes[1].ID)
	}
	if link.Pred != 0 {
		t.Errorf("Failed to get correct number of predecessors:%v expect:0", link.Pred)
	}

	// Given a name-of-an-and-iterator's shape.
	andInternal := NewAnd(qs)

	hasa1 := hasaWithTag(qs, "tag1", "cool")
	hasa1.Tagger().Add("hasa1")
	andInternal.AddSubIterator(hasa1)

	hasa2 := hasaWithTag(qs, "tag2", "fun")
	hasa2.Tagger().Add("hasa2")
	andInternal.AddSubIterator(hasa2)

	pred := qs.FixedIterator()
	pred.Add(qs.ValueOf(quad.Raw("name")))

	and := NewAnd(qs)
	and.AddSubIterator(NewLinksTo(qs, andInternal, quad.Subject))
	and.AddSubIterator(NewLinksTo(qs, pred, quad.Predicate))

	shape = make(map[string]interface{})
	OutputQueryShapeForIterator(NewHasA(qs, and, quad.Object), qs, shape)

	links = shape["links"].([]Link)
	if len(links) != 3 {
		t.Errorf("Failed to find the correct number of links, got:%d expect:3", len(links))
	}
	nodes = shape["nodes"].([]Node)
	if len(nodes) != 7 {
		t.Errorf("Failed to find the correct number of nodes, got:%d expect:7", len(nodes))
	}
	var n int
	for _, node := range nodes {
		if node.IsLinkNode {
			n++
		}
	}
	if n != 3 {
		t.Errorf("Failed to find the correct number of link nodes, got:%d expect:3", n)
	}
}
Beispiel #30
0
)

var testNQuads = []struct {
	message string
	input   string
	expect  quad.Quad
	err     error
}{
	// Tests from original nquads.

	// NTriple tests.
	{
		message: "parse simple triples",
		input:   "this is valid .",
		expect: quad.Quad{
			Subject:   quad.Raw("this"),
			Predicate: quad.Raw("is"),
			Object:    quad.Raw("valid"),
			Label:     nil,
		},
	},
	{
		message: "parse quoted triples",
		input:   `this is "valid too" .`,
		expect: quad.Quad{
			Subject:   quad.Raw("this"),
			Predicate: quad.Raw("is"),
			Object:    quad.String("valid too"),
			Label:     nil,
		},
	},