github.com/cayleygraph/cayley@v0.7.7/writer/single.go (about) 1 // Copyright 2014 The Cayley Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package writer 16 17 import ( 18 "github.com/cayleygraph/cayley/graph" 19 "github.com/cayleygraph/quad" 20 ) 21 22 func init() { 23 graph.RegisterWriter("single", NewSingleReplication) 24 } 25 26 type Single struct { 27 qs graph.QuadStore 28 ignoreOpts graph.IgnoreOpts 29 } 30 31 func NewSingle(qs graph.QuadStore, opts graph.IgnoreOpts) (graph.QuadWriter, error) { 32 return &Single{ 33 qs: qs, 34 ignoreOpts: opts, 35 }, nil 36 } 37 38 func NewSingleReplication(qs graph.QuadStore, opts graph.Options) (graph.QuadWriter, error) { 39 ignoreMissing, err := opts.BoolKey("ignore_missing", graph.IgnoreMissing) 40 if err != nil { 41 return nil, err 42 } 43 44 ignoreDuplicate, err := opts.BoolKey("ignore_duplicate", graph.IgnoreDuplicates) 45 if err != nil { 46 return nil, err 47 } 48 49 return NewSingle(qs, graph.IgnoreOpts{ 50 IgnoreMissing: ignoreMissing, 51 IgnoreDup: ignoreDuplicate, 52 }) 53 } 54 55 func (s *Single) AddQuad(q quad.Quad) error { 56 deltas := make([]graph.Delta, 1) 57 deltas[0] = graph.Delta{ 58 Quad: q, 59 Action: graph.Add, 60 } 61 return s.qs.ApplyDeltas(deltas, s.ignoreOpts) 62 } 63 64 func (s *Single) AddQuadSet(set []quad.Quad) error { 65 tx := graph.NewTransactionN(len(set)) 66 for _, q := range set { 67 tx.AddQuad(q) 68 } 69 return s.qs.ApplyDeltas(tx.Deltas, s.ignoreOpts) 70 } 71 72 func (s *Single) RemoveQuad(q quad.Quad) error { 73 deltas := make([]graph.Delta, 1) 74 deltas[0] = graph.Delta{ 75 Quad: q, 76 Action: graph.Delete, 77 } 78 return s.qs.ApplyDeltas(deltas, s.ignoreOpts) 79 } 80 81 // RemoveNode removes all quads with the given value. 82 // 83 // It returns ErrNodeNotExists if node is missing. 84 func (s *Single) RemoveNode(v quad.Value) error { 85 gv := s.qs.ValueOf(v) 86 if gv == nil { 87 return graph.ErrNodeNotExists 88 } 89 del := graph.NewRemover(s) 90 defer del.Close() 91 92 total := 0 93 // TODO(dennwc): QuadStore may remove node without iterations. Consider optional interface for this. 94 for _, d := range []quad.Direction{quad.Subject, quad.Predicate, quad.Object, quad.Label} { 95 r := graph.NewResultReader(s.qs, s.qs.QuadIterator(d, gv)) 96 n, err := quad.Copy(del, r) 97 r.Close() 98 if err != nil { 99 return err 100 } 101 total += n 102 } 103 if err := del.Flush(); err != nil { 104 return err 105 } 106 if total == 0 { 107 return graph.ErrNodeNotExists 108 } 109 return nil 110 } 111 112 func (s *Single) Close() error { 113 // Nothing to clean up locally. 114 return nil 115 } 116 117 func (s *Single) ApplyTransaction(t *graph.Transaction) error { 118 return s.qs.ApplyDeltas(t.Deltas, s.ignoreOpts) 119 }