Class: RDF::Query::Pattern
- Defined in:
- lib/rdf/query/pattern.rb
Overview
An RDF query pattern.
Instance Attribute Summary collapse
-
#cost ⇒ Numeric
The estimated cost of this pattern (for query optimization).
-
#options ⇒ Hash
readonly
Any additional options for this pattern.
Attributes inherited from Statement
#context, #id, #object, #predicate, #subject
Class Method Summary collapse
Instance Method Summary collapse
-
#binding_count ⇒ Integer
Returns the number of bindings in this pattern.
-
#bindings ⇒ Hash{Symbol => RDF::Term}
Returns all bindings in this pattern.
-
#bindings? ⇒ Boolean
Returns ‘true` if this pattern contains bindings.
-
#blank? ⇒ Boolean
Returns ‘true` if this is a blank pattern, with all terms being `nil`.
-
#bound? ⇒ Boolean
Returns ‘true` if all variables in this pattern are bound.
-
#bound_variables ⇒ Hash{Symbol => Variable}
Returns all bound variables in this pattern.
-
#constant? ⇒ Boolean
Returns ‘true` if this is a constant pattern, with all terms being either URIs, blank nodes, or literals.
-
#execute(queryable, bindings = {}) {|statement| ... } ⇒ Enumerator
Executes this query pattern on the given ‘queryable` object.
-
#has_variables? ⇒ Boolean
(also: #variables?)
Returns ‘true` if this pattern contains any variables.
-
#initialize(subject = nil, predicate = nil, object = nil, options = {}) ⇒ Pattern
constructor
A new instance of Pattern.
- #initialize! ⇒ Object
-
#optional? ⇒ Boolean
Returns ‘true` if this is an optional pattern.
-
#solution(statement) ⇒ RDF::Query::Solution
Returns a query solution constructed by binding any variables in this pattern with the corresponding terms in the given ‘statement`.
-
#to_s ⇒ String
Returns a string representation of this pattern.
-
#unbound? ⇒ Boolean
Returns ‘true` if all variables in this pattern are unbound.
-
#unbound_variables ⇒ Hash{Symbol => Variable}
Returns all unbound variables in this pattern.
-
#variable? ⇒ Boolean
Returns ‘true` if this is a variable pattern, with any term being `nil` or a variable.
-
#variable_count ⇒ Integer
(also: #cardinality, #arity)
Returns the number of variables in this pattern.
-
#variable_terms(name = nil) ⇒ Array<Symbol>
Returns the variable terms in this pattern.
-
#variables ⇒ Hash{Symbol => Variable}
Returns all variables in this pattern.
Methods inherited from Statement
#==, #===, #[], #[]=, #asserted?, #eql?, #has_blank_nodes?, #has_context?, #has_graph?, #has_object?, #has_predicate?, #has_subject?, #inferred?, #invalid?, #quoted?, #reified, #statement?, #to_hash, #to_quad, #to_triple, #valid?
Methods included from Value
#graph?, #inspect, #inspect!, #iri?, #literal?, #node?, #resource?, #statement?, #to_ntriples, #to_quad, #to_rdf, #type_error, #uri?
Constructor Details
Instance Attribute Details
#cost ⇒ Numeric
The estimated cost of this pattern (for query optimization).
59 60 61 |
# File 'lib/rdf/query/pattern.rb', line 59 def cost @cost end |
#options ⇒ Hash (readonly)
Any additional options for this pattern.
53 54 55 |
# File 'lib/rdf/query/pattern.rb', line 53 def @options end |
Class Method Details
.from(pattern, options = {}) ⇒ Object
8 9 10 11 12 13 14 15 16 |
# File 'lib/rdf/query/pattern.rb', line 8 def self.from(pattern, = {}) case pattern when Pattern then pattern when Array, Statement self.new(pattern[0], pattern[1], pattern[2], .merge(:context => pattern[3])) when Hash then self.new(.merge(pattern)) else raise ArgumentError, "expected RDF::Query::Pattern, RDF::Statement, Hash, or Array, but got #{pattern.inspect}" end end |
Instance Method Details
#binding_count ⇒ Integer
Returns the number of bindings in this pattern.
261 262 263 |
# File 'lib/rdf/query/pattern.rb', line 261 def binding_count bindings.size end |
#bindings ⇒ Hash{Symbol => RDF::Term}
Returns all bindings in this pattern.
269 270 271 272 273 274 275 276 |
# File 'lib/rdf/query/pattern.rb', line 269 def bindings bindings = {} bindings.merge!(subject.bindings) if subject.is_a?(Variable) bindings.merge!(predicate.bindings) if predicate.is_a?(Variable) bindings.merge!(object.bindings) if object.is_a?(Variable) bindings.merge!(context.bindings) if context.is_a?(Variable) bindings end |
#bindings? ⇒ Boolean
Returns ‘true` if this pattern contains bindings.
253 254 255 |
# File 'lib/rdf/query/pattern.rb', line 253 def bindings? !bindings.empty? end |
#blank? ⇒ Boolean
Returns ‘true` if this is a blank pattern, with all terms being `nil`.
66 67 68 |
# File 'lib/rdf/query/pattern.rb', line 66 def blank? subject.nil? && predicate.nil? && object.nil? && context.nil? end |
#bound? ⇒ Boolean
Returns ‘true` if all variables in this pattern are bound.
282 283 284 |
# File 'lib/rdf/query/pattern.rb', line 282 def bound? !variables.empty? && variables.values.all?(&:bound?) end |
#bound_variables ⇒ Hash{Symbol => Variable}
Returns all bound variables in this pattern.
290 291 292 |
# File 'lib/rdf/query/pattern.rb', line 290 def bound_variables variables.reject { |name, variable| variable.unbound? } end |
#constant? ⇒ Boolean
Returns ‘true` if this is a constant pattern, with all terms being either URIs, blank nodes, or literals.
A constant pattern is structurally and functionally equivalent to an RDF statement.
79 80 81 |
# File 'lib/rdf/query/pattern.rb', line 79 def constant? !(variable?) end |
#execute(queryable, bindings = {}) {|statement| ... } ⇒ Enumerator
Executes this query pattern on the given ‘queryable` object.
Values are matched using using Queryable#query_pattern.
If the optional ‘bindings` are given, variables will be substituted with their values when executing the query.
To match triples only in the default context, set context to ‘false’.
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/rdf/query/pattern.rb', line 144 def execute(queryable, bindings = {}, &block) query = { :subject => subject.is_a?(Variable) && bindings[subject.to_sym] ? bindings[subject.to_sym] : subject, :predicate => predicate.is_a?(Variable) && bindings[predicate.to_sym] ? bindings[predicate.to_sym] : predicate, :object => object.is_a?(Variable) && bindings[object.to_sym] ? bindings[object.to_sym] : object, :context => context.is_a?(Variable) && bindings[context.to_sym] ? bindings[context.to_sym] : context, }.delete_if{|k,v| v.nil?} # Do all the variable terms refer to distinct variables? variables = self.variables if variable_count == variables.size # If so, we can just let the repository implementation handle # everything and yield matching statements directly: queryable.query(query, &block) # No, some terms actually refer to the same variable... else # Figure out which terms refer to the same variable: terms = variables.each_key.find do |name| terms = variable_terms(name) break terms if terms.size > 1 end queryable.query(query) do |statement| # Only yield those matching statements where the variable # constraint is also satisfied: # FIXME: `Array#uniq` uses `#eql?` and `#hash`, not `#==` if matches = terms.map { |term| statement.send(term) }.uniq.size.equal?(1) block.call(statement) end end end end |
#has_variables? ⇒ Boolean Also known as: variables?
Returns ‘true` if this pattern contains any variables.
98 99 100 101 102 103 |
# File 'lib/rdf/query/pattern.rb', line 98 def has_variables? subject.is_a?(Variable) || predicate.is_a?(Variable) || object.is_a?(Variable) || context.is_a?(Variable) end |
#initialize! ⇒ Object
41 42 43 44 45 46 47 |
# File 'lib/rdf/query/pattern.rb', line 41 def initialize! @context = Variable.new(@context) if @context.is_a?(Symbol) @subject = Variable.new(@subject) if @subject.is_a?(Symbol) @predicate = Variable.new(@predicate) if @predicate.is_a?(Symbol) @object = Variable.new(@object) if @object.is_a?(Symbol) super end |
#optional? ⇒ Boolean
Returns ‘true` if this is an optional pattern.
115 116 117 |
# File 'lib/rdf/query/pattern.rb', line 115 def optional? !![:optional] end |
#solution(statement) ⇒ RDF::Query::Solution
Returns a query solution constructed by binding any variables in this pattern with the corresponding terms in the given ‘statement`.
188 189 190 191 192 193 194 195 |
# File 'lib/rdf/query/pattern.rb', line 188 def solution(statement) RDF::Query::Solution.new do |solution| solution[subject.to_sym] = statement.subject if subject.is_a?(Variable) solution[predicate.to_sym] = statement.predicate if predicate.is_a?(Variable) solution[object.to_sym] = statement.object if object.is_a?(Variable) solution[context.to_sym] = statement.context if context.is_a?(Variable) end end |
#to_s ⇒ String
Returns a string representation of this pattern.
314 315 316 317 318 319 320 321 322 323 324 325 326 327 |
# File 'lib/rdf/query/pattern.rb', line 314 def to_s StringIO.open do |buffer| # FIXME in RDF::Statement buffer << 'OPTIONAL ' if optional? buffer << [subject, predicate, object].map do |r| r.is_a?(RDF::Query::Variable) ? r.to_s : RDF::NTriples.serialize(r) end.join(" ") buffer << case context when nil, false then " ." when Variable then " #{context.to_s} ." else " #{RDF::NTriples.serialize(context)} ." end buffer.string end end |
#unbound? ⇒ Boolean
Returns ‘true` if all variables in this pattern are unbound.
298 299 300 |
# File 'lib/rdf/query/pattern.rb', line 298 def unbound? !variables.empty? && variables.values.all?(&:unbound?) end |
#unbound_variables ⇒ Hash{Symbol => Variable}
Returns all unbound variables in this pattern.
306 307 308 |
# File 'lib/rdf/query/pattern.rb', line 306 def unbound_variables variables.reject { |name, variable| variable.bound? } end |
#variable? ⇒ Boolean
Returns ‘true` if this is a variable pattern, with any term being `nil` or a variable.
89 90 91 |
# File 'lib/rdf/query/pattern.rb', line 89 def variable? subject.nil? || predicate.nil? || object.nil? || context.nil? || has_variables? end |
#variable_count ⇒ Integer Also known as: cardinality, arity
Returns the number of variables in this pattern.
Note: this does not count distinct variables, and will therefore e.g. return 3 even if two terms are actually the same variable.
223 224 225 226 227 228 229 230 |
# File 'lib/rdf/query/pattern.rb', line 223 def variable_count count = 0 count += 1 if subject.is_a?(Variable) count += 1 if predicate.is_a?(Variable) count += 1 if object.is_a?(Variable) count += 1 if context.is_a?(Variable) count end |
#variable_terms(name = nil) ⇒ Array<Symbol>
Returns the variable terms in this pattern.
207 208 209 210 211 212 213 214 |
# File 'lib/rdf/query/pattern.rb', line 207 def variable_terms(name = nil) terms = [] terms << :subject if subject.is_a?(Variable) && (!name || name.eql?(subject.name)) terms << :predicate if predicate.is_a?(Variable) && (!name || name.eql?(predicate.name)) terms << :object if object.is_a?(Variable) && (!name || name.eql?(object.name)) terms << :context if context.is_a?(Variable) && (!name || name.eql?(context.name)) terms end |
#variables ⇒ Hash{Symbol => Variable}
Returns all variables in this pattern.
Note: this returns a hash containing distinct variables only.
240 241 242 243 244 245 246 247 |
# File 'lib/rdf/query/pattern.rb', line 240 def variables variables = {} variables.merge!(subject.variables) if subject.is_a?(Variable) variables.merge!(predicate.variables) if predicate.is_a?(Variable) variables.merge!(object.variables) if object.is_a?(Variable) variables.merge!(context.variables) if context.is_a?(Variable) variables end |