Class: RDF::Query

Inherits:
Object show all
Includes:
Enumerable
Defined in:
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query/pattern.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query/solution.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query/variable.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query/solutions.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query/hash_pattern_normalizer.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-n3-a6ef81a7e1ce/lib/rdf/n3/extensions.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/rdf-spec-4f36efa2dbbc/lib/rdf/spec/inspects.rb,
vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb

Overview

An RDF basic graph pattern (BGP) query.

Named queries either match against a specifically named graph if the name is an RDF::Resource or bound RDF::Query::Variable. Names that are against unbound variables match either default or named graphs. The name of false will only match against the default graph.

Variable names cause the variable to be added to the solution set elements.

Examples:

Constructing a basic graph pattern query (1)

query = RDF::Query.new do
  pattern [:person, RDF.type,  FOAF.Person]
  pattern [:person, FOAF.name, :name]
  pattern [:person, FOAF.mbox, :email]
end

Constructing a basic graph pattern query (2)

query = RDF::Query.new({
  person: {
    RDF.type  => FOAF.Person,
    FOAF.name => :name,
    FOAF.mbox => :email,
  }
})

Executing a basic graph pattern query

graph = RDF::Graph.load('etc/doap.nt')
query.execute(graph).each do |solution|
  puts solution.inspect
end

Constructing and executing a query in one go (1)

solutions = RDF::Query.execute(graph) do
  pattern [:person, RDF.type, FOAF.Person]
end

Constructing and executing a query in one go (2)

solutions = RDF::Query.execute(graph, {
  person: {
    RDF.type => FOAF.Person,
  }
})

In this example, the default graph contains the names of the publishers of two named graphs. The triples in the named graphs are not visible in the default graph in this example.

# default graph
@prefix dc: <http://purl.org/dc/elements/1.1/

<http://example.org/bob>    dc:publisher  "Bob" .
<http://example.org/alice>  dc:publisher  "Alice" .

# Named graph: http://example.org/bob
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Bob" .
_:a foaf:mbox <mailto:bob@oldcorp.example.org> .

# Named graph: http://example.org/alice
@prefix foaf: <http://xmlns.com/foaf/0.1/> .

_:a foaf:name "Alice" .
_:a foaf:mbox <mailto:alice@work.example.org> .

See Also:

Since:

  • 0.3.0

Direct Known Subclasses

SPARQL::Client::Query

Defined Under Namespace

Classes: HashPatternNormalizer, Pattern, Solution, Solutions, Variable

Instance Attribute Summary collapse

Attributes included from Enumerable

#existentials, #universals

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Enumerable

add_entailment, #canonicalize, #canonicalize!, #dump, #each_graph, #each_object, #each_predicate, #each_quad, #each_subject, #each_term, #each_triple, #entail, #enum_graph, #enum_object, #enum_predicate, #enum_quad, #enum_statement, #enum_subject, #enum_term, #enum_triple, #graph?, #graph_names, #invalid?, #method_missing, #object?, #objects, #predicate?, #predicates, #project_graph, #quad?, #quads, #respond_to_missing?, #statement?, #statements, #subject?, #subjects, #supports?, #term?, #terms, #to_a, #to_h, #to_set, #triple?, #triples

Methods included from Util::Aliasing::LateBound

#alias_method

Methods included from Isomorphic

#bijection_to, #isomorphic_with?

Methods included from Countable

#count

Constructor Details

#initialize(patterns = [], **options) {|query| ... } ⇒ Query #initialize(patterns, **options) ⇒ Query

Initializes a new basic graph pattern query.

Overloads:

  • #initialize(patterns = [], **options) {|query| ... } ⇒ Query

    Parameters:

    Options Hash (**options):

    • :solutions (RDF::Query::Solutions) — default: Solutions.new
    • :graph_name (RDF::Resource, RDF::Query::Variable, false) — default: nil

      Default graph name for matching against queryable. Queries with a graph name match against a specifically named graphs if the name is an Resource or bound Variable. Queries using an unbound variable as a graph name only match against named graphs, and will not match the default graph. The name of false will only match against the default graph.

    • :name (RDF::Resource, RDF::Query::Variable, false) — default: nil

      Alias for :graph_name.

    Yields:

    • (query)

    Yield Parameters:

    Yield Returns:

    • (void)

      ignored

  • #initialize(patterns, **options) ⇒ Query

    Parameters:

Parameters:

  • options (Hash)

    a customizable set of options

Options Hash (**options):

  • validate (Boolean) — default: false

    validate patterns @yield [query] @yieldparam [RDF::Query] query @yieldreturn [void] ignored

Since:

  • 0.3.0



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 183

def initialize(*patterns, solutions: nil, graph_name: nil, name: nil, validate: false, **options, &block)
  @options = options.dup
  @solutions = Query::Solutions(solutions)
  graph_name = name if graph_name.nil?
  @graph_name = graph_name

  patterns << @options if patterns.empty?

  @patterns  = case patterns.first
    when Hash  then compile_hash_patterns(HashPatternNormalizer.normalize!(patterns.first.dup, @options))
    when Array then patterns.first
    else patterns
  end

  if block_given?
    case block.arity
      when 1 then block.call(self)
      else instance_eval(&block)
    end
  end

  validate! if validate
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RDF::Enumerable

Instance Attribute Details

#graph_nameRDF::Resource, ...

Scope the query to named graphs matching value

Returns:

Since:

  • 0.3.0



141
142
143
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 141

def graph_name
  @graph_name
end

#optionsHash (readonly)

Any additional options for this query.

Returns:

Since:

  • 0.3.0



135
136
137
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 135

def options
  @options
end

#patternsArray<RDF::Query::Pattern> (readonly)

The patterns that constitute this query.

Returns:

Since:

  • 0.3.0



123
124
125
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 123

def patterns
  @patterns
end

#solutionsRDF::Query::Solutions (readonly)

The solution sequence for this query.

Returns:

Since:

  • 0.3.0



129
130
131
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 129

def solutions
  @solutions
end

Class Method Details

.execute(queryable, patterns = {}, options = {}) {|query| ... } ⇒ RDF::Query::Solutions

Executes a query on the given queryable graph or repository.

Parameters:

Yields:

  • (query)

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:

See Also:

Since:

  • 0.3.0



92
93
94
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 92

def self.execute(queryable, patterns = {}, options = {}, &block)
  self.new(patterns, **options, &block).execute(queryable, **options)
end

.SolutionsSolutions .Solutions(solutions) ⇒ Solutions .Solutions(array) ⇒ Solutions .Solutions(*args) ⇒ Solutions

Cast values as Solutions

Overloads:

  • .SolutionsSolutions

    Returns Solutions.new()

    Returns:

  • .Solutions(solutions) ⇒ Solutions

    Returns the argument

    Returns:

  • .Solutions(array) ⇒ Solutions

    Returns the array extended with solutions

    Parameters:

    Returns:

    • (Solutions)

      returns the array extended with solutions

  • .Solutions(*args) ⇒ Solutions

    Returns new solutions including the arguments, which must each be a Solution

    Parameters:

    Returns:

    • (Solutions)

      returns new solutions including the arguments, which must each be a Solution

Since:

  • 0.3.0



111
112
113
114
115
116
117
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 111

def self.Solutions(*args)
  if args.length == 1
    return args[0] if args[0].is_a?(Solutions)
    args = args[0] if args[0].is_a?(Array)
  end
  return Solutions.new(args)
end

Instance Method Details

#+(other) ⇒ RDF::Query

Add patterns from another query to form a new Query

Parameters:

Returns:

Since:

  • 0.3.0



413
414
415
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 413

def +(other)
  Query.new(self.patterns + other.patterns)
end

#<<(pattern)

This method returns an undefined value.

Appends the given query pattern to this query.

Parameters:

Since:

  • 0.3.0



213
214
215
216
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 213

def <<(pattern)
  @patterns << Pattern.from(pattern)
  self
end

#==(other) ⇒ Boolean

Equivalence for Queries: Same Patterns Same Context

Returns:

  • (Boolean)

Since:

  • 0.3.0



404
405
406
407
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 404

def ==(other)
  # FIXME: this should be graph_name == other.graph_name
  other.is_a?(RDF::Query) && patterns == other.patterns && graph_name == graph_name
end

#apply_graph_name(graph_name = nil) ⇒ Object

Apply the graph name specified (or configured) to all patterns that have no graph name

Parameters:

Since:

  • 0.3.0



438
439
440
441
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 438

def apply_graph_name(graph_name = nil)
  graph_name ||= self.graph_name
  patterns.each {|pattern| pattern.graph_name = graph_name if pattern.graph_name.nil?} unless graph_name.nil?
end

#bind(solution) ⇒ self

Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables

Parameters:

Returns:

  • (self)

Since:

  • 0.3.0



471
472
473
474
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 471

def bind(solution)
  patterns.each {|p| p.bind(solution)}
  self
end

#default?Boolean

Is this query scoped to the default graph?

Returns:

  • (Boolean)

Since:

  • 0.3.0



425
426
427
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 425

def default?
  graph_name == false
end

#dupRDF::Query

Duplicate query, including patterns and solutions

Returns:

Since:

  • 0.3.0



525
526
527
528
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 525

def dup
  patterns = @patterns.map {|p| p.dup}
  Query.new(patterns, graph_name: graph_name, solutions: @solutions.dup, **options)
end

#each_solution {|solution| ... } ⇒ Enumerator Also known as: each

Enumerates over each matching query solution.

Yields:

  • (solution)

Yield Parameters:

Returns:

Since:

  • 0.3.0



506
507
508
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 506

def each_solution(&block)
  @solutions.each(&block)
end

#each_statement {|RDF::Query::Pattern| ... } ⇒ Enumerator

Enumerates over each statement (pattern).

Yields:

Yield Parameters:

  • pattern (::Query::Pattern)

Returns:

Since:

  • 0.3.0



517
518
519
520
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 517

def each_statement(&block)
  apply_graph_name
  patterns.each(&block)
end

#empty?Boolean

Query has no patterns

Returns:

  • (Boolean)

Since:

  • 0.3.0



495
496
497
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 495

def empty?
  patterns.empty?
end

#executable?Boolean

Returns true as this is executable.

Returns:

  • (Boolean)

    true

Since:

  • 0.3.0



532
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 532

def executable?; true; end

#execute(queryable, bindings: {}, solutions: Solution.new, graph_name: nil, name: nil, **options) {|solution| ... } ⇒ RDF::Query::Solutions

Note:

solutions could be an Iterator, but this algorithm cycles over solutions, which requires them to be an array internally.

Executes this query on the given queryable graph or repository.

Named queries either match against a specifically named graphs if the name is an RDF::Resource or bound RDF::Query::Variable. Names that are against unbound variables match either detault or named graphs. The name of false will only match against the default graph.

If the query nas no patterns, it returns a single empty solution as per SPARQL 1.1 Empty Group Pattern.

Parameters:

  • queryable (RDF::Queryable)

    the graph or repository to query

  • solutions (RDF::Query::Solutions) (defaults to: Solution.new)

    (Solutions.new)

  • graph_name (RDF::Resource, RDF::Query::Variable, false) (defaults to: nil)

    (nil) Default graph name for matching against queryable. Queries with a graph name match against a specifically named graphs if the name is an Resource or bound Variable. Queries using an unbound variable as a graph name only match against named graphs, and will not match the default graph. The name of false will only match against the default graph.

  • name (RDF::Resource, RDF::Query::Variable, false) (defaults to: nil)

    (nil) Alias for :graph_name.

  • options (Hash{Symbol => Object})

    any additional keyword options

Options Hash (**options):

Yields:

  • (solution)

    each matching solution

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:

See Also:

Since:

  • 0.3.0



308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 308

def execute(queryable, bindings: {}, solutions: Solution.new, graph_name: nil, name: nil, **options, &block)
  # Use provided solutions to allow for query chaining
  # Otherwise, a quick empty solution simplifies the logic below; no special case for
  # the first pattern
  @solutions = Query::Solutions(solutions)
  bindings = bindings.to_h if bindings.is_a?(Solution)

  # If there are no patterns, just return the empty solution
  if empty?
    @solutions.each(&block) if block_given?
    return @solutions
  end

  self.optimize! if options[:optimize]
  patterns = @patterns
  graph_name = name if graph_name.nil?
  @graph_name = graph_name unless graph_name.nil?

  # Add graph_name to pattern, if necessary
  unless @graph_name.nil?
    if patterns.empty?
      patterns = [Pattern.new(nil, nil, nil, graph_name: @graph_name)]
    else
      apply_graph_name(@graph_name)
    end
  end

  patterns.each do |pattern|

    old_solutions, @solutions = @solutions, Query::Solutions()

    bindings.each_key do |variable|
      if pattern.variables.include?(variable)
        unbound_solutions, old_solutions = old_solutions, Query::Solutions()
        Array(bindings[variable]).each do |binding|
          unbound_solutions.each do |solution|
            old_solutions << solution.merge(variable => binding)
          end
        end
        bindings.delete(variable)
      end
    end

    old_solutions.each do |solution|
      found_match = false
      pattern.execute(queryable, solution) do |statement|
        found_match = true
        @solutions << solution.merge(pattern.solution(statement))
      end
      # If this pattern was optional, and we didn't find any matches,
      # just copy it over as-is.
      if !found_match && pattern.optional?
        @solutions << solution
      end
    end

    #puts "solutions after #{pattern} are #{@solutions.to_a.inspect}"

    # It's important to abort failed queries quickly because later patterns
    # that can have constraints are often broad without them.
    # We have no solutions at all:
    return @solutions if @solutions.empty?

    if !pattern.optional?
      # We have no solutions for variables we should have solutions for
      # (excludes non-distinguished variables):
      need_vars = pattern.variables.select {|k,v| v.distinguished?}.keys
      @solutions.each do |solution|
        break if need_vars.empty?
        need_vars -= solution.bindings.keys
      end
      return Query::Solutions() unless need_vars.empty?
    end
  end
  @solutions.each(&block) if block_given?
  @solutions
end

#failed?Boolean

Returns true if this query did not match when last executed.

When the solution sequence is empty, this method can be used to determine whether the query failed to match or not.

Returns:

  • (Boolean)

See Also:

Since:

  • 0.3.0



394
395
396
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 394

def failed?
  @solutions.empty?
end

#inspectObject

Since:

  • 0.3.0



31
32
33
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-spec-4f36efa2dbbc/lib/rdf/spec/inspects.rb', line 31

def inspect
  "RDF::Query(#{graph_name ? graph_name.to_sxp : 'nil'})#{patterns.inspect}"
end

#matched?Boolean

Returns true if this query matched when last executed.

When the solution sequence is empty, this method can be used to determine whether the query matched successfully or not.

Returns:

  • (Boolean)

See Also:

Since:

  • 0.3.0



406
407
408
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 406

def matched?
  !failed?
end

#named?Boolean

Is this query scoped to a named graph?

Returns:

  • (Boolean)

Since:

  • 0.3.0



419
420
421
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 419

def named?
  !!graph_name
end

#ndvarsArray<RDF::Query::Variable>

Return the non-destinguished variables contained within patterns and graph name

Returns:

Since:

  • 0.3.0



497
498
499
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 497

def ndvars
  vars.reject(&:distinguished?)
end

#node?Boolean Also known as: has_blank_nodes?

Returns true if any pattern contains a blank node.

Returns:

  • (Boolean)

Since:

  • 2.0



489
490
491
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 489

def node?
  patterns.any?(&:node?) || graph_name && graph_name.node?
end

#optimize(**options) ⇒ RDF::Query

Returns an optimized copy of this query.

Parameters:

Returns:

Since:

  • 0.3.0



240
241
242
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 240

def optimize(**options)
  self.dup.optimize!(**options)
end

#optimize!(**options) ⇒ self

Optimize the query, removing lexical shortcuts in URIs

Returns:

  • (self)

See Also:

Since:

  • 0.3.0



255
256
257
258
259
260
261
262
263
264
265
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 255

def optimize!(**options)
  optional, required = @patterns.uniq.partition(&:optional?)
  required.sort! do |a, b|
    (a.cost || 0) <=> (b.cost || 0)
  end
  optional.sort! do |a, b|
    (a.cost || 0) <=> (b.cost || 0)
  end
  @patterns = required + optional
  self
end

#optimize_without_expression!self

Optimizes this query by reordering its constituent triple patterns according to their cost estimates.

Optional patterns have greater cost than non-optional patterns so they will always come after non-optional patterns

Parameters:

Returns:

  • (self)

See Also:

Since:

  • 0.3.0



508
509
510
511
512
513
514
515
516
517
518
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 508

def optimize!(**options)
  optional, required = @patterns.uniq.partition(&:optional?)
  required.sort! do |a, b|
    (a.cost || 0) <=> (b.cost || 0)
  end
  optional.sort! do |a, b|
    (a.cost || 0) <=> (b.cost || 0)
  end
  @patterns = required + optional
  self
end

#pattern(pattern, **options)

This method returns an undefined value.

Appends the given query pattern to this query.

Parameters:

Options Hash (**options):

  • :optional (Boolean) — default: false

    whether this is an optional pattern

Since:

  • 0.3.0



228
229
230
231
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 228

def pattern(pattern, **options)
  @patterns << Pattern.from(pattern, **options)
  self
end

#query_yields_boolean?Boolean

Query results in a boolean result (e.g., ASK)

Returns:

  • (Boolean)

Since:

  • 0.3.0



478
479
480
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 478

def query_yields_boolean?
  false
end

#query_yields_solutions?Boolean

Query results solutions (e.g., SELECT)

Returns:

  • (Boolean)

Since:

  • 0.3.0



490
491
492
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 490

def query_yields_solutions?
  true
end

#query_yields_statements?Boolean

Query results statements (e.g., CONSTRUCT, DESCRIBE, CREATE)

Returns:

  • (Boolean)

Since:

  • 0.3.0



484
485
486
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 484

def query_yields_statements?
  false
end

#rewrite(&block) ⇒ SPARQL::Algebra::Expression

Don't do any more rewriting

Returns:

Since:

  • 0.3.0



412
413
414
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 412

def rewrite(&block)
  self
end

#to_sparql(top_level: true, filter_ops: [], **options) ⇒ String

Returns a partial SPARQL grammar for this query.

Parameters:

  • top_level (Boolean) (defaults to: true)

    (true) Treat this as a top-level, generating SELECT ... WHERE {}

  • filter_ops (Array<Operator>) (defaults to: [])

    ([]) Filter Operations

Returns:

Since:

  • 0.3.0



441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 441

def to_sparql(top_level: true, filter_ops: [], **options)
  str = @patterns.map do |e|
    e.to_sparql(top_level: false, **options) + " . \n"
  end.join("")
  str = "GRAPH #{graph_name.to_sparql(**options)} {\n#{str}\n}\n" if graph_name
  if top_level
    SPARQL::Algebra::Operator.to_sparql(str, filter_ops: filter_ops, **options)
  else
    # Filters
    filter_ops.each do |op|
      str << "\nFILTER (#{op.to_sparql(**options)}) ."
    end

    # Extensons
    extensions = options.fetch(:extensions, [])
    extensions.each do |as, expression|
      v = expression.to_sparql(**options)
      pp = RDF::Query::Variable.new(as).to_sparql(**options)
      str << "\nBIND (" << v << " AS " << pp << ") ."
    end
    str = "{#{str}}" unless filter_ops.empty? && extensions.empty?
    str
  end
end

#to_sxp_binArray

Transform Query into an Array form of an SSE

If Query has the as_container option set, serialize as Quads Otherwise, If Query is named, serialize as a GroupGraphPattern. Otherise, serialize as a BGP

Returns:

Since:

  • 0.3.0



423
424
425
426
427
428
429
430
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 423

def to_sxp_bin
  if options[:as_container]
    [:graph, graph_name] + [patterns.map(&:to_sxp_bin)]
  else
    res = [:bgp] + patterns.map(&:to_sxp_bin)
    (graph_name ? [:graph, graph_name, res] : res)
  end
end

#unnamed?Boolean

Is this query unscoped? This indicates that it can return results from either a named graph or the default graph.

Returns:

  • (Boolean)

Since:

  • 0.3.0



432
433
434
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 432

def unnamed?
  graph_name.nil?
end

#valid?Boolean

Determine if the query containts valid patterns

Returns:

  • (Boolean)

    true or false

Since:

  • 0.3.9



535
536
537
538
539
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 535

def valid?
  !!validate! rescue raise false
rescue
  false
end

#validate!RDF::Query

Validate this query, making sure it can be executed by our query engine. This method is public so that it may be called by implementations of RDF::Queryable#query_execute that bypass our built-in query engine.

Returns:

Raises:

  • (ArgumentError)

    This query cannot be executed.

Since:

  • 0.3.0



548
549
550
551
552
553
554
555
556
557
558
559
560
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 548

def validate!
  # All patterns must be valid
  @patterns.each(&:validate!)

  # All optional patterns must appear after the regular patterns.
  if i = @patterns.find_index(&:optional?)
    unless @patterns[i..-1].all?(&:optional?)
      raise ArgumentError.new("Optional patterns must appear at end of query")
    end
  end

  self
end

#variable?Boolean #variable?(variables) ⇒ Boolean Also known as: variables?, has_variables?

Overloads:

  • #variable?Boolean

    Returns true if any pattern contains a variable.

    Returns:

    • (Boolean)
  • #variable?(variables) ⇒ Boolean

    Returns true if any pattern contains any of the variables.

    Parameters:

    Returns:

    • (Boolean)

Since:

  • 0.3.0



453
454
455
456
457
458
459
460
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 453

def variable?(*args)
  case args.length
  when 0 then !variables.empty?
  when 1
    patterns.any? {|p| p.variable?(*args)}
  else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
  end
end

#variable_countInteger

Returns the number of variables in this query.

Returns:

Since:

  • 0.3.0



480
481
482
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 480

def variable_count
  variables.keys.length
end

#variablesHash{Symbol => RDF::Query::Variable}

The variables used in this query. This includes variables used in patterns along with the graph_name itself, if it is a variable.

Returns:

Since:

  • 0.3.0



468
469
470
471
472
473
474
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/rdf-196b73b4a78a/lib/rdf/query.rb', line 468

def variables
  # Set variables used in query
  vars = patterns.inject({}) do |memo, pattern|
    memo.merge(pattern.variables)
  end
  graph_name.is_a?(Variable) ? vars.merge(graph_name.to_sym => graph_name) : vars
end

#varsArray<RDF::Query::Variable>

Return the variables contained within patterns and graph name

Returns:

Since:

  • 0.3.0



504
505
506
# File 'vendor/bundler/ruby/3.3.0/bundler/gems/sparql-36baa432eb7f/lib/sparql/algebra/extensions.rb', line 504

def vars
  variables.values
end