diff --git a/rdf/disk/graph.go b/rdf/disk/graph.go index ab0be77..66d7a71 100644 --- a/rdf/disk/graph.go +++ b/rdf/disk/graph.go @@ -123,6 +123,33 @@ func (g *Graph) Describe(nodes ...rdf.NamedNode) (rdf.Graph, error) { return res, err } +func (g *Graph) DescribeW(enc *rdf.Encoder, nodes ...rdf.NamedNode) error { + return g.kv.View(func(tx *bolt.Tx) error { + cache := make(map[uint32]rdf.Node) + for _, node := range nodes { + sID, err := g.getID(tx, node) + if err == ErrNotFound { + return nil + } + if err != nil { + return err + } + + cache[sID] = node + trs, err := g.describe(tx, sID, cache) + if err != nil { + return err + } + for _, tr := range trs { + if err := enc.Encode(tr); err != nil { + return err + } + } + } + return nil + }) +} + func (g *Graph) describe(tx *bolt.Tx, nodeID uint32, cache map[uint32]rdf.Node) ([]rdf.Triple, error) { // nodeID must represent either a Named Node or Blank Node. var trs []rdf.Triple diff --git a/rdf/graph.go b/rdf/graph.go index 125bb8e..e388af9 100644 --- a/rdf/graph.go +++ b/rdf/graph.go @@ -15,6 +15,8 @@ type Graph interface { // as well all triples of blank nodes which are outgoing relation of the node. Describe(...NamedNode) (Graph, error) + DescribeW(*Encoder, ...NamedNode) error + // Update performs an update query which inserts and/or deletes triples // from the Graph. // diff --git a/rdf/memory/graph.go b/rdf/memory/graph.go index af849aa..50978c6 100644 --- a/rdf/memory/graph.go +++ b/rdf/memory/graph.go @@ -125,6 +125,39 @@ func (g *Graph) Describe(nodes ...rdf.NamedNode) (rdf.Graph, error) { return res, nil } +func (g *Graph) DescribeW(enc *rdf.Encoder, nodes ...rdf.NamedNode) error { + for _, node := range nodes { + if s, found := g.node2id[node]; found { + for p, objs := range g.spo[s] { + for _, o := range objs { + if err := enc.Encode(rdf.Triple{ + Subject: node, + Predicate: g.id2node[p].(rdf.NamedNode), + Object: g.id2node[o], + }); err != nil { + return err + } + if _, ok := g.id2node[o].(rdf.BlankNode); ok { + for p, objs := range g.spo[o] { + for _, bo := range objs { + if err := enc.Encode(rdf.Triple{ + Subject: g.id2node[o].(rdf.SubjectNode), + Predicate: g.id2node[p].(rdf.NamedNode), + Object: g.id2node[bo], + }); err != nil { + return err + } + } + } + } + } + } + } + + } + return nil +} + func (g *Graph) Update(del []rdf.TriplePattern, ins []rdf.TriplePattern, where []rdf.TriplePattern) (delN, insN int, err error) { if where != nil { // Encode patterns