activerdf_net7 1.6.16 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +63 -0
- data/activerdf-jena/lib/activerdf_jena/jena.rb +4 -4
- data/activerdf-jena/lib/activerdf_jena/jena_adapter.rb +55 -55
- data/activerdf-jena/lib/activerdf_jena/lucene.rb +1 -1
- data/activerdf-jena/lib/activerdf_jena/ng4j.rb +7 -7
- data/activerdf-jena/lib/activerdf_jena/ng4j_adapter.rb +47 -47
- data/activerdf-jena/lib/activerdf_jena/pellet.rb +1 -1
- data/activerdf-jena/test/test_jena_adapter.rb +121 -120
- data/activerdf-jena/test/test_ng4j_adapter.rb +111 -110
- data/activerdf-rdflite/lib/activerdf_rdflite/fetching.rb +23 -19
- data/activerdf-rdflite/lib/activerdf_rdflite/rdflite.rb +153 -277
- data/activerdf-rdflite/lib/activerdf_rdflite/suggesting.rb +2 -2
- data/activerdf-rdflite/test/test_fetching.rb +7 -22
- data/activerdf-rdflite/test/test_rdflite.rb +44 -257
- data/activerdf-redland/lib/activerdf_redland/redland.rb +246 -282
- data/activerdf-redland/test/test_redland_adapter.rb +62 -224
- data/activerdf-sesame/ext/wrapper-sesame2.jar +0 -0
- data/activerdf-sesame/java/build.number +2 -2
- data/activerdf-sesame/java/build.xml +0 -0
- data/activerdf-sesame/java/lib/junit-3.8.2.jar +0 -0
- data/activerdf-sesame/java/settings.xml +0 -0
- data/activerdf-sesame/java/src/org/activerdf/wrapper/sesame2/WrapperForSesame2.java +0 -0
- data/activerdf-sesame/java/temp/build/org/activerdf/wrapper/sesame2/WrapperForSesame2.class +0 -0
- data/activerdf-sesame/java/temp/manifest/MANIFEST.MF +2 -2
- data/activerdf-sesame/java/test-src/org/activerdf/wrapper/sesame2/TestWrapperForSesame2.java +0 -0
- data/activerdf-sesame/lib/activerdf_sesame/sesame.rb +360 -364
- data/activerdf-sesame/test/test_sesame_adapter.rb +85 -83
- data/activerdf-sparql/lib/activerdf_sparql/sparql.rb +147 -148
- data/activerdf-sparql/lib/activerdf_sparql/sparql_result_parser.rb +5 -5
- data/activerdf-sparql/test/test_sparql_adapter.rb +2 -0
- data/activerdf-yars/lib/activerdf_yars/jars2.rb +85 -83
- data/lib/active_rdf/federation/active_rdf_adapter.rb +26 -39
- data/lib/active_rdf/federation/connection_pool.rb +119 -110
- data/lib/active_rdf/federation/federation_manager.rb +51 -51
- data/lib/active_rdf/objectmanager/bnode.rb +8 -2
- data/lib/active_rdf/objectmanager/literal.rb +81 -50
- data/lib/active_rdf/objectmanager/namespace.rb +117 -84
- data/lib/active_rdf/objectmanager/object_manager.rb +101 -96
- data/lib/active_rdf/objectmanager/ordered_set.rb +1 -1
- data/lib/active_rdf/objectmanager/property.rb +345 -0
- data/lib/active_rdf/objectmanager/property_list.rb +4 -4
- data/lib/active_rdf/objectmanager/property_lookup.rb +57 -0
- data/lib/active_rdf/objectmanager/resource.rb +293 -501
- data/lib/active_rdf/objectmanager/resource_like.rb +2 -2
- data/lib/active_rdf/objectmanager/resource_query.rb +85 -0
- data/lib/active_rdf/queryengine/ntriples_parser.rb +75 -68
- data/lib/active_rdf/queryengine/query.rb +237 -183
- data/lib/active_rdf/queryengine/query2jars2.rb +17 -15
- data/lib/active_rdf/queryengine/query2sparql.rb +107 -101
- data/lib/active_rdf.rb +28 -17
- data/lib/active_rdf_helpers.rb +37 -5
- data/lib/active_rdf_log.rb +11 -11
- data/test/adapters/test_activerdf_adapter.rb +138 -0
- data/test/{test_adapters.rb → adapters/test_adapters.rb} +6 -24
- data/test/adapters/test_bnode_capable_adapter.rb +31 -0
- data/test/adapters/test_context_aware_adapter.rb +31 -0
- data/test/adapters/test_network_aware_adapter.rb +29 -0
- data/test/adapters/test_persistent_adapter.rb +21 -0
- data/test/adapters/test_read_only_adapter.rb +15 -0
- data/test/adapters/test_reasoning_adapter.rb +11 -0
- data/test/adapters/test_writable_adapter.rb +163 -0
- data/test/common.rb +78 -96
- data/test/federation/test_connection_pool.rb +25 -44
- data/test/federation/test_federation_manager.rb +45 -45
- data/test/objectmanager/test_literal.rb +47 -26
- data/test/objectmanager/test_namespace.rb +3 -1
- data/test/objectmanager/test_object_manager.rb +35 -45
- data/test/objectmanager/test_ordered_set.rb +1 -1
- data/test/objectmanager/test_property.rb +261 -0
- data/test/objectmanager/test_resource_reading.rb +196 -104
- data/test/objectmanager/test_resource_reasoning.rb +26 -0
- data/test/objectmanager/test_resource_writing.rb +34 -25
- data/test/queryengine/my_external_resource.rb +5 -1
- data/test/queryengine/test_external_resource_class.rb +1 -8
- data/test/queryengine/test_ntriples_parser.rb +5 -3
- data/test/queryengine/test_query.rb +3 -3
- data/test/queryengine/test_query2jars2.rb +2 -2
- data/test/queryengine/test_query2sparql.rb +2 -2
- data/test/queryengine/test_query_engine.rb +46 -28
- metadata +16 -8
- data/activerdf-rdflite/test/test_bnode_data.nt +0 -5
- data/activerdf-rdflite/test/test_data.nt +0 -32
- data/activerdf-rdflite/test/test_escaped_data.nt +0 -2
- data/activerdf-redland/test/test_person_data.nt +0 -42
- data/test/objectmanager/test_talia_syntax.rb +0 -68
@@ -1,33 +1,32 @@
|
|
1
1
|
# require 'active_rdf'
|
2
2
|
require 'federation/federation_manager'
|
3
|
-
require 'queryengine/query2sparql'
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
# features. Query is passed to federation manager or adapter for execution on
|
9
|
-
# data source. In all clauses symbols represent variables:
|
4
|
+
# Represents a query on a datasource, abstract representation of SPARQL
|
5
|
+
# features. Query is passed to federation manager or adapter for execution on
|
6
|
+
# data source. In all clauses symbols represent variables:
|
10
7
|
# Query.new.select(:s).where(:s,:p,:o).
|
11
|
-
|
12
|
-
|
8
|
+
module ActiveRDF
|
9
|
+
class Query
|
10
|
+
attr_reader :select_clauses, :where_clauses, :filter_clauses, :sort_clauses, :limits, :offsets, :keywords
|
13
11
|
|
14
|
-
|
12
|
+
bool_accessor :distinct, :ask, :select, :count, :keyword, :all_types
|
15
13
|
|
16
14
|
# Creates a new query. You may pass a different class that is used for "resource"
|
17
15
|
# type objects instead of RDFS::Resource
|
18
16
|
def initialize(resource_type = RDFS::Resource)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
17
|
+
@distinct = false
|
18
|
+
@select_clauses = []
|
19
|
+
@where_clauses = []
|
20
|
+
@filter_clauses = {}
|
21
|
+
@sort_clauses = []
|
22
|
+
@limits = nil
|
23
|
+
@offsets = nil
|
24
|
+
@keywords = {}
|
25
|
+
@reasoning = nil
|
26
|
+
@all_types = false
|
27
|
+
@nil_clause_idx = -1
|
29
28
|
set_resource_class(resource_type)
|
30
|
-
|
29
|
+
end
|
31
30
|
|
32
31
|
# This returns the class that is be used for resources, by default this
|
33
32
|
# is RDFS::Resource
|
@@ -39,207 +38,262 @@ class Query
|
|
39
38
|
# that it can be created using the uri of the resource as it's only
|
40
39
|
# parameter and that it has an 'uri' property
|
41
40
|
def set_resource_class(resource_class)
|
42
|
-
raise(ArgumentError, "resource_class must be a class") unless(resource_class.
|
41
|
+
raise(ArgumentError, "resource_class must be a class") unless(resource_class.class == Class)
|
43
42
|
|
44
43
|
test = resource_class.new("http://uri")
|
45
44
|
raise(ArgumentError, "Must have an uri property") unless(test.respond_to?(:uri))
|
46
45
|
@resource_class = resource_class
|
47
46
|
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
def initialize_copy(orig)
|
49
|
+
# dup the instance variables so we're not messing with the original query's values
|
50
|
+
instance_variables.each do |iv|
|
51
|
+
orig_val = instance_variable_get(iv)
|
52
|
+
case orig_val
|
53
|
+
when Array,Hash
|
54
|
+
instance_variable_set(iv,orig_val.dup)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
55
58
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
@select_clauses
|
59
|
+
|
60
|
+
# Clears the select clauses
|
61
|
+
def clear_select
|
62
|
+
ActiveRdfLogger::log_debug "Cleared select clause", self
|
63
|
+
@select_clauses = []
|
64
|
+
@distinct = false
|
61
65
|
end
|
62
|
-
# removing duplicate select clauses
|
63
|
-
@select_clauses.uniq!
|
64
|
-
self
|
65
|
-
end
|
66
66
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
67
|
+
# Adds variables to select clause
|
68
|
+
def select *s
|
69
|
+
raise(ActiveRdfError, "variable must be a Symbol") unless s.all?{|var| var.is_a?(Symbol)}
|
70
|
+
@select = true
|
71
|
+
# removing duplicate select clauses
|
72
|
+
@select_clauses.concat(s).uniq!
|
73
|
+
self
|
74
|
+
end
|
72
75
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
alias_method :select_distinct, :distinct
|
76
|
+
# Adds variables to ask clause (see SPARQL specification)
|
77
|
+
def ask
|
78
|
+
@ask = true
|
79
|
+
self
|
80
|
+
end
|
79
81
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
82
|
+
# Request reasoning be performed on query
|
83
|
+
def reasoning(bool)
|
84
|
+
@reasoning = truefalse(bool)
|
85
|
+
self
|
86
|
+
end
|
87
|
+
def reasoning=(bool)
|
88
|
+
self.reasoning(bool)
|
89
|
+
end
|
90
|
+
def reasoning?
|
91
|
+
@reasoning
|
92
|
+
end
|
85
93
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
94
|
+
# Set query to ignore language & datatypes for objects
|
95
|
+
def all_types(enabled = true)
|
96
|
+
@all_types = enabled
|
97
|
+
self
|
98
|
+
end
|
91
99
|
|
92
|
-
|
93
|
-
|
100
|
+
# Adds variables to select distinct clause
|
101
|
+
def distinct *s
|
102
|
+
@distinct = true
|
103
|
+
select(*s)
|
104
|
+
end
|
105
|
+
alias_method :select_distinct, :distinct
|
94
106
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
@filter_clauses.uniq!
|
107
|
+
# Adds variables to count clause
|
108
|
+
def count *s
|
109
|
+
@count = true
|
110
|
+
select(*s)
|
111
|
+
end
|
101
112
|
|
102
|
-
|
103
|
-
|
113
|
+
# Adds sort predicates
|
114
|
+
#
|
115
|
+
def sort *s
|
116
|
+
s.each do |var|
|
117
|
+
|
118
|
+
@sort_clauses << [var,:asc]
|
119
|
+
end
|
120
|
+
self
|
121
|
+
end
|
104
122
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
123
|
+
# adds reverse sorting predicates
|
124
|
+
def reverse_sort *s
|
125
|
+
s.each do |var|
|
126
|
+
raise(ActiveRdfError, "variable must be a Symbol") unless var.is_a? Symbol
|
127
|
+
@sort_clauses << [var,:desc]
|
128
|
+
end
|
129
|
+
self
|
130
|
+
end
|
111
131
|
|
112
|
-
filter
|
113
|
-
|
114
|
-
|
132
|
+
# adds operator filter on one variable
|
133
|
+
# variable is a Ruby symbol that appears in select/where clause, operator is a
|
134
|
+
# SPARQL operator (e.g. '>','lang','datatype'), operand is a SPARQL value (e.g. 15)
|
135
|
+
def filter(variable, operator, operand)
|
136
|
+
raise(ActiveRdfError, "variable must be a Symbol") unless variable.is_a? Symbol
|
137
|
+
@filter_clauses[variable] = [operator.to_sym,operand]
|
138
|
+
self
|
139
|
+
end
|
115
140
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
raise(ActiveRdfError, "variable must be a
|
141
|
+
# adds regular expression filter on one variable
|
142
|
+
# variable is Ruby symbol that appears in select/where clause, regex is Ruby
|
143
|
+
# regular expression
|
144
|
+
def regexp(variable, regexp)
|
145
|
+
raise(ActiveRdfError, "variable must be a symbol") unless variable.is_a? Symbol
|
146
|
+
regexp = regexp.source if(regexp.is_a?(Regexp))
|
121
147
|
|
122
|
-
filter
|
123
|
-
|
148
|
+
filter(variable, :regexp, regexp)
|
149
|
+
end
|
150
|
+
alias :regex :regexp
|
124
151
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
filter "lang(?#{variable} = '#{tag}'"
|
131
|
-
else
|
132
|
-
filter "regex(lang(?#{variable}), '^#{tag.gsub(/_.*/,'')}$')"
|
152
|
+
# filter variable on specified language tag, e.g. lang(:o, 'en', true)
|
153
|
+
# optionally matches exactly on language dialect, otherwise only
|
154
|
+
# language-specifier is considered
|
155
|
+
def lang(variable, tag, exact=true)
|
156
|
+
filter(variable,:lang,[tag.sub(/^@/,''),exact])
|
133
157
|
end
|
134
|
-
end
|
135
158
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
s.each { |clause| @reverse_sort_clauses << parametrise(clause) }
|
140
|
-
@reverse_sort_clauses.uniq!
|
141
|
-
|
142
|
-
self
|
143
|
-
end
|
159
|
+
def datatype(variable, type)
|
160
|
+
filter(variable,:datatype,type)
|
161
|
+
end
|
144
162
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
163
|
+
# Adds limit clause (maximum number of results to return)
|
164
|
+
def limit(i)
|
165
|
+
@limits = i.to_i
|
166
|
+
self
|
167
|
+
end
|
150
168
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
169
|
+
# Add offset clause (ignore first n results)
|
170
|
+
def offset(i)
|
171
|
+
@offsets = i.to_i
|
172
|
+
self
|
173
|
+
end
|
156
174
|
|
157
|
-
|
175
|
+
# Adds where clauses (s,p,o) where each constituent is either variable (:s) or
|
158
176
|
# an RDFS::Resource (or equivalent class). Keyword queries are specified with the special :keyword
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
+
# symbol: Query.new.select(:s).where(:s, :keyword, 'eyal')
|
178
|
+
def where s,p,o,c=nil
|
179
|
+
case p
|
180
|
+
when :keyword
|
181
|
+
# treat keywords in where-clauses specially
|
182
|
+
keyword_where(s,o)
|
183
|
+
else
|
184
|
+
# give nil clauses a unique variable
|
185
|
+
s,p,o = [s,p,o].collect{|clause| clause.nil? ? "nil#{@nil_clause_idx += 1}".to_sym : clause}
|
186
|
+
|
187
|
+
# remove duplicate variable bindings, e.g.
|
188
|
+
# where(:s,type,:o).where(:s,type,:oo) we should remove the second clause,
|
189
|
+
# since it doesn't add anything to the query and confuses the query
|
190
|
+
# generator.
|
191
|
+
# if you construct this query manually, you shouldn't! if your select
|
192
|
+
# variable happens to be in one of the removed clauses: tough luck.
|
193
|
+
unless (s.respond_to?(:uri) or s.is_a?(Symbol)) and (s.class != RDFS::BNode)
|
194
|
+
raise(ActiveRdfError, "Cannot add a where clause with s #{s}: s must be a resource or a variable, is a #{s.class.name}")
|
195
|
+
end
|
196
|
+
unless (p.respond_to?(:uri) or p.is_a?(Symbol)) and (s.class != RDFS::BNode)
|
177
197
|
raise(ActiveRdfError, "Cannot add a where clause with p #{p}: p must be a resource or a variable, is a #{p.class.name}")
|
198
|
+
end
|
199
|
+
raise(ActiveRdfErrror, "Cannot add a where clause where o is a blank node") if(o.class == RDFS::BNode)
|
200
|
+
|
201
|
+
@where_clauses << [s,p,o,c]
|
178
202
|
end
|
179
|
-
|
203
|
+
self
|
204
|
+
end
|
180
205
|
|
181
|
-
|
206
|
+
# Adds keyword constraint to the query. You can use all Ferret query syntax in
|
207
|
+
# the constraint (e.g. keyword_where(:s,'eyal|benjamin')
|
208
|
+
def keyword_where s,o
|
209
|
+
@keyword = true
|
210
|
+
if @keywords.include?(s)
|
211
|
+
@keywords[s] = @keywords[s] + ' ' + o
|
212
|
+
else
|
213
|
+
@keywords[s] = o
|
214
|
+
end
|
215
|
+
self
|
182
216
|
end
|
183
|
-
self
|
184
|
-
end
|
185
217
|
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
218
|
+
# Executes query on data sources. Either returns result as array
|
219
|
+
# (flattened into single value unless specified otherwise)
|
220
|
+
# or executes a block (number of block variables should be
|
221
|
+
# same as number of select variables)
|
222
|
+
#
|
223
|
+
# usage:: results = query.execute
|
224
|
+
# usage:: query.execute do |s,p,o| ... end
|
225
|
+
def execute(options={:flatten => false}, &block)
|
226
|
+
options = {:flatten => true} if options == :flatten
|
227
|
+
|
228
|
+
prepared_query = prepare_query(options)
|
229
|
+
|
230
|
+
if block_given?
|
231
|
+
for result in FederationManager.execute(prepared_query, options.merge(:flatten => false))
|
232
|
+
yield result
|
233
|
+
end
|
234
|
+
else
|
235
|
+
FederationManager.execute(prepared_query, options)
|
236
|
+
end
|
237
|
+
end
|
198
238
|
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
# usage:: query.execute do |s,p,o| ... end
|
206
|
-
def execute(options={:flatten => false}, &block)
|
207
|
-
options = {:flatten => true} if options == :flatten
|
208
|
-
|
209
|
-
if block_given?
|
210
|
-
for result in FederationManager.query(self, options)
|
211
|
-
yield result
|
239
|
+
# Returns query string depending on adapter (e.g. SPARQL, N3QL, etc.)
|
240
|
+
def to_s
|
241
|
+
if ConnectionPool.read_adapters.empty?
|
242
|
+
inspect
|
243
|
+
else
|
244
|
+
ConnectionPool.read_adapters.first.translate(prepare_query)
|
212
245
|
end
|
213
|
-
else
|
214
|
-
FederationManager.query(self, options)
|
215
246
|
end
|
216
|
-
end
|
217
247
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
else
|
223
|
-
ConnectionPool.read_adapters.first.translate(self)
|
248
|
+
# Returns SPARQL serialisation of query
|
249
|
+
def to_sp
|
250
|
+
require 'queryengine/query2sparql' unless(defined?(Query2SPARQL))
|
251
|
+
Query2SPARQL.translate(self)
|
224
252
|
end
|
225
|
-
end
|
226
253
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
254
|
+
private
|
255
|
+
def prepare_query(options = {})
|
256
|
+
# leave the original query intact
|
257
|
+
dup = self.dup
|
258
|
+
dup.expand_obj_values
|
259
|
+
# dup.reasoned_query if dup.reasoning?
|
260
|
+
|
261
|
+
# extract options
|
262
|
+
if options.include?(:order)
|
263
|
+
dup.sort(:sort_value)
|
264
|
+
dup.where(:s, options.delete(:order), :sort_value)
|
265
|
+
end
|
231
266
|
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
when Symbol, Literal, Class, nil
|
236
|
-
s
|
237
|
-
else
|
238
|
-
if(s.respond_to?(:uri))
|
239
|
-
s
|
240
|
-
else
|
241
|
-
'"' + s.to_s + '"'
|
267
|
+
if options.include?(:reverse_order)
|
268
|
+
dup.reverse_sort(:sort_value)
|
269
|
+
dup.where(:s, options.delete(:reverse_order), :sort_value)
|
242
270
|
end
|
271
|
+
|
272
|
+
dup.limit(options.delete(:limit)) if options.include?(:limit)
|
273
|
+
dup.offset(options.delete(:offset)) if options.include?(:offset)
|
274
|
+
|
275
|
+
dup
|
243
276
|
end
|
277
|
+
|
278
|
+
protected
|
279
|
+
def expand_obj_values
|
280
|
+
new_where_clauses = []
|
281
|
+
@where_clauses.each do |s,p,o,c|
|
282
|
+
if o.respond_to?(:to_ary)
|
283
|
+
o.to_ary.each{|elem| new_where_clauses << [s,p,elem,c]}
|
284
|
+
else
|
285
|
+
new_where_clauses << [s,p,o,c]
|
286
|
+
end
|
287
|
+
end
|
288
|
+
@where_clauses = new_where_clauses
|
289
|
+
end
|
290
|
+
|
291
|
+
# def reasoned_query
|
292
|
+
# new_where_clauses = []
|
293
|
+
# @where_clauses.each do |s,p,o,c|
|
294
|
+
# # other reasoning should be added here
|
295
|
+
# end
|
296
|
+
# @where_clauses += new_where_clauses
|
297
|
+
# end
|
244
298
|
end
|
245
|
-
end
|
299
|
+
end
|
@@ -2,21 +2,23 @@
|
|
2
2
|
|
3
3
|
# Translates abstract query into jars2 query.
|
4
4
|
# (ignores ASK queries)
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
5
|
+
module ActiveRDF
|
6
|
+
class Query2Jars2
|
7
|
+
def self.translate(query)
|
8
|
+
str = ""
|
9
|
+
if query.select?
|
10
|
+
# concatenate each where clause using space: s p o
|
11
|
+
# and then concatenate the clauses using dot: s p o . s2 p2 o2 .
|
12
|
+
str << "#{query.where_clauses.collect{|w| w.collect{|w| '?'+w.to_s}.join(' ')}.join(" .\n")} ."
|
13
|
+
# TODO: should we maybe reverse the order on the where_clauses? it depends
|
14
|
+
# on Andreas' answer of the best order to give to jars2. Users would
|
15
|
+
# probably put the most specific stuff first, and join to get the
|
16
|
+
# interesting information. Maybe we should not touch it and let the user
|
17
|
+
# figure it out.
|
18
|
+
end
|
18
19
|
|
19
20
|
ActiveRdfLogger::log_debug(self) { "Query2Jars2: translated #{query} to #{str}" }
|
20
|
-
|
21
|
+
return str
|
22
|
+
end
|
21
23
|
end
|
22
|
-
end
|
24
|
+
end
|