class RDF::Virtuoso::Query

A SPARQL query builder.

@example Iterating over all found solutions

query.each_solution { |solution| puts solution.inspect }

Constants

AGG_METHODS
SPARQL 1.1 Aggregates

@return [Query] @see www.w3.org/TR/sparql11-query/#defn_aggCount def count(*variables)

options[:count] = variables
self

end

Attributes

data_values[R]
form[R]
options[R]

@return [Hash{Symbol => Object}]

values[R]

@return [Array<[key, RDF::Value]>]

Public Class Methods

ask(**options) click to toggle source

Creates a boolean ‘ASK` query.

@param [Hash{Symbol => Object}] options @return [Query] @see www.w3.org/TR/rdf-sparql-query/#ask

# File lib/rdf/virtuoso/query.rb, line 32
def self.ask(**options)
  self.new(:ask, **options)
end
clear(*variables, **options) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 100
def self.clear(*variables, **options)
  self.new(:clear, **options).clear(variables.first)
end
construct(*patterns, **options) click to toggle source

Creates a graph ‘CONSTRUCT` query.

@param [Array<RDF::Query::Pattern, Array>] patterns @param [Hash{Symbol => Object}] options @return [Query] @see www.w3.org/TR/rdf-sparql-query/#construct

# File lib/rdf/virtuoso/query.rb, line 65
def self.construct(*patterns, **options)
  self.new(:construct, **options).construct(*patterns) # FIXME
end
create(*variables, **options) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 92
def self.create(*variables, **options)
  self.new(:create, **options).create(variables.first)
end
delete(*patterns, **options) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 88
def self.delete(*patterns, **options)
  self.new(:delete, **options).delete(*patterns) 
end
delete_data(*patterns, **options) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 84
def self.delete_data(*patterns, **options)
  self.new(:delete_data, **options).delete_data(*patterns)
end
describe(*variables, **options) click to toggle source

Creates a ‘DESCRIBE` query.

@param [Array<Symbol, RDF::URI>] variables @param [Hash{Symbol => Object}] options @return [Query] @see www.w3.org/TR/rdf-sparql-query/#describe

# File lib/rdf/virtuoso/query.rb, line 54
def self.describe(*variables, **options)
  self.new(:describe, **options).describe(*variables)
end
drop(*variables, **options) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 96
def self.drop(*variables, **options)
  self.new(:drop, **options).drop(variables.first)
end
insert(*patterns, **options) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 80
def self.insert(*patterns, **options)
  self.new(:insert, **options).insert(*patterns) 
end
insert_data(*patterns, **options) click to toggle source

Creates an ‘UPDATE` query.

@param [Array<RDF::Query::Pattern, Array>] patterns @param [Hash{Symbol => Object}] options @return [Query] @see www.w3.org/Submission/SPARQL-Update/

# File lib/rdf/virtuoso/query.rb, line 76
def self.insert_data(*patterns, **options)
  self.new(:insert_data, **options).insert_data(*patterns) 
end
new(form = :ask, **options, &block) click to toggle source

@param [Symbol, to_s] form @param [Hash{Symbol => Object}] options @yield [query] @yieldparam [Query]

Calls superclass method
# File lib/rdf/virtuoso/query.rb, line 109
def initialize(form = :ask, **options, &block)
  @form = form.respond_to?(:to_sym) ? form.to_sym : form.to_s.to_sym
  super([], **options, &block)
end
select(*variables, **options) click to toggle source

Creates a tuple ‘SELECT` query.

@param [Array<Symbol>] variables @param [Hash{Symbol => Object}] options @return [Query] @see www.w3.org/TR/rdf-sparql-query/#select

# File lib/rdf/virtuoso/query.rb, line 43
def self.select(*variables, **options)
  self.new(:select, **options).select(*variables)
end

Public Instance Methods

ask() click to toggle source

@return [Query] @see www.w3.org/TR/rdf-sparql-query/#ask

# File lib/rdf/virtuoso/query.rb, line 117
def ask
  @form = :ask
  self
end
build_patterns(patterns) click to toggle source

@private make RDF::Query::Pattern from triple array if not already done include :graph_name in Statement @return [RDF::Query::Pattern]

# File lib/rdf/virtuoso/query.rb, line 408
def build_patterns(patterns)
  patterns.map do |pattern|
    case pattern
    when RDF::Query::Pattern then pattern
    else RDF::Query::Pattern.new(*pattern.to_a)
    end
  end
end
clear(uri) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 230
def clear(uri)
  options[:graph] = uri
  self
end
construct(*patterns) click to toggle source

@param [Array<RDF::Query::Pattern, Array>] patterns @return [Query] @see www.w3.org/TR/rdf-sparql-query/#construct

# File lib/rdf/virtuoso/query.rb, line 146
def construct(*patterns)
  new_patterns = []
  patterns.each do |pattern|
    new_patterns << pattern.map do |value|
      if value.is_a?(Symbol)
        value = RDF::Query::Variable.new(value)
      elsif value.is_a?(RDF::URI) 
        value = value
      else
        value = RDF::Literal.new(value)
      end
    end
  end
  @data_values = build_patterns(new_patterns)
  self
end
create(uri) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 220
def create(uri)
  options[:graph] = uri
  self
end
define(string) click to toggle source

@param string @return [Query] @see www.w3.org/TR/rdf-sparql-query/#specDataset

# File lib/rdf/virtuoso/query.rb, line 238
def define(string)
  options[:define] = string
  self
end
delete(*patterns) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 203
def delete(*patterns)
  new_patterns = []
  patterns.each do |pattern|
    new_patterns << pattern.map do |value|
      if value.is_a?(Symbol)
        value = RDF::Query::Variable.new(value)
      elsif value.is_a?(RDF::URI) 
        value = value
      else
        value = RDF::Literal.new(value)
      end
    end
  end
  @data_values = build_patterns(new_patterns)
  self
end
delete_data(*patterns) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 194
def delete_data(*patterns)
  new_patterns = []
  patterns.each do |values|
    new_patterns << values.map { |var| [var, var.is_a?(RDF::URI) ? var : var] }
  end
  @data_values = new_patterns #build_patterns(new_patterns)
  self
end
describe(*variables) click to toggle source

@param [Array<Symbol>] variables @return [Query] @see www.w3.org/TR/rdf-sparql-query/#describe

# File lib/rdf/virtuoso/query.rb, line 135
def describe(*variables)
  @values = variables.map { |var|
    [var, var.is_a?(RDF::URI) ? var : RDF::Query::Variable.new(var)]
  }
  self
end
distinct(state = true) click to toggle source

@return [Query] @see www.w3.org/TR/rdf-sparql-query/#modDistinct

# File lib/rdf/virtuoso/query.rb, line 309
def distinct(state = true)
  options[:distinct] = state
  self
end
drop(uri) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 225
def drop(uri)
  options[:graph] = uri
  self
end
each_statement(&block) click to toggle source

@yield [statement] @yieldparam [RDF::Statement] @return [Enumerator]

# File lib/rdf/virtuoso/query.rb, line 456
def each_statement(&block)
  result.each_statement(&block)
end
false?() click to toggle source

@return [Boolean]

# File lib/rdf/virtuoso/query.rb, line 442
def false?
  !true?
end
filter(string) click to toggle source

@private

# File lib/rdf/virtuoso/query.rb, line 419
def filter(string)
  (options[:filters] ||= []) << string
  self
end
filters(filters = nil) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 424
def filters(filters = nil)
  options[:filters] ||= []
  options[:filters] += filters.to_a
  self
end
from(uri) click to toggle source

@param [RDF::URI] uri @return [Query] @see www.w3.org/TR/rdf-sparql-query/#specDataset

# File lib/rdf/virtuoso/query.rb, line 246
def from(uri)
  options[:from] = uri
  self
end
from_named(uri) click to toggle source

@param [RDF::URI] uri @return [Query]

# File lib/rdf/virtuoso/query.rb, line 253
def from_named(uri)
  (options[:from_named] ||= []) << uri
  self
end
graph(uri) click to toggle source

@param [RDF::URI] uri @return [Query]

# File lib/rdf/virtuoso/query.rb, line 260
def graph(uri)
  options[:graph] = uri
  self
end
graph2(uri) click to toggle source

@param [RDF::URI] uri @return [Query] Inline version of graph

# File lib/rdf/virtuoso/query.rb, line 290
def graph2(uri)
  @patterns += [Pattern.new(:graph_statement, uri)]
  self
end
group(*patterns) click to toggle source

@param [Array<RDF::Query::Pattern, Array>] patterns @return [Query] Group is a non-SPARQL function. It works same as where, but groups the patterns within brackets: { }, allowing to structure the query.

# File lib/rdf/virtuoso/query.rb, line 281
def group(*patterns)
  @patterns += [Pattern.new(:start_group_pattern)] + build_patterns(patterns) + [Pattern.new(:end_group_pattern)]
  self
end
insert(*patterns) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 177
def insert(*patterns)
  new_patterns = []
  patterns.each do |pattern|
    new_patterns << pattern.map do |value|
      if value.is_a?(Symbol)
        value = RDF::Query::Variable.new(value)
      elsif value.is_a?(RDF::URI) 
        value = value
      else
        value = RDF::Literal.new(value)
      end
    end
  end
  @data_values = build_patterns(new_patterns)
  self
end
insert_data(*patterns) click to toggle source

@param [Array<RDF::Query::Pattern, Array>] patterns @return [Query] @see www.w3.org/Submission/SPARQL-Update/

# File lib/rdf/virtuoso/query.rb, line 168
def insert_data(*patterns)
  new_patterns = []
  patterns.each do |values|
    new_patterns << values.map { |var| [var, var.is_a?(RDF::URI) ? var : var] }
  end
  @data_values = new_patterns #build_patterns(new_patterns)
  self
end
inspect() click to toggle source

Returns a developer-friendly representation of this query.

@return [String]

# File lib/rdf/virtuoso/query.rb, line 706
def inspect
  sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, to_s)
end
inspect!() click to toggle source

Outputs a developer-friendly representation of this query to ‘stderr`.

@return [void]

# File lib/rdf/virtuoso/query.rb, line 697
def inspect!
  warn(inspect)
  self
end
limit(length) click to toggle source

@param [Integer, to_i] length @return [Query] @see www.w3.org/TR/rdf-sparql-query/#modResultLimit

# File lib/rdf/virtuoso/query.rb, line 351
def limit(length)
  slice(nil, length)
end
minus(*patterns) click to toggle source

@return [Query] @see www.w3.org/TR/rdf-sparql-query/#minus

# File lib/rdf/virtuoso/query.rb, line 393
def minus(*patterns)
  (options[:minuses] ||= []) << build_patterns(patterns)
  self
end
offset(start) click to toggle source

@param [Integer, to_i] start @return [Query] @see www.w3.org/TR/rdf-sparql-query/#modOffset

# File lib/rdf/virtuoso/query.rb, line 343
def offset(start)
  slice(start, nil)
end
optional(*patterns) click to toggle source

@return [Query] @see www.w3.org/TR/rdf-sparql-query/#optionals

# File lib/rdf/virtuoso/query.rb, line 385
def optional(*patterns)
  (options[:optionals] ||= []) << build_patterns(patterns)
  self
end
order(*variables) click to toggle source

@param [Array<Symbol, String>] variables @return [Query] @see www.w3.org/TR/rdf-sparql-query/#modOrderBy

# File lib/rdf/virtuoso/query.rb, line 299
def order(*variables)
  options[:order_by] = variables
  self
end
Also aliased as: order_by
order_by(*variables)
Alias for: order
prefix(string) click to toggle source

@return [Query] @see www.w3.org/TR/rdf-sparql-query/#prefNames

# File lib/rdf/virtuoso/query.rb, line 368
def prefix(string)
  (options[:prefixes] ||= []) << string
  self
end
prefixes(prefixes = nil) click to toggle source

@return [Query] @see www.w3.org/TR/rdf-sparql-query/#prefNames

# File lib/rdf/virtuoso/query.rb, line 376
def prefixes(prefixes = nil)
  options[:prefixes] ||= []
  options[:prefixes] += prefixes.to_a
  self
end
reduced(state = true) click to toggle source

@return [Query] @see www.w3.org/TR/rdf-sparql-query/#modReduced

# File lib/rdf/virtuoso/query.rb, line 317
def reduced(state = true)
  options[:reduced] = state
  self
end
result() click to toggle source

@return [Object]

# File lib/rdf/virtuoso/query.rb, line 462
def result
  @result ||= execute
end
select(*variables) click to toggle source

@param [Array<Symbol>] variables @return [Query] @see www.w3.org/TR/rdf-sparql-query/#select

# File lib/rdf/virtuoso/query.rb, line 126
def select(*variables)
  @values = variables.map { |var| [var, RDF::Query::Variable.new(var)] }
  self
end
serialize_patterns(patterns) click to toggle source

@private

# File lib/rdf/virtuoso/query.rb, line 675
def serialize_patterns(patterns)
  if patterns.is_a?(RDF::Query::Pattern)
    if patterns.variables[:start_group_pattern]
      "{"
    elsif patterns.variables[:end_group_pattern]
      "}"
    elsif patterns.variables[:graph_statement]
      "GRAPH #{serialize_value(patterns[1])}"
    else
      patterns.to_triple.map { |v| serialize_value(v) }.join(' ') << " ."
    end
  else
    patterns.map do |p|
      p.to_triple.map { |v| serialize_value(v) }.join(' ') << " ."
    end
  end
end
serialize_value(value) click to toggle source

Serializes an RDF::Value into a format appropriate for select, construct, and where clauses

@param [RDF::Value] value @return [String] @private

# File lib/rdf/virtuoso/query.rb, line 716
def serialize_value(value)
  # SPARQL queries are UTF-8, but support ASCII-style Unicode escapes, so
  # the N-Triples serializer is fine unless it's a variable:
  case
    when value.is_a?(String) then value.inspect
    when value.is_a?(RDF::Query::Variable) then value.to_s
    else RDF::NTriples.serialize(value)
  end
end
slice(start, length) click to toggle source

@param [Integer, to_i] start @param [Integer, to_i] length @return [Query]

# File lib/rdf/virtuoso/query.rb, line 359
def slice(start, length)
  options[:offset] = start.to_i if start
  options[:limit] = length.to_i if length
  self
end
solutions() click to toggle source

@return [Enumerable<RDF::Query::Solution>]

# File lib/rdf/virtuoso/query.rb, line 448
def solutions
  result
end
to_s() click to toggle source

Returns the string representation of this query.

@return [String]

# File lib/rdf/virtuoso/query.rb, line 477
def to_s
  buffer = []
  buffer << "DEFINE #{options[:define]}" if options[:define]
  buffer << [form.to_s.gsub('_', ' ').upcase]
  case form
  when :select, :describe
    buffer << 'DISTINCT' if options[:distinct]
    buffer << 'REDUCED'  if options[:reduced]
    # Aggregates in select/describe
    aggregates = [:count, :min, :max, :avg, :sum, :sample, :group_concat, :group_digest]
    if (options.keys & aggregates).any?
      (options.keys & aggregates).each do |agg|
        case agg
        when :sample
          # multiple samples splits to individual sample expressions
          options[agg].each_slice(1) do |a|
            buffer << '(sql:' + agg.to_s.upcase
            a.map do |var| 
              buffer << (var.is_a?(String) ? var : "(?#{var})")
              buffer << "AS ?#{var})"
            end
          end
        when :group_concat
          # multiple samples splits to individual sample expressions
          options[agg].each_slice(2) do |a|
            buffer << '(sql:' + agg.to_s.upcase
            buffer << a.map {|var| (var.is_a?(Symbol) ? "(?#{var}" : var.is_a?(String) ? "'#{var}'" : var )}.join(', ')
            buffer << ') AS ?' + a.first.to_s + ')'
          end
        when :group_digest
          # multiple samples splits to individual sample expressions
          options[agg].each_slice(4) do |a|
            buffer << '(sql:' + agg.to_s.upcase
            buffer << a.map {|var| (var.is_a?(Symbol) ? "(?#{var}" : var.is_a?(String) ? "'#{var}'" : var )}.join(', ')
            buffer << ') AS ?' + a.first.to_s + ')'
          end              
        else
          # multiple samples splits to individual sample expressions
          options[agg].each_slice(1) do |a|
            buffer << '(' + agg.to_s.upcase
            a.map do |var| 
              buffer << (var.is_a?(String) ? var : "(?#{var})")
              buffer << "AS ?#{var})"
            end
          end
        end
        #
      end
      # also handle variables that are not aggregates
      buffer << values.map { |v| serialize_value(v[1]) }.join(' ') unless values.empty?
    else
      # no variables? select/describe all (*)
      buffer << (values.empty? ? '*' : values.map { |v| serialize_value(v[1]) }.join(' '))
    end
    
  when :construct
    buffer << '{'
    buffer += serialize_patterns(@data_values)
    buffer << '}'
    
    # for virtuoso inserts
  when :insert_data
    buffer << "INTO GRAPH #{serialize_value(options[:graph])}" if options[:graph]
    buffer << '{'
    @data_values.each do |triple|
      if triple.first.first.is_a?(RDF::Statement)
        buffer << triple.map { |v| serialize_value(v[1])}
      else
        buffer << triple.map { |v| serialize_value(v[1])}.join(' ') + " ."
      end
    end
    buffer << '}'          
    
  when :insert
    buffer << "INTO GRAPH #{serialize_value(options[:graph])}" if options[:graph]
    # buffer += serialize_patterns(options[:template])
    # (@data_values.map { |v| puts v[1].inspect; puts 'xxx ' } )
    buffer << '{'
    buffer += serialize_patterns(@data_values)
    buffer << '}'          
    
  when :delete_data
    buffer << "FROM #{serialize_value(options[:graph])}" if options[:graph]
    buffer << '{'
    @data_values.each do |triple|
      if triple.first.first.is_a?(RDF::Statement)
        buffer << triple.map { |v| serialize_value(v[1])}
      else
        buffer << triple.map { |v| serialize_value(v[1])}.join(' ') + " ."
      end
    end
    buffer << '}'          

  when :delete
    buffer << "FROM #{serialize_value(options[:graph])}" if options[:graph]
    buffer << '{'
    buffer += serialize_patterns(@data_values)
    buffer << '}'           

  when :create, :drop
    buffer << 'SILENT' if options[:silent]
    buffer << "GRAPH #{serialize_value(options[:graph])}"

  when :clear
    buffer << "GRAPH #{serialize_value(options[:graph])}"

  end

  buffer << "FROM #{serialize_value(options[:from])}" if options[:from]
  options[:from_named].each {|from_named| buffer << "FROM NAMED #{serialize_value(from_named)}" } if options[:from_named]


  unless patterns.empty? && ([:describe, :insert_data, :delete_data, :create, :clear, :drop].include?(form))
    buffer << 'WHERE {'

    buffer << '{' if options[:unions]

    # iterate patterns
    # does patterns have :graph_name hash? build with GRAPH statement
    patterns.each do | pattern|
      if pattern.graph_name
        buffer << "GRAPH #{serialize_value(RDF::URI(pattern.graph_name))}"
        buffer << '{'
        buffer << serialize_patterns(pattern)
        buffer << '}'
      else
        buffer << serialize_patterns(pattern)
      end
    end

    if options[:optionals]
      options[:optionals].each do |patterns|
        buffer << 'OPTIONAL {'

            patterns.each do | pattern|
      if pattern.graph_name
        buffer << "GRAPH #{serialize_value(RDF::URI(pattern.graph_name))}"
        buffer << '{'
        buffer << serialize_patterns(pattern)
        buffer << '}'
      else
        buffer << serialize_patterns(pattern)
      end
    end

        buffer << '}'
      end
    end

    if options[:minuses]
      options[:minuses].each do |patterns|
        buffer << 'MINUS {'

            patterns.each do | pattern|
      if pattern.graph_name
        buffer << "GRAPH #{serialize_value(RDF::URI(pattern.graph_name))}"
        buffer << '{'
        buffer << serialize_patterns(pattern)
        buffer << '}'
      else
        buffer << serialize_patterns(pattern)
      end
    end

        buffer << '}'
      end
    end

    if options[:filters]
      buffer += options[:filters].map { |filter| "FILTER(#{filter})" }
    end
    buffer << '}'

    if options[:unions]
      options[:unions].each do |patterns|
        buffer << 'UNION {'
        buffer += serialize_patterns(patterns)
        buffer << '}'
      end
      buffer << '}'
    end

  end

  if options[:order_by]
    buffer << 'ORDER BY'
    buffer += options[:order_by].map { |var| var.is_a?(String) ? var : "?#{var}" }
  end

  buffer << "OFFSET #{options[:offset]}" if options[:offset]
  buffer << "LIMIT #{options[:limit]}"   if options[:limit]
  options[:prefixes].reverse.each {|e| buffer.unshift("PREFIX #{e}") } if options[:prefixes]

  buffer.join(' ')
end
true?() click to toggle source

@return [Boolean]

# File lib/rdf/virtuoso/query.rb, line 432
def true?
  case result
  when TrueClass, FalseClass then result
  when Enumerable then !result.empty?
  else false
  end
end
union(*patterns) click to toggle source
# File lib/rdf/virtuoso/query.rb, line 398
def union(*patterns)
  (options[:unions] ||= []) << build_patterns(patterns)
  self
end
where(*patterns) click to toggle source

@param [Array<RDF::Query::Pattern, Array>] patterns @return [Query] @see www.w3.org/TR/rdf-sparql-query/#GraphPattern

# File lib/rdf/virtuoso/query.rb, line 269
def where(*patterns)
  @patterns += build_patterns(patterns)
  self
end
Also aliased as: whether
whether(*patterns)
Alias for: where