module RDF::Queryable
Override RDF::Queryable
to execute against SPARQL::Algebra::Query
elements as well as RDF::Query
and RDF::Pattern
Extensions for `RDF::Queryable`
Public Instance Methods
Concise Bounded Description
Given a particular node (the starting node) in a particular RDF
graph (the source graph), a subgraph of that particular graph, taken to comprise a concise bounded description of the resource denoted by the starting node, can be identified as follows:
1. Include in the subgraph all statements in the source graph where the subject of the statement is the starting node; 2. Recursively, for all statements identified in the subgraph thus far having a blank node object, include in the subgraph all statements in the source graph where the subject of the statement is the blank node in question and which are not already included in the subgraph. 3. Recursively, for all statements included in the subgraph thus far, for all reifications of each statement in the source graph, include the concise bounded description beginning from the rdf:Statement node of each reification. (we skip this step)
This results in a subgraph where the object nodes are either URI references, literals, or blank nodes not serving as the subject of any statement in the graph.
Used to implement the SPARQL
`DESCRIBE` operator.
@overload concise_bounded_description
(*terms, **options, &block)
@param [Array<RDF::Term>] terms List of terms to include in the results. @param [Hash{Symbol => Object}] options @option options [Boolean] :non_subjects (false) If `term` is not a `subject` within `self` then add all `subject`s referencing the term as a `predicate` or `object`. @option options [RDF::Graph] graph Graph containing statements already considered.
@yield [statement] @yieldparam [RDF::Statement] statement @yieldreturn [void] ignored @return [RDF::Graph]
@see www.w3.org/Submission/CBD/
# File lib/sparql/extensions.rb, line 43 def concise_bounded_description(*terms, **options, &block) graph = options[:graph] || RDF::Graph.new if options[:non_subjects] query_terms = terms.dup # Find terms not in self as a subject and recurse with their subjects terms.reject {|term| self.first({subject: term})}.each do |term| self.query({predicate: term}) do |statement| query_terms << statement.subject end self.query({object: term}) do |statement| query_terms << statement.subject end end terms = query_terms.uniq end # Don't consider term if already in graph terms.reject {|term| graph.first({subject: term})}.each do |term| # Find statements from queryiable with term as a subject self.query({subject: term}) do |statement| yield(statement) if block_given? graph << statement # Include reifications of this statement RDF::Query.new({ s: { RDF.type => RDF["Statement"], RDF.subject => statement.subject, RDF.predicate => statement.predicate, RDF.object => statement.object, } }, **{}).execute(self).each do |solution| # Recurse to include this subject recurse_opts = options.merge(non_subjects: false, graph: graph) self.concise_bounded_description(solution[:s], **recurse_opts, &block) end # Recurse if object is a BNode and it is not already in subjects if statement.object.node? recurse_opts = options.merge(non_subjects: false, graph: graph) self.concise_bounded_description(statement.object, **recurse_opts, &block) end end end graph end
Queries `self` for RDF
statements matching the given `pattern`.
Monkey patch to RDF::Queryable#query
to execute a {SPARQL::Algebra::Operator} in addition to an {RDF::Query} object.
@example
queryable.query([nil, RDF::DOAP.developer, nil]) queryable.query({predicate: RDF::DOAP.developer}) op = SPARQL::Algebra::Expression.parse(%q((bgp (triple ?a doap:developer ?b)))) queryable.query(op)
@param [RDF::Query, RDF::Statement
, Array(RDF::Term
), Hash
, SPARQL::Operator] pattern @yield [statement]
each matching statement
@yieldparam [RDF::Statement] statement @yieldreturn [void] ignored @return [Enumerator] @see RDF::Queryable#query_pattern
# File lib/sparql/algebra/extensions.rb, line 323 def query(pattern, **options, &block) raise TypeError, "#{self} is not queryable" if respond_to?(:queryable?) && !queryable? if pattern.is_a?(SPARQL::Algebra::Operator) && pattern.respond_to?(:execute) before_query(pattern) if respond_to?(:before_query) solutions = if method(:query_execute).arity == 1 query_execute(pattern, &block) else query_execute(pattern, **options, &block) end after_query(pattern) if respond_to?(:after_query) if !pattern.respond_to?(:query_yeilds_solutions?) || pattern.query_yields_solutions? # Just return solutions solutions else # Return an enumerator enum_for(:query, pattern, **options) end else query_without_sparql(pattern, **options, &block) end end