Class: Reddy::Graph
- Inherits:
-
Object
- Object
- Reddy::Graph
- Defined in:
- lib/reddy/graph.rb
Overview
A simple graph to hold triples.
Graphs store triples, and the namespaces associated with those triples, where defined
Direct Known Subclasses
Instance Attribute Summary collapse
-
#identifier ⇒ Object
readonly
Returns the value of attribute identifier.
-
#nsbinding ⇒ Object
readonly
Data Store interface.
-
#store ⇒ Object
readonly
Returns the value of attribute store.
-
#triples(triple = Triple.new(nil, nil, nil), &block) ⇒ Array
(also: #find)
readonly
Triples from graph, optionally matching subject, predicate, or object.
Instance Method Summary collapse
-
#<<(triple) ⇒ Graph
Adds an more extant triples to a graph.
-
#[](item) ⇒ Object
Indexed statement in serialized graph triples.
-
#add(*triples) ⇒ Graph
Adds one or more extant triples to a graph.
-
#add_triple(subject, predicate, object) ⇒ Graph
Adds a triple to a graph directly from the intended subject, predicate, and object.
-
#bind(namespace) ⇒ Namespace
Bind a namespace to the graph.
-
#bnodes ⇒ Object
Get all BNodes with usage count used within graph.
-
#close(commit_pending_transaction = false) ⇒ Object
Close the graph store.
-
#commit ⇒ Object
Commit changes to graph.
-
#contains?(triple) ⇒ Boolean
Check to see if this graph contains the specified triple.
- #context_aware? ⇒ Boolean
-
#destroy(configuration = nil) ⇒ Object
Destroy the store identified by configuration if supported.
-
#eql?(other) ⇒ Boolean
(also: #==)
Two graphs are equal if each is an instance of the other, considering BNode equivalence.
-
#get_by_type(object) ⇒ Object
Get list of subjects having rdf:type == object.
-
#has_bnode_identifier?(bn) ⇒ Boolean
Detect the presence of a BNode in the graph, either as a subject or an object.
-
#initialize(options = {}) ⇒ Graph
constructor
Create a Graph with the given store and identifier.
- #inspect ⇒ Object
-
#merge!(graph) ⇒ Object
Merge a graph into this graph.
-
#namespace(prefix) ⇒ Object
Namespace for prefix.
-
#objects ⇒ Object
List of distinct objects in graph.
-
#open(configuration, create = false) ⇒ Object
Open the graph store.
-
#predicates ⇒ Object
List of distinct predicates in graph.
-
#prefix(namespace) ⇒ Object
Prefix for namespace.
-
#remove(triple) ⇒ Object
Remove a triple from the graph.
-
#rollback ⇒ Object
Rollback active transactions.
-
#size ⇒ Object
Number of Triples in the graph.
-
#subjects ⇒ Object
List of distinct subjects in graph.
-
#to_ntriples ⇒ String
Exports the graph to RDF in N-Triples form.
-
#to_rdfxml ⇒ String
Exports the graph to RDF in RDF/XML form.
-
#to_s ⇒ Object
Output graph using to_ntriples.
Constructor Details
#initialize(options = {}) ⇒ Graph
Create a Graph with the given store and identifier.
The constructor accepts a store option, that will be used to store the graph data.
Stores can be context-aware or unaware. Unaware stores take up (some) less space but cannot support features that require context, such as true merging/demerging of sub-graphs and provenance.
The Graph constructor can take an identifier which identifies the Graph by name. If none is given, the graph is assigned a BNode for it’s identifier. For more on named graphs, see: en.wikipedia.org/wiki/RDFLib
- options[:store]
-
storage, defaults to a new ListStore instance
- options[:identifier]
-
Identifier for this graph, Literal, BNode or URIRef
30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/reddy/graph.rb', line 30 def initialize( = {}) @nsbinding = {} # Instantiate triple store @store = case [:store] when AbstractStore then [:store] when :list_store then ListStore.new when :memory_store then MemoryStore.new else MemoryStore.new end @identifier = [:identifier] || BNode.new end |
Instance Attribute Details
#identifier ⇒ Object (readonly)
Returns the value of attribute identifier.
8 9 10 |
# File 'lib/reddy/graph.rb', line 8 def identifier @identifier end |
#nsbinding ⇒ Object (readonly)
Data Store interface
51 52 53 |
# File 'lib/reddy/graph.rb', line 51 def nsbinding @nsbinding end |
#store ⇒ Object (readonly)
Returns the value of attribute store.
9 10 11 |
# File 'lib/reddy/graph.rb', line 9 def store @store end |
#triples(triple = Triple.new(nil, nil, nil), &block) ⇒ Array (readonly) Also known as: find
Triples from graph, optionally matching subject, predicate, or object. Delegates to Store#triples.
235 236 237 |
# File 'lib/reddy/graph.rb', line 235 def triples @triples end |
Instance Method Details
#<<(triple) ⇒ Graph
202 203 204 205 |
# File 'lib/reddy/graph.rb', line 202 def << (triple) @store.add(triple, self) self end |
#[](item) ⇒ Object
Indexed statement in serialized graph triples. Equivalent to graph.triples
175 |
# File 'lib/reddy/graph.rb', line 175 def [] (item); @store.item(item, self); end |
#add(*triples) ⇒ Graph
Adds one or more extant triples to a graph. Delegates to Store.
Example
g = Graph.new;
t1 = Triple.new(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new);
t2 = Triple.new(BNode.new, URIRef.new("http://xmlns.com/foaf/0.1/knows"), BNode.new);
g.add(t1, t2, ...)
- options[:context]
-
Graph context in which to deposit triples, defaults to default_context or self
219 220 221 222 223 224 |
# File 'lib/reddy/graph.rb', line 219 def add(*triples) = triples.last.is_a?(Hash) ? triples.pop : {} ctx = [:context] || @default_context || self triples.each {|t| @store.add(t, ctx)} self end |
#add_triple(subject, predicate, object) ⇒ Graph
187 188 189 190 |
# File 'lib/reddy/graph.rb', line 187 def add_triple(subject, predicate, object) self.add(Triple.new(subject, predicate, object)) self end |
#bind(namespace) ⇒ Namespace
151 152 153 154 |
# File 'lib/reddy/graph.rb', line 151 def bind(namespace) raise GraphException, "Can't bind #{namespace.inspect} as namespace" unless namespace.is_a?(Namespace) @store.bind(namespace) end |
#bnodes ⇒ Object
Get all BNodes with usage count used within graph
257 258 259 |
# File 'lib/reddy/graph.rb', line 257 def bnodes @store.bnodes(self) end |
#close(commit_pending_transaction = false) ⇒ Object
Close the graph store
Might be necessary for stores that require closing a connection to a database or releasing some resource.
77 78 79 |
# File 'lib/reddy/graph.rb', line 77 def close(commit_pending_transaction=false) @store.open(commit_pending_transaction) end |
#commit ⇒ Object
Commit changes to graph
60 |
# File 'lib/reddy/graph.rb', line 60 def commit; @store.commit; end |
#contains?(triple) ⇒ Boolean
Check to see if this graph contains the specified triple
252 253 254 |
# File 'lib/reddy/graph.rb', line 252 def contains?(triple) @store.contains?(triple, self) end |
#context_aware? ⇒ Boolean
48 |
# File 'lib/reddy/graph.rb', line 48 def context_aware?; @context_aware; end |
#destroy(configuration = nil) ⇒ Object
Destroy the store identified by configuration if supported
54 55 56 57 |
# File 'lib/reddy/graph.rb', line 54 def destroy(configuration = nil) @store.destroy(configuration) self.freeze end |
#eql?(other) ⇒ Boolean Also known as: ==
Two graphs are equal if each is an instance of the other, considering BNode equivalence. This may be done by creating a new graph an substituting each permutation of BNode identifiers from self to other until every permutation is exhausted, or a textual equivalence is found after sorting each graph.
We just follow Python RDFlib’s lead and do a simple comparison
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/reddy/graph.rb', line 293 def eql? (other) #puts "eql? size #{self.size} vs #{other.size}" return false if !other.is_a?(Graph) || self.size != other.size bn_self = bnodes.values.sort bn_other = other.bnodes.values.sort #puts "eql? bnodes '#{bn_self.to_sentence}' vs '#{bn_other.to_sentence}'" return false unless bn_self == bn_other # Check each triple to see if it's contained in the other graph triples do |t, ctx| next if t.subject.is_a?(BNode) || t.object.is_a?(BNode) #puts "eql? contains '#{t.to_ntriples}'" return false unless other.contains?(t) end true end |
#get_by_type(object) ⇒ Object
Get list of subjects having rdf:type == object
264 265 266 |
# File 'lib/reddy/graph.rb', line 264 def get_by_type(object) triples(Triple.new(nil, RDF_TYPE, object)).map {|t, ctx| t.subject} end |
#has_bnode_identifier?(bn) ⇒ Boolean
Detect the presence of a BNode in the graph, either as a subject or an object
244 245 246 247 248 249 |
# File 'lib/reddy/graph.rb', line 244 def has_bnode_identifier?(bn) triples do |triple, context| return true if triple.subject.eql?(bn) || triple.object.eql?(bn) end false end |
#inspect ⇒ Object
44 45 46 |
# File 'lib/reddy/graph.rb', line 44 def inspect "Graph[id=#{identifier},store=#{store.inspect}]" end |
#merge!(graph) ⇒ Object
Merge a graph into this graph
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 |
# File 'lib/reddy/graph.rb', line 269 def merge!(graph) raise GraphException.new("merge without a graph") unless graph.is_a?(Graph) # Map BNodes from source Graph to new BNodes bn = graph.bnodes bn.keys.each {|k| bn[k] = BNode.new} graph.triples do |triple, context| # If triple contains bnodes, remap to new values if triple.subject.is_a?(BNode) || triple.object.is_a?(BNode) triple = triple.clone triple.subject = bn[triple.subject] if triple.subject.is_a?(BNode) triple.object = bn[triple.object] if triple.object.is_a?(BNode) end self << triple end end |
#namespace(prefix) ⇒ Object
Namespace for prefix
157 |
# File 'lib/reddy/graph.rb', line 157 def namespace(prefix); @store.namespace(prefix); end |
#objects ⇒ Object
List of distinct objects in graph
172 |
# File 'lib/reddy/graph.rb', line 172 def objects; @store.objects(self); end |
#open(configuration, create = false) ⇒ Object
Open the graph store
Might be necessary for stores that require opening a connection to a database or acquiring some resource.
69 70 71 |
# File 'lib/reddy/graph.rb', line 69 def open(configuration, create=false) @store.open(configuration, create) end |
#predicates ⇒ Object
List of distinct predicates in graph
169 |
# File 'lib/reddy/graph.rb', line 169 def predicates; @store.predicates(self); end |
#prefix(namespace) ⇒ Object
Prefix for namespace
160 |
# File 'lib/reddy/graph.rb', line 160 def prefix(namespace); @store.prefix(namespace); end |
#remove(triple) ⇒ Object
Remove a triple from the graph. Delegates to store. Nil matches all triples and thus empties the graph
228 |
# File 'lib/reddy/graph.rb', line 228 def remove(triple); @store.remove(triple, self); end |
#rollback ⇒ Object
Rollback active transactions
63 |
# File 'lib/reddy/graph.rb', line 63 def rollback; @store.rollback; end |
#size ⇒ Object
Number of Triples in the graph
163 |
# File 'lib/reddy/graph.rb', line 163 def size; @store.size(self); end |
#subjects ⇒ Object
List of distinct subjects in graph
166 |
# File 'lib/reddy/graph.rb', line 166 def subjects; @store.subjects(self); end |
#to_ntriples ⇒ String
90 91 92 93 94 |
# File 'lib/reddy/graph.rb', line 90 def to_ntriples triples.collect do |t| t.to_ntriples end * "\n" + "\n" end |
#to_rdfxml ⇒ String
Exports the graph to RDF in RDF/XML form.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/reddy/graph.rb', line 105 def to_rdfxml replace_text = {} rdfxml = "" xml = builder = Builder::XmlMarkup.new(:target => rdfxml, :indent => 2) extended_bindings = nsbinding.merge( "rdf" => RDF_NS, "rdfs" => RDFS_NS, "xhv" => XHV_NS, "xml" => XML_NS ) rdf_attrs = extended_bindings.values.inject({}) { |hash, ns| hash.merge(ns.xmlns_attr => ns.uri.to_s)} uri_bindings = extended_bindings.values.inject({}) { |hash, ns| hash.merge(ns.uri.to_s => ns.prefix)} xml.instruct! xml.rdf(:RDF, rdf_attrs) do # Add statements for each subject subjects.each do |s| xml.rdf(:Description, (s.is_a?(BNode) ? "rdf:nodeID" : "rdf:about") => s) do triples(Triple.new(s, nil, nil)) do |triple, context| xml_args = triple.object.xml_args if triple.object.is_a?(Literal) && triple.object.xmlliteral? replace_text["__replace_with_#{triple.object.object_id}__"] = xml_args[0] xml_args[0] = "__replace_with_#{triple.object.object_id}__" end xml.tag!(triple.predicate.to_qname(uri_bindings), *xml_args) end end end end # Perform literal substitutions replace_text.each_pair do |match, value| rdfxml.sub!(match, value) end rdfxml end |
#to_s ⇒ Object
Output graph using to_ntriples
97 |
# File 'lib/reddy/graph.rb', line 97 def to_s; self.to_ntriples; end |