Class: Query

Inherits:
Object
  • Object
show all
Defined in:
lib/active_rdf/queryengine/query.rb

Overview

Represents a query on a datasource, abstract representation of SPARQL features. Query is passed to federation manager or adapter for execution on data source. In all clauses symbols represent variables: Query.new.select(:s).where(:s,:p,:o).

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(resource_type = RDFS::Resource) ⇒ Query

Creates a new query. You may pass a different class that is used for “resource” type objects instead of RDFS::Resource



18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/active_rdf/queryengine/query.rb', line 18

def initialize(resource_type = RDFS::Resource)
  @distinct = false
  @limits = nil
  @offsets = nil
  @select_clauses = []
  @where_clauses = []
  @sort_clauses = []
  @filter_clauses = []
  @keywords = {}
  @reasoning = true
  @reverse_sort_clauses = []
  set_resource_class(resource_type)
end

Instance Attribute Details

#filter_clausesObject (readonly)

Returns the value of attribute filter_clauses.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def filter_clauses
  @filter_clauses
end

#keywordsObject (readonly)

Returns the value of attribute keywords.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def keywords
  @keywords
end

#limitsObject (readonly)

Returns the value of attribute limits.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def limits
  @limits
end

#offsetsObject (readonly)

Returns the value of attribute offsets.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def offsets
  @offsets
end

#reverse_sort_clausesObject (readonly)

Returns the value of attribute reverse_sort_clauses.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def reverse_sort_clauses
  @reverse_sort_clauses
end

#select_clausesObject (readonly)

Returns the value of attribute select_clauses.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def select_clauses
  @select_clauses
end

#sort_clausesObject (readonly)

Returns the value of attribute sort_clauses.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def sort_clauses
  @sort_clauses
end

#where_clausesObject (readonly)

Returns the value of attribute where_clauses.



12
13
14
# File 'lib/active_rdf/queryengine/query.rb', line 12

def where_clauses
  @where_clauses
end

Instance Method Details

#askObject

Adds variables to ask clause (see SPARQL specification)



68
69
70
71
# File 'lib/active_rdf/queryengine/query.rb', line 68

def ask
  @ask = true
  self
end

#clear_selectObject

Clears the select clauses



50
51
52
53
54
# File 'lib/active_rdf/queryengine/query.rb', line 50

def clear_select
  ActiveRdfLogger::log_debug "Cleared select clause"
  @select_clauses = []
  @distinct = false
end

#count(*s) ⇒ Object

Adds variables to count clause



81
82
83
84
# File 'lib/active_rdf/queryengine/query.rb', line 81

def count *s
  @count = true
  select(*s)
end

#distinct(*s) ⇒ Object Also known as: select_distinct

Adds variables to select distinct clause



74
75
76
77
# File 'lib/active_rdf/queryengine/query.rb', line 74

def distinct *s
  @distinct = true
  select(*s)
end

#execute(options = {:flatten => false}, &block) ⇒ Object

Executes query on data sources. Either returns result as array (flattened into single value unless specified otherwise) or executes a block (number of block variables should be same as number of select variables)

usage

results = query.execute

usage

query.execute do |s,p,o| … end



206
207
208
209
210
211
212
213
214
215
216
# File 'lib/active_rdf/queryengine/query.rb', line 206

def execute(options={:flatten => false}, &block)
  options = {:flatten => true} if options == :flatten

  if block_given?
    for result in FederationManager.query(self, options)
      yield result
    end
  else
    FederationManager.query(self, options)
  end
end

#filter(*s) ⇒ Object

adds one or more generic filters NOTE: you have to use SPARQL syntax for variables, eg. regex(?s, ‘abc’)



97
98
99
100
101
102
103
# File 'lib/active_rdf/queryengine/query.rb', line 97

def filter *s
  # add filter clauses
  @filter_clauses << s
  @filter_clauses.uniq!

  self
end

#filter_operator(variable, operator, operand) ⇒ Object

adds operator filter one one variable variable is a Ruby symbol that appears in select/where clause, operator is a SPARQL operator (e.g. ‘>’), operand is a SPARQL value (e.g. 15)

Raises:



119
120
121
122
123
# File 'lib/active_rdf/queryengine/query.rb', line 119

def filter_operator(variable, operator, operand)
  raise(ActiveRdfError, "variable must be a Symbol") unless variable.is_a? Symbol

  filter "?#{variable} #{operator} #{operand}"
end

#filter_regexp(variable, regexp) ⇒ Object Also known as: filter_regex

adds regular expression filter on one variable variable is Ruby symbol that appears in select/where clause, regex is Ruby regular expression

Raises:



108
109
110
111
112
113
# File 'lib/active_rdf/queryengine/query.rb', line 108

def filter_regexp(variable, regexp)
  raise(ActiveRdfError, "variable must be a symbol") unless variable.is_a? Symbol
  regexp = regexp.source if(regexp.is_a?(Regexp))

  filter "regex(str(?#{variable}), \"#{regexp}\")"
end

#keyword_where(s, o) ⇒ Object

Adds keyword constraint to the query. You can use all Ferret query syntax in the constraint (e.g. keyword_where(:s,‘eyal|benjamin’)



188
189
190
191
192
193
194
195
196
197
# File 'lib/active_rdf/queryengine/query.rb', line 188

def keyword_where s,o
  @keyword = true
  s = parametrise(s)
  if @keywords.include?(s)
    @keywords[s] = @keywords[s] + ' ' + o
  else
    @keywords[s] = o
  end
  self
end

#lang(variable, tag, exact = false) ⇒ Object

filter variable on specified language tag, e.g. lang(:o, ‘en’) optionally matches exactly on language dialect, otherwise only language-specifier is considered



128
129
130
131
132
133
134
# File 'lib/active_rdf/queryengine/query.rb', line 128

def lang variable, tag, exact=false
  if exact
    filter "lang(?#{variable} = '#{tag}'"
  else
    filter "regex(lang(?#{variable}), '^#{tag.gsub(/_.*/,'')}$')"
  end
end

#limit(i) ⇒ Object

Adds limit clause (maximum number of results to return)



146
147
148
149
# File 'lib/active_rdf/queryengine/query.rb', line 146

def limit(i)
  @limits = i.to_i
  self
end

#offset(i) ⇒ Object

Add offset clause (ignore first n results)



152
153
154
155
# File 'lib/active_rdf/queryengine/query.rb', line 152

def offset(i)
  @offsets = i.to_i
  self
end

#resource_classObject

This returns the class that is be used for resources, by default this is RDFS::Resource



34
35
36
# File 'lib/active_rdf/queryengine/query.rb', line 34

def resource_class
  @resource_class ||= RDFS::Resource
end

#reverse_sort(*s) ⇒ Object

adds reverse sorting predicates



137
138
139
140
141
142
143
# File 'lib/active_rdf/queryengine/query.rb', line 137

def reverse_sort *s
  # add sort clauses without duplicates
  s.each { |clause| @reverse_sort_clauses << parametrise(clause) }
  @reverse_sort_clauses.uniq!
  
  self
end

#select(*s) ⇒ Object

Adds variables to select clause



57
58
59
60
61
62
63
64
65
# File 'lib/active_rdf/queryengine/query.rb', line 57

def select *s
  @select = true
  s.each do |e|
    @select_clauses << parametrise(e) 
  end
  # removing duplicate select clauses
  @select_clauses.uniq!
  self
end

#set_resource_class(resource_class) ⇒ Object

Sets the resource_class. Any class may be used, however it is required that it can be created using the uri of the resource as it’s only parameter and that it has an ‘uri’ property

Raises:

  • (ArgumentError)


41
42
43
44
45
46
47
# File 'lib/active_rdf/queryengine/query.rb', line 41

def set_resource_class(resource_class)
  raise(ArgumentError, "resource_class must be a class") unless(resource_class.is_a?(Class))

  test = resource_class.new("http://uri")
  raise(ArgumentError, "Must have an uri property") unless(test.respond_to?(:uri))
  @resource_class = resource_class
end

#sort(*s) ⇒ Object

Adds sort predicates



87
88
89
90
91
92
93
# File 'lib/active_rdf/queryengine/query.rb', line 87

def sort *s
  # add sort clauses without duplicates
  s.each { |clause| @sort_clauses << parametrise(clause) }
  @sort_clauses.uniq!

  self
end

#to_sObject

Returns query string depending on adapter (e.g. SPARQL, N3QL, etc.)



219
220
221
222
223
224
225
# File 'lib/active_rdf/queryengine/query.rb', line 219

def to_s
  if ConnectionPool.read_adapters.empty?
    inspect 
  else
    ConnectionPool.read_adapters.first.translate(self)
  end
end

#to_spObject

Returns SPARQL serialisation of query



228
229
230
# File 'lib/active_rdf/queryengine/query.rb', line 228

def to_sp
  Query2SPARQL.translate(self)
end

#where(s, p, o, c = nil) ⇒ Object

Adds where clauses (s,p,o) where each constituent is either variable (:s) or an RDFS::Resource (or equivalent class). Keyword queries are specified with the special :keyword symbol: Query.new.select(:s).where(:s, :keyword, ‘eyal’)



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/active_rdf/queryengine/query.rb', line 160

def where s,p,o,c=nil
  case p
  when :keyword
    # treat keywords in where-clauses specially
    keyword_where(s,o)
  else
    # remove duplicate variable bindings, e.g.
    # where(:s,type,:o).where(:s,type,:oo) we should remove the second clause, 
    # since it doesn't add anything to the query and confuses the query 
    # generator. 
    # if you construct this query manually, you shouldn't! if your select 
    # variable happens to be in one of the removed clauses: tough luck.

    unless (s.respond_to?(:uri) or s.is_a?(Symbol)) and (!s.is_a?(RDFS::BNode))
      raise(ActiveRdfError, "Cannot add a where clause with s #{s}: s must be a resource or a variable")
    end
    unless (p.respond_to?(:uri) or p.is_a?(Symbol)) and (!s.is_a?(RDFS::BNode))
      raise(ActiveRdfError, "Cannot add a where clause with p #{p}: p must be a resource or a variable, is a #{p.class.name}")
    end
    raise(ActiveRdfErrror, "Cannot add a where clause where o is a blank node") if(o.is_a?(RDFS::BNode))

    @where_clauses << [s,p,o,c].collect{|arg| parametrise(arg)}
  end
  self
end