From 3e2b4900632857de361927c8871ef32332699081 Mon Sep 17 00:00:00 2001 From: Barak Michener Date: Wed, 2 Sep 2015 17:36:00 -0400 Subject: [PATCH] Fixes memstore transaction semantics --- graph/memstore/quadstore.go | 22 +++++++++++++++++++++- graph/memstore/quadstore_test.go | 31 ++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/graph/memstore/quadstore.go b/graph/memstore/quadstore.go index 5605437..f12937a 100644 --- a/graph/memstore/quadstore.go +++ b/graph/memstore/quadstore.go @@ -106,6 +106,26 @@ func newQuadStore() *QuadStore { } func (qs *QuadStore) ApplyDeltas(deltas []graph.Delta, ignoreOpts graph.IgnoreOpts) error { + // Precheck the whole transaction + for _, d := range deltas { + switch d.Action { + case graph.Add: + if !ignoreOpts.IgnoreDup { + if _, exists := qs.indexOf(d.Quad); exists { + return graph.ErrQuadExists + } + } + case graph.Delete: + if !ignoreOpts.IgnoreMissing { + if _, exists := qs.indexOf(d.Quad); !exists { + return graph.ErrQuadNotExist + } + } + default: + return errors.New("memstore: invalid action") + } + } + for _, d := range deltas { var err error switch d.Action { @@ -120,7 +140,7 @@ func (qs *QuadStore) ApplyDeltas(deltas []graph.Delta, ignoreOpts graph.IgnoreOp err = nil } default: - err = errors.New("memstore: invalid action") + panic("memstore: unexpected invalid action") } if err != nil { return err diff --git a/graph/memstore/quadstore_test.go b/graph/memstore/quadstore_test.go index 5bcf1d3..0d57d39 100644 --- a/graph/memstore/quadstore_test.go +++ b/graph/memstore/quadstore_test.go @@ -180,13 +180,17 @@ func TestLinksToOptimization(t *testing.T) { func TestRemoveQuad(t *testing.T) { qs, w, _ := makeTestStore(simpleGraph) - w.RemoveQuad(quad.Quad{ + err := w.RemoveQuad(quad.Quad{ Subject: "E", Predicate: "follows", Object: "F", Label: "", }) + if err != nil { + t.Error("Couldn't remove quad", err) + } + fixed := qs.FixedIterator() fixed.Add(qs.ValueOf("E")) @@ -204,3 +208,28 @@ func TestRemoveQuad(t *testing.T) { t.Error("E should not have any followers.") } } + +func TestTransaction(t *testing.T) { + qs, w, _ := makeTestStore(simpleGraph) + size := qs.Size() + + tx := graph.NewTransaction() + tx.AddQuad(quad.Quad{ + Subject: "E", + Predicate: "follows", + Object: "G", + Label: ""}) + tx.RemoveQuad(quad.Quad{ + Subject: "Non", + Predicate: "existent", + Object: "quad", + Label: ""}) + + err := w.ApplyTransaction(tx) + if err == nil { + t.Error("Able to remove a non-existent quad") + } + if size != qs.Size() { + t.Error("Appended a new quad in a failed transaction") + } +}