Module: RDF::Queryable

Includes:
Enumerable
Included in:
Dataset, Enumerable::Enumerator, Graph, Enumerator, Transaction
Defined in:
lib/rdf/mixin/queryable.rb,
lib/rdf/mixin/enumerator.rb

Overview

An RDF query mixin.

Classes that include this module should implement a #query_pattern method that yields RDF statements. Classes may also implement an optimized #query_execute method that yields RDF statements.

See Also:

Defined Under Namespace

Classes: Enumerator

Instance Method Summary collapse

Instance Method Details

#firstRDF::Statement #first(pattern) ⇒ RDF::Statement

Queries self for an RDF statement matching the given pattern and returns that statement if found.

Returns nil if no statements match pattern.

Overloads:

Returns:

Since:

  • 0.1.9


174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/rdf/mixin/queryable.rb', line 174

def first(pattern = nil)
  if pattern
    query(pattern) do |statement|
      return statement
    end
  elsif respond_to?(:each_statement)
    each_statement do |statement|
      return statement
    end
  else
    return super()
  end
  nil
end

#first_literalRDF::Literal #first_literal(pattern) ⇒ RDF::Literal

Queries self for RDF statements matching the given pattern and returns the first found object literal.

Returns nil if no statements match pattern or if none of the found statements have a literal as their object term.

Overloads:

Returns:

Since:

  • 0.1.9


265
266
267
268
269
270
# File 'lib/rdf/mixin/queryable.rb', line 265

def first_literal(pattern = nil)
  __send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
    return statement.object if statement.object.is_a?(RDF::Literal)
  end
  return nil
end

#first_objectRDF::Term #first_object(pattern) ⇒ RDF::Term

Queries self for an RDF statement matching the given pattern and returns the statement's object term.

Returns nil if no statements match pattern.

Overloads:

Since:

  • 0.1.9


242
243
244
245
246
247
# File 'lib/rdf/mixin/queryable.rb', line 242

def first_object(pattern = nil)
  __send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
    return statement.object
  end
  return nil
end

#first_predicateRDF::URI #first_predicate(pattern) ⇒ RDF::URI

Queries self for an RDF statement matching the given pattern and returns the statement's predicate term.

Returns nil if no statements match pattern.

Overloads:

Since:

  • 0.1.9


222
223
224
225
226
227
# File 'lib/rdf/mixin/queryable.rb', line 222

def first_predicate(pattern = nil)
  __send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
    return statement.predicate
  end
  return nil
end

#first_subjectRDF::Resource #first_subject(pattern) ⇒ RDF::Resource

Queries self for an RDF statement matching the given pattern and returns the statement's subject term.

Returns nil if no statements match pattern.

Overloads:

Since:

  • 0.1.9


202
203
204
205
206
207
# File 'lib/rdf/mixin/queryable.rb', line 202

def first_subject(pattern = nil)
  __send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
    return statement.subject
  end
  return nil
end

#first_valueObject #first_value(pattern) ⇒ Object

Queries self for RDF statements matching the given pattern and returns the value of the first found object literal.

Returns nil if no statements match pattern or if none of the found statements have a literal as their object term.

Overloads:

  • #first_valueObject

    Returns:

    • (Object)
  • #first_value(pattern) ⇒ Object

    Parameters:

    Returns:

    • (Object)

Since:

  • 0.1.9


286
287
288
# File 'lib/rdf/mixin/queryable.rb', line 286

def first_value(pattern = nil)
  (literal = first_literal(pattern)) ? literal.value : nil
end

#query(pattern, **options) {|statement| ... } ⇒ Enumerator<RDF::Statement>, ...

Note:

Since 2.0, this may return an Enumerable or an Enumerator in addition to Solutions

Queries self for RDF statements matching the given pattern.

This method delegates to the protected #query_pattern method for the actual lower-level query pattern matching implementation.

Examples:

Querying for statements having a given predicate

queryable.query([nil, RDF::Vocab::DOAP.developer, nil])
queryable.query({predicate: RDF::Vocab::DOAP.developer}) do |statement|
  puts statement.inspect
end

Querying for solutions from a BGP

query = RDF::Query.new {pattern [:s, :p, :o]}
queryable.query(query) do |solution|
  puts solution.inspect
end

Parameters:

Yields:

  • (statement)

    each matching statement

Yield Parameters:

Yield Returns:

  • (void)

    ignored

Returns:

Raises:

  • (TypeError)

See Also:


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/rdf/mixin/queryable.rb', line 44

def query(pattern, **options, &block)
  raise TypeError, "#{self} is not readable" if respond_to?(:readable?) && !readable?

  case pattern
    # A basic graph pattern (BGP) query:
    when Query
      solutions = RDF::Query::Solutions.new
      block = lambda {|solution| solutions << solution} unless block_given?
      before_query(pattern) if respond_to?(:before_query)
      query_execute(pattern, **options, &block)
      after_query(pattern) if respond_to?(:after_query)
      # Returns the solutions, not an enumerator
      solutions
 
    # A simple triple/quad pattern query:
    else
      pattern = Query::Pattern.from(pattern)
      before_query(pattern) if respond_to?(:before_query)
      enum = case
        # Blank triple/quad patterns are equivalent to iterating over
        # every statement, so as a minor optimization we'll just do that
        # directly instead of bothering with `#query_pattern`:
        when pattern.blank?
          if block_given?
            each(&block)
          else
            to_a.extend(Queryable)
          end

        # Constant triple/quad patterns are equivalent to looking up a
        # particular statement, so as a minor optimization we'll just do
        # that directly instead of bothering with `#query_pattern`:
        when pattern.constant?
          statement = Statement.from(pattern)
          if include?(statement)
            if block_given?
              yield statement
            else
              [statement]
            end
          end

        # Otherwise, we delegate to `#query_pattern`:
        else # pattern.variable?
          query_pattern(pattern, **options, &block)
      end
      after_query(pattern) if respond_to?(:after_query)
      enum
  end
end

#query_execute(query, **options) {|solution| ... } (protected)

This method returns an undefined value.

Queries self using the given basic graph pattern (BGP) query, yielding each matched solution to the given block.

Since RDF.rb 0.3.0, repository implementations can override this method in order to provide for storage-specific optimized graph pattern query execution.

Parameters:

  • query (RDF::Query)

    the query to execute

  • options (Hash{Symbol => Object})

    ({}) Any other options passed to query.execute

Yields:

  • (solution)

Yield Parameters:

Yield Returns:

  • (void)

    ignored

See Also:

Since:

  • 0.3.0


114
115
116
117
118
119
120
# File 'lib/rdf/mixin/queryable.rb', line 114

def query_execute(query, **options, &block)
  # By default, we let RDF.rb's built-in `RDF::Query#execute` handle BGP
  # query execution by breaking down the query into its constituent
  # triple patterns and invoking `RDF::Query::Pattern#execute` on each
  # pattern.
  query.execute(self, **options, &block)
end

#query_pattern(pattern, **options) {|statement| ... } (protected)

This method returns an undefined value.

Queries self for RDF statements matching the given pattern, yielding each matched statement to the given block.

Since RDF.rb 0.2.0, repository implementations should override this method in order to provide for storage-specific optimized triple pattern matching.

RDFStar (RDF*)

Statements may have embedded statements as either a subject or object, recursively.

Patterns may also have embedded patterns as either a subject or object, recursively.

When matching, match an embedded pattern against embedded statements, recursively. (see RDF::Query::Pattern#eql?)

Parameters:

  • pattern (RDF::Query::Pattern)

    the query pattern to match

  • options (Hash{Symbol => Object})

    ({}) Any other options

Yields:

  • (statement)

Yield Parameters:

Yield Returns:

  • (void)

    ignored

See Also:

Since:

  • 0.2.0


150
151
152
153
154
155
156
# File 'lib/rdf/mixin/queryable.rb', line 150

def query_pattern(pattern, **options, &block)
  # By default, we let Ruby's built-in `Enumerable#grep` handle the
  # matching of statements by iterating over all statements and calling
  # `RDF::Query::Pattern#===` on each statement.
  # @see http://ruby-doc.org/core/classes/Enumerable.html#M003121
  grep(pattern, &block)
end