activerdf_net7 1.7.1 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -155,8 +155,7 @@ module ActiveRDF
155
155
  check_input = [s,p,o]
156
156
  raise ActiveRdfError, "cannot add triple with nil or blank node subject, predicate, or object" if check_input.any? {|r| r.nil? || r.is_a?(Symbol) }
157
157
 
158
- params = activerdf_to_sesame(s, p, o, c)
159
- @db.add(params[0], params[1], params[2], wrap_contexts(c))
158
+ @db.add(*activerdf_to_sesame(s, p, o, c))
160
159
  true
161
160
  rescue Exception => e
162
161
  raise ActiveRdfError, "Sesame add triple failed: #{e.message}"
@@ -370,7 +369,7 @@ module ActiveRDF
370
369
  }
371
370
 
372
371
  # wrap Context
373
- params << wrap_contexts(c) unless (c.nil?)
372
+ params << wrap_contexts(c)
374
373
 
375
374
  params
376
375
  end
@@ -381,7 +380,7 @@ module ActiveRDF
381
380
  def wrap(item, use_nil = false)
382
381
  result =
383
382
  if(item.respond_to?(:uri))
384
- if (item.uri.to_s[0..4].match(/http:/).nil?)
383
+ if (item.uri.to_s[0..4].match(/http:/i).nil?)
385
384
  @valueFactory.createLiteral(item.uri.to_s)
386
385
  else
387
386
  @valueFactory.createURI(item.uri.to_s)
@@ -7,7 +7,7 @@ include ActiveRdfBenchmark
7
7
 
8
8
  module ActiveRDF
9
9
  class FederationManager
10
- def FederationManager.contexts
10
+ def FederationManager.contexts
11
11
  ConnectionPool.adapters.collect{|adapter| adapter.contexts if adapter.respond_to?(:contexts)}.flatten.compact
12
12
  end
13
13
 
@@ -15,21 +15,21 @@ module ActiveRDF
15
15
  def FederationManager.add(s,p,o,c=nil)
16
16
  benchmark("SPARQL/RDF", Logger::DEBUG) do |bench_message|
17
17
  bench_message << "ADD #{s} - #{p} - #{o} : #{c}" if(bench_message)
18
- # TODO: allow addition of full graphs
19
- raise ActiveRdfError, "cannot write without a write-adapter" unless ConnectionPool.write_adapter
18
+ # TODO: allow addition of full graphs
19
+ raise ActiveRdfError, "cannot write without a write-adapter" unless ConnectionPool.write_adapter
20
20
  ConnectionPool.write_adapter.add(s,p,o,c)
21
- end
21
+ end
22
22
  end
23
23
 
24
24
  # delete triple s,p,o (context is optional) to the currently selected write-adapter
25
25
  def FederationManager.delete(s,p=nil,o=nil,c=nil)
26
26
  benchmark("SPARQL/RDF", Logger::DEBUG) do |bench_message|
27
27
  bench_message << "DELETE #{s} - #{p} - #{o} : #{c}" if(bench_message)
28
- raise ActiveRdfError, "cannot write without a write-adapter" unless ConnectionPool.write_adapter
29
- # transform wildcard symbols to nil (for the adaptors)
30
- s = nil if s.is_a? Symbol
31
- p = nil if p.is_a? Symbol
32
- o = nil if o.is_a? Symbol
28
+ raise ActiveRdfError, "cannot write without a write-adapter" unless ConnectionPool.write_adapter
29
+ # transform wildcard symbols to nil (for the adaptors)
30
+ s = nil if s.is_a? Symbol
31
+ p = nil if p.is_a? Symbol
32
+ o = nil if o.is_a? Symbol
33
33
  ConnectionPool.write_adapter.delete(s,p,o,c)
34
34
  end
35
35
  end
@@ -57,56 +57,56 @@ module ActiveRDF
57
57
  benchmark("SPARQL/RDF", Logger::DEBUG) do |bench_message|
58
58
  # Only build the benchmark message if we need it
59
59
  bench_message << ((q.class == String) ? q : q.to_sp) if(bench_message)
60
- # ask each adapter for query results
61
- # and yield them consequtively
62
- if block_given?
63
- ConnectionPool.read_adapters.each do |source|
64
- source.execute(q) do |*clauses|
65
- yield(*clauses)
60
+ # ask each adapter for query results
61
+ # and yield them consequtively
62
+ if block_given?
63
+ ConnectionPool.read_adapters.each do |source|
64
+ source.execute(q) do |*clauses|
65
+ yield(*clauses)
66
+ end
66
67
  end
67
- end
68
- else
69
- # build Array of results from all sources
70
- # TODO: write test for sebastian's select problem
71
- # (without distinct, should get duplicates, they
72
- # were filtered out when doing results.union)
73
- results = []
74
- ConnectionPool.read_adapters.each do |source|
75
- source_results = source.execute(q)
76
- source_results.each do |clauses|
77
- results << clauses
68
+ else
69
+ # build Array of results from all sources
70
+ # TODO: write test for sebastian's select problem
71
+ # (without distinct, should get duplicates, they
72
+ # were filtered out when doing results.union)
73
+ results = []
74
+ ConnectionPool.read_adapters.each do |source|
75
+ source_results = source.execute(q)
76
+ source_results.each do |clauses|
77
+ results << clauses
78
+ end
78
79
  end
79
- end
80
80
 
81
- # count
82
- return results.flatten.inject{|mem,c| mem + c} if q.count?
81
+ # count
82
+ return results.flatten.inject{|mem,c| mem + c} if q.count?
83
83
 
84
- # filter the empty results
85
- results.reject {|ary| ary.empty? }
84
+ # filter the empty results
85
+ results.reject {|ary| ary.empty? }
86
86
 
87
- # remove duplicate results from multiple
88
- # adapters if asked for distinct query
89
- # (adapters return only distinct results,
90
- # but they cannot check duplicates against each other)
91
- results.uniq! if q.distinct?
87
+ # remove duplicate results from multiple
88
+ # adapters if asked for distinct query
89
+ # (adapters return only distinct results,
90
+ # but they cannot check duplicates against each other)
91
+ results.uniq! if q.distinct?
92
92
 
93
- # flatten results array if only one select clause
94
- # to prevent unnecessarily nested array [[eyal],[renaud],...]
95
- results.flatten! if q.select_clauses.size == 1 or q.ask?
93
+ # flatten results array if only one select clause
94
+ # to prevent unnecessarily nested array [[eyal],[renaud],...]
95
+ results.flatten! if q.select_clauses.size == 1 or q.ask?
96
96
 
97
- # remove array (return single value or nil) if asked to
98
- if options[:flatten]
99
- case results.size
100
- when 0
101
- results = nil
102
- when 1
103
- results = results.first
97
+ # remove array (return single value or nil) if asked to
98
+ if options[:flatten]
99
+ case results.size
100
+ when 0
101
+ results = nil
102
+ when 1
103
+ results = results.first
104
+ end
104
105
  end
105
106
  end
106
- end
107
107
 
108
- results
108
+ results
109
109
  end # End benchmark
110
110
  end # End query
111
- end
112
111
  end
112
+ end
@@ -0,0 +1,28 @@
1
+ module ActiveRDF
2
+
3
+ # Helper Module that contains same additional methods that
4
+ # are expected from classes that want to behave like
5
+ # RDFS::Resource.
6
+ #
7
+ # The module expects that the including class has an uri
8
+ # method or property.
9
+ module ResourceLike
10
+
11
+ # returns uri of resource, can be overridden in subclasses
12
+ def to_s
13
+ "<#{uri}>"
14
+ end
15
+
16
+ # overriding sort based on uri
17
+ def <=>(other)
18
+ uri <=> other.uri
19
+ end
20
+
21
+ # NTriple representation of element
22
+ def to_literal_s
23
+ "<#{uri}>"
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,317 @@
1
+ require 'active_rdf/federation/federation_manager'
2
+
3
+ # Represents a query on a datasource, abstract representation of SPARQL
4
+ # features. Query is passed to federation manager or adapter for execution on
5
+ # data source. In all clauses symbols represent variables:
6
+ # Query.new.select(:s).where(:s,:p,:o).
7
+ module ActiveRDF
8
+ class Query
9
+ attr_reader :select_clauses, :where_clauses, :filter_clauses, :sort_clauses, :limits, :offsets, :keywords
10
+
11
+ bool_accessor :distinct, :ask, :select, :count, :keyword, :all_types
12
+
13
+ # Creates a new query. You may pass a different class that is used for "resource"
14
+ # type objects instead of RDFS::Resource
15
+ def initialize(resource_type = RDFS::Resource)
16
+ @distinct = false
17
+ @select_clauses = []
18
+ @where_clauses = []
19
+ @filter_clauses = {}
20
+ @sort_clauses = []
21
+ @limits = nil
22
+ @offsets = nil
23
+ @keywords = {}
24
+ @reasoning = nil
25
+ @all_types = false
26
+ @nil_clause_idx = -1
27
+ set_resource_class(resource_type)
28
+ end
29
+
30
+ <<<<<<< HEAD:lib/active_rdf/queryengine/query.rb
31
+ # This returns the class that is be used for resources, by default this
32
+ # is RDFS::Resource
33
+ def resource_class
34
+ @resource_class ||= RDFS::Resource
35
+ end
36
+
37
+ # Sets the resource_class. Any class may be used, however it is required
38
+ # that it can be created using the uri of the resource as it's only
39
+ # parameter and that it has an 'uri' property
40
+ def set_resource_class(resource_class)
41
+ raise(ArgumentError, "resource_class must be a class") unless(resource_class.class == Class)
42
+
43
+ test = resource_class.new("http://uri")
44
+ raise(ArgumentError, "Must have an uri property") unless(test.respond_to?(:uri))
45
+ @resource_class = resource_class
46
+ end
47
+
48
+ =======
49
+ >>>>>>> 9e1004bb8cd871b9a465a676ffde1a3c16790611:lib/active_rdf/query/query.rb
50
+ def initialize_copy(orig)
51
+ # dup the instance variables so we're not messing with the original query's values
52
+ instance_variables.each do |iv|
53
+ orig_val = instance_variable_get(iv)
54
+ case orig_val
55
+ when Array,Hash
56
+ instance_variable_set(iv,orig_val.dup)
57
+ end
58
+ end
59
+ end
60
+
61
+ # Clears the select clauses
62
+ def clear_select
63
+ <<<<<<< HEAD:lib/active_rdf/queryengine/query.rb
64
+ ActiveRdfLogger::log_debug "Cleared select clause", self
65
+ =======
66
+ ActiveRdfLogger::log_debug(self) { "Cleared select clause" }
67
+ >>>>>>> 9e1004bb8cd871b9a465a676ffde1a3c16790611:lib/active_rdf/query/query.rb
68
+ @select_clauses = []
69
+ @distinct = false
70
+ end
71
+
72
+ # Adds variables to select clause
73
+ def select *s
74
+ raise(ActiveRdfError, "variable must be a Symbol") unless s.all?{|var| var.is_a?(Symbol)}
75
+ @select = true
76
+ # removing duplicate select clauses
77
+ @select_clauses.concat(s).uniq!
78
+ self
79
+ end
80
+
81
+ # Adds variables to ask clause (see SPARQL specification)
82
+ def ask
83
+ @ask = true
84
+ self
85
+ end
86
+
87
+ # Request reasoning be performed on query
88
+ def reasoning(bool)
89
+ @reasoning = truefalse(bool)
90
+ self
91
+ end
92
+
93
+ def reasoning=(bool)
94
+ self.reasoning(bool)
95
+ end
96
+
97
+ def reasoning?
98
+ @reasoning
99
+ end
100
+
101
+ # Set query to ignore language & datatypes for objects
102
+ def all_types(enabled = true)
103
+ @all_types = enabled
104
+ self
105
+ end
106
+
107
+ # Adds variables to select distinct clause
108
+ def distinct *s
109
+ @distinct = true
110
+ select(*s)
111
+ end
112
+ alias_method :select_distinct, :distinct
113
+
114
+ # Adds variables to count clause
115
+ def count *s
116
+ @count = true
117
+ select(*s)
118
+ end
119
+
120
+ # Adds sort predicates
121
+ #
122
+ def sort *s
123
+ s.each do |var|
124
+ <<<<<<< HEAD:lib/active_rdf/queryengine/query.rb
125
+
126
+ =======
127
+ raise(ActiveRdfError, "variable must be a Symbol") unless var.is_a? Symbol
128
+ >>>>>>> 9e1004bb8cd871b9a465a676ffde1a3c16790611:lib/active_rdf/query/query.rb
129
+ @sort_clauses << [var,:asc]
130
+ end
131
+ self
132
+ end
133
+
134
+ # adds reverse sorting predicates
135
+ def reverse_sort *s
136
+ s.each do |var|
137
+ raise(ActiveRdfError, "variable must be a Symbol") unless var.is_a? Symbol
138
+ @sort_clauses << [var,:desc]
139
+ end
140
+ self
141
+ end
142
+
143
+ # adds operator filter on one variable
144
+ # variable is a Ruby symbol that appears in select/where clause, operator is a
145
+ # SPARQL operator (e.g. '>','lang','datatype'), operand is a SPARQL value (e.g. 15)
146
+ def filter(variable, operator, operand)
147
+ raise(ActiveRdfError, "variable must be a Symbol") unless variable.is_a? Symbol
148
+ @filter_clauses[variable] = [operator.to_sym,operand]
149
+ self
150
+ end
151
+
152
+ # adds regular expression filter on one variable
153
+ # variable is Ruby symbol that appears in select/where clause, regex is Ruby
154
+ # regular expression
155
+ def regexp(variable, regexp)
156
+ raise(ActiveRdfError, "variable must be a symbol") unless variable.is_a? Symbol
157
+ regexp = regexp.source if(regexp.is_a?(Regexp))
158
+ <<<<<<< HEAD:lib/active_rdf/queryengine/query.rb
159
+
160
+ =======
161
+ >>>>>>> 9e1004bb8cd871b9a465a676ffde1a3c16790611:lib/active_rdf/query/query.rb
162
+ filter(variable, :regexp, regexp)
163
+ end
164
+ alias :regex :regexp
165
+
166
+ # filter variable on specified language tag, e.g. lang(:o, 'en', true)
167
+ # optionally matches exactly on language dialect, otherwise only
168
+ # language-specifier is considered
169
+ def lang(variable, tag, exact=true)
170
+ filter(variable,:lang,[tag.sub(/^@/,''),exact])
171
+ end
172
+
173
+ def datatype(variable, type)
174
+ filter(variable,:datatype,type)
175
+ end
176
+
177
+ # Adds limit clause (maximum number of results to return)
178
+ def limit(i)
179
+ @limits = i.to_i
180
+ self
181
+ end
182
+
183
+ # Add offset clause (ignore first n results)
184
+ def offset(i)
185
+ @offsets = i.to_i
186
+ self
187
+ end
188
+
189
+ # Adds where clauses (s,p,o) where each constituent is either variable (:s) or
190
+ # an RDFS::Resource (or equivalent class). Keyword queries are specified with the special :keyword
191
+ # symbol: Query.new.select(:s).where(:s, :keyword, 'eyal')
192
+ def where s,p,o,c=nil
193
+ case p
194
+ when :keyword
195
+ # treat keywords in where-clauses specially
196
+ keyword_where(s,o)
197
+ else
198
+ # give nil clauses a unique variable
199
+ s,p,o = [s,p,o].collect{|clause| clause.nil? ? "nil#{@nil_clause_idx += 1}".to_sym : clause}
200
+
201
+ # remove duplicate variable bindings, e.g.
202
+ # where(:s,type,:o).where(:s,type,:oo) we should remove the second clause,
203
+ # since it doesn't add anything to the query and confuses the query
204
+ # generator.
205
+ # if you construct this query manually, you shouldn't! if your select
206
+ # variable happens to be in one of the removed clauses: tough luck.
207
+ unless (s.respond_to?(:uri) or s.is_a?(Symbol)) and (s.class != RDFS::BNode)
208
+ raise(ActiveRdfError, "Cannot add a where clause with s #{s}: s must be a resource or a variable, is a #{s.class.name}")
209
+ end
210
+ unless (p.respond_to?(:uri) or p.is_a?(Symbol)) and (s.class != RDFS::BNode)
211
+ raise(ActiveRdfError, "Cannot add a where clause with p #{p}: p must be a resource or a variable, is a #{p.class.name}")
212
+ end
213
+ raise(ActiveRdfErrror, "Cannot add a where clause where o is a blank node") if(o.class == RDFS::BNode)
214
+
215
+ @where_clauses << [s,p,o,c]
216
+ end
217
+ self
218
+ end
219
+
220
+ # Adds keyword constraint to the query. You can use all Ferret query syntax in
221
+ # the constraint (e.g. keyword_where(:s,'eyal|benjamin')
222
+ def keyword_where s,o
223
+ @keyword = true
224
+ if @keywords.include?(s)
225
+ @keywords[s] = @keywords[s] + ' ' + o
226
+ else
227
+ @keywords[s] = o
228
+ end
229
+ self
230
+ end
231
+
232
+ # Executes query on data sources. Either returns result as array
233
+ # (flattened into single value unless specified otherwise)
234
+ # or executes a block (number of block variables should be
235
+ # same as number of select variables)
236
+ #
237
+ # usage:: results = query.execute
238
+ # usage:: query.execute do |s,p,o| ... end
239
+ def execute(options={:flatten => false}, &block)
240
+ options = {:flatten => true} if options == :flatten
241
+
242
+ prepared_query = prepare_query(options)
243
+
244
+ if block_given?
245
+ for result in FederationManager.execute(prepared_query, options.merge(:flatten => false))
246
+ yield result
247
+ end
248
+ else
249
+ FederationManager.execute(prepared_query, options)
250
+ end
251
+ end
252
+
253
+ # Returns query string depending on adapter (e.g. SPARQL, N3QL, etc.)
254
+ def to_s
255
+ if ConnectionPool.read_adapters.empty?
256
+ inspect
257
+ else
258
+ ConnectionPool.read_adapters.first.translate(prepare_query)
259
+ end
260
+ end
261
+
262
+ # Returns SPARQL serialisation of query
263
+ def to_sp
264
+ <<<<<<< HEAD:lib/active_rdf/queryengine/query.rb
265
+ require 'queryengine/query2sparql' unless(defined?(Query2SPARQL))
266
+ =======
267
+ require 'active_rdf/queryengine/query2sparql' unless(defined?(Query2SPARQL))
268
+ >>>>>>> 9e1004bb8cd871b9a465a676ffde1a3c16790611:lib/active_rdf/query/query.rb
269
+ Query2SPARQL.translate(self)
270
+ end
271
+
272
+ private
273
+ def prepare_query(options = {})
274
+ # leave the original query intact
275
+ dup = self.dup
276
+ dup.expand_obj_values
277
+ # dup.reasoned_query if dup.reasoning?
278
+
279
+ # extract options
280
+ if options.include?(:order)
281
+ dup.sort(:sort_value)
282
+ dup.where(:s, options.delete(:order), :sort_value)
283
+ end
284
+
285
+ if options.include?(:reverse_order)
286
+ dup.reverse_sort(:sort_value)
287
+ dup.where(:s, options.delete(:reverse_order), :sort_value)
288
+ end
289
+
290
+ dup.limit(options.delete(:limit)) if options.include?(:limit)
291
+ dup.offset(options.delete(:offset)) if options.include?(:offset)
292
+
293
+ dup
294
+ end
295
+
296
+ protected
297
+ def expand_obj_values
298
+ new_where_clauses = []
299
+ @where_clauses.each do |s,p,o,c|
300
+ if o.respond_to?(:to_ary)
301
+ o.to_ary.each{|elem| new_where_clauses << [s,p,elem,c]}
302
+ else
303
+ new_where_clauses << [s,p,o,c]
304
+ end
305
+ end
306
+ @where_clauses = new_where_clauses
307
+ end
308
+
309
+ # def reasoned_query
310
+ # new_where_clauses = []
311
+ # @where_clauses.each do |s,p,o,c|
312
+ # # other reasoning should be added here
313
+ # end
314
+ # @where_clauses += new_where_clauses
315
+ # end
316
+ end
317
+ end
@@ -11,9 +11,9 @@ module ActiveRDF
11
11
 
12
12
  bool_accessor :distinct, :ask, :select, :count, :keyword, :all_types
13
13
 
14
- # Creates a new query. You may pass a different class that is used for "resource"
15
- # type objects instead of RDFS::Resource
16
- def initialize(resource_type = RDFS::Resource)
14
+ # Creates a new query. You may pass a different class that is used for "resource"
15
+ # type objects instead of RDFS::Resource
16
+ def initialize(resource_type = RDFS::Resource)
17
17
  @distinct = false
18
18
  @select_clauses = []
19
19
  @where_clauses = []
@@ -25,41 +25,40 @@ module ActiveRDF
25
25
  @reasoning = nil
26
26
  @all_types = false
27
27
  @nil_clause_idx = -1
28
- set_resource_class(resource_type)
28
+ set_resource_class(resource_type)
29
29
  end
30
30
 
31
- # This returns the class that is be used for resources, by default this
32
- # is RDFS::Resource
33
- def resource_class
34
- @resource_class ||= RDFS::Resource
35
- end
31
+ # This returns the class that is be used for resources, by default this
32
+ # is RDFS::Resource
33
+ def resource_class
34
+ @resource_class ||= RDFS::Resource
35
+ end
36
36
 
37
- # Sets the resource_class. Any class may be used, however it is required
38
- # that it can be created using the uri of the resource as it's only
39
- # parameter and that it has an 'uri' property
40
- def set_resource_class(resource_class)
41
- raise(ArgumentError, "resource_class must be a class") unless(resource_class.class == Class)
37
+ # Sets the resource_class. Any class may be used, however it is required
38
+ # that it can be created using the uri of the resource as it's only
39
+ # parameter and that it has an 'uri' property
40
+ def set_resource_class(resource_class)
41
+ raise(ArgumentError, "resource_class must be a class") unless(resource_class.class == Class)
42
42
 
43
- test = resource_class.new("http://uri")
44
- raise(ArgumentError, "Must have an uri property") unless(test.respond_to?(:uri))
45
- @resource_class = resource_class
46
- end
43
+ test = resource_class.new("http://uri")
44
+ raise(ArgumentError, "Must have an uri property") unless(test.respond_to?(:uri))
45
+ @resource_class = resource_class
46
+ end
47
47
 
48
48
  def initialize_copy(orig)
49
49
  # dup the instance variables so we're not messing with the original query's values
50
50
  instance_variables.each do |iv|
51
51
  orig_val = instance_variable_get(iv)
52
52
  case orig_val
53
- when Array,Hash
54
- instance_variable_set(iv,orig_val.dup)
53
+ when Array,Hash
54
+ instance_variable_set(iv,orig_val.dup)
55
55
  end
56
56
  end
57
57
  end
58
58
 
59
-
60
59
  # Clears the select clauses
61
60
  def clear_select
62
- ActiveRdfLogger::log_debug "Cleared select clause", self
61
+ ActiveRdfLogger::log_debug "Cleared select clause", self
63
62
  @select_clauses = []
64
63
  @distinct = false
65
64
  end
@@ -84,9 +83,11 @@ module ActiveRDF
84
83
  @reasoning = truefalse(bool)
85
84
  self
86
85
  end
86
+
87
87
  def reasoning=(bool)
88
88
  self.reasoning(bool)
89
89
  end
90
+
90
91
  def reasoning?
91
92
  @reasoning
92
93
  end
@@ -114,7 +115,7 @@ module ActiveRDF
114
115
  #
115
116
  def sort *s
116
117
  s.each do |var|
117
-
118
+
118
119
  @sort_clauses << [var,:asc]
119
120
  end
120
121
  self
@@ -142,10 +143,10 @@ module ActiveRDF
142
143
  # variable is Ruby symbol that appears in select/where clause, regex is Ruby
143
144
  # regular expression
144
145
  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))
146
+ raise(ActiveRdfError, "variable must be a symbol") unless variable.is_a? Symbol
147
+ regexp = regexp.source if(regexp.is_a?(Regexp))
147
148
 
148
- filter(variable, :regexp, regexp)
149
+ filter(variable, :regexp, regexp)
149
150
  end
150
151
  alias :regex :regexp
151
152
 
@@ -173,7 +174,7 @@ module ActiveRDF
173
174
  end
174
175
 
175
176
  # Adds where clauses (s,p,o) where each constituent is either variable (:s) or
176
- # an RDFS::Resource (or equivalent class). Keyword queries are specified with the special :keyword
177
+ # an RDFS::Resource (or equivalent class). Keyword queries are specified with the special :keyword
177
178
  # symbol: Query.new.select(:s).where(:s, :keyword, 'eyal')
178
179
  def where s,p,o,c=nil
179
180
  case p
@@ -190,13 +191,13 @@ module ActiveRDF
190
191
  # generator.
191
192
  # if you construct this query manually, you shouldn't! if your select
192
193
  # 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}")
194
+ unless (s.respond_to?(:uri) or s.is_a?(Symbol)) and (s.class != RDFS::BNode)
195
+ raise(ActiveRdfError, "Cannot add a where clause with s #{s}: s must be a resource or a variable, is a #{s.class.name}")
195
196
  end
196
- unless (p.respond_to?(:uri) or p.is_a?(Symbol)) and (s.class != RDFS::BNode)
197
- raise(ActiveRdfError, "Cannot add a where clause with p #{p}: p must be a resource or a variable, is a #{p.class.name}")
197
+ unless (p.respond_to?(:uri) or p.is_a?(Symbol)) and (s.class != RDFS::BNode)
198
+ raise(ActiveRdfError, "Cannot add a where clause with p #{p}: p must be a resource or a variable, is a #{p.class.name}")
198
199
  end
199
- raise(ActiveRdfErrror, "Cannot add a where clause where o is a blank node") if(o.class == RDFS::BNode)
200
+ raise(ActiveRdfErrror, "Cannot add a where clause where o is a blank node") if(o.class == RDFS::BNode)
200
201
 
201
202
  @where_clauses << [s,p,o,c]
202
203
  end
@@ -247,7 +248,7 @@ module ActiveRDF
247
248
 
248
249
  # Returns SPARQL serialisation of query
249
250
  def to_sp
250
- require 'queryengine/query2sparql' unless(defined?(Query2SPARQL))
251
+ require 'queryengine/query2sparql' unless(defined?(Query2SPARQL))
251
252
  Query2SPARQL.translate(self)
252
253
  end
253
254
 
@@ -288,12 +289,12 @@ module ActiveRDF
288
289
  @where_clauses = new_where_clauses
289
290
  end
290
291
 
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
292
+ # def reasoned_query
293
+ # new_where_clauses = []
294
+ # @where_clauses.each do |s,p,o,c|
295
+ # # other reasoning should be added here
296
+ # end
297
+ # @where_clauses += new_where_clauses
298
+ # end
298
299
  end
299
300
  end
@@ -0,0 +1,116 @@
1
+ require 'active_rdf/federation/connection_pool'
2
+
3
+ include ActiveRdfBenchmark
4
+
5
+ # Manages the federation of datasources: distributes queries to right
6
+ # datasources and merges their results
7
+
8
+ module ActiveRDF
9
+ class FederationManager
10
+ <<<<<<< HEAD:lib/active_rdf/federation/federation_manager.rb
11
+ def FederationManager.contexts
12
+ =======
13
+ def FederationManager.contexts
14
+ >>>>>>> 9e1004bb8cd871b9a465a676ffde1a3c16790611:lib/active_rdf/storage/federated_store.rb
15
+ ConnectionPool.adapters.collect{|adapter| adapter.contexts if adapter.respond_to?(:contexts)}.flatten.compact
16
+ end
17
+
18
+ # add triple s,p,o (context is optional) to the currently selected write-adapter
19
+ def FederationManager.add(s,p,o,c=nil)
20
+ benchmark("SPARQL/RDF", Logger::DEBUG) do |bench_message|
21
+ bench_message << "ADD #{s} - #{p} - #{o} : #{c}" if(bench_message)
22
+ # TODO: allow addition of full graphs
23
+ raise ActiveRdfError, "cannot write without a write-adapter" unless ConnectionPool.write_adapter
24
+ ConnectionPool.write_adapter.add(s,p,o,c)
25
+ end
26
+ end
27
+
28
+ # delete triple s,p,o (context is optional) to the currently selected write-adapter
29
+ def FederationManager.delete(s,p=nil,o=nil,c=nil)
30
+ benchmark("SPARQL/RDF", Logger::DEBUG) do |bench_message|
31
+ bench_message << "DELETE #{s} - #{p} - #{o} : #{c}" if(bench_message)
32
+ raise ActiveRdfError, "cannot write without a write-adapter" unless ConnectionPool.write_adapter
33
+ # transform wildcard symbols to nil (for the adaptors)
34
+ s = nil if s.is_a? Symbol
35
+ p = nil if p.is_a? Symbol
36
+ o = nil if o.is_a? Symbol
37
+ ConnectionPool.write_adapter.delete(s,p,o,c)
38
+ end
39
+ end
40
+
41
+ # delete every triples about a specified resource
42
+ def FederationManager.delete_all(resource)
43
+ delete(resource, nil, nil)
44
+ end
45
+
46
+ # Clear the store (or the given context)
47
+ def FederationManager.clear(context=nil)
48
+ # FIXME: Make sure that all adapters support clearing
49
+ raise(RuntimeError, "Adapter #{ConnectionPool.write_adapter.class} doesn't support clear") unless(ConnectionPool.write_adapter.respond_to?(:clear))
50
+ ConnectionPool.write_adapter.clear(context)
51
+ end
52
+
53
+ # executes read-only queries
54
+ # by distributing query over complete read-pool
55
+ # and aggregating the results
56
+ def FederationManager.execute(q, options={:flatten => false})
57
+ if ConnectionPool.read_adapters.empty?
58
+ raise ActiveRdfError, "cannot execute query without data sources"
59
+ end
60
+
61
+ benchmark("SPARQL/RDF", Logger::DEBUG) do |bench_message|
62
+ # Only build the benchmark message if we need it
63
+ bench_message << ((q.class == String) ? q : q.to_sp) if(bench_message)
64
+ # ask each adapter for query results
65
+ # and yield them consequtively
66
+ if block_given?
67
+ ConnectionPool.read_adapters.each do |source|
68
+ source.execute(q) do |*clauses|
69
+ yield(*clauses)
70
+ end
71
+ end
72
+ else
73
+ # build Array of results from all sources
74
+ # TODO: write test for sebastian's select problem
75
+ # (without distinct, should get duplicates, they
76
+ # were filtered out when doing results.union)
77
+ results = []
78
+ ConnectionPool.read_adapters.each do |source|
79
+ source_results = source.execute(q)
80
+ source_results.each do |clauses|
81
+ results << clauses
82
+ end
83
+ end
84
+
85
+ # count
86
+ return results.flatten.inject{|mem,c| mem + c} if q.count?
87
+
88
+ # filter the empty results
89
+ results.reject {|ary| ary.empty? }
90
+
91
+ # remove duplicate results from multiple
92
+ # adapters if asked for distinct query
93
+ # (adapters return only distinct results,
94
+ # but they cannot check duplicates against each other)
95
+ results.uniq! if q.distinct?
96
+
97
+ # flatten results array if only one select clause
98
+ # to prevent unnecessarily nested array [[eyal],[renaud],...]
99
+ results.flatten! if q.select_clauses.size == 1 or q.ask?
100
+
101
+ # remove array (return single value or nil) if asked to
102
+ if options[:flatten]
103
+ case results.size
104
+ when 0
105
+ results = nil
106
+ when 1
107
+ results = results.first
108
+ end
109
+ end
110
+ end
111
+
112
+ results
113
+ end # End benchmark
114
+ end # End query
115
+ end
116
+ end
@@ -27,6 +27,7 @@ class ActiveRdfLogger
27
27
 
28
28
  # Assign a new logger
29
29
  def logger=(logger)
30
+ raise(ArgumentError, "Empty Logger") if(logger == nil)
30
31
  @logger = logger
31
32
  @native_logger = false
32
33
  end
@@ -55,8 +56,8 @@ class ActiveRdfLogger
55
56
  end
56
57
 
57
58
  def get_active_rdf_logger
58
- if(defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER)
59
- RAILS_DEFAULT_LOGGER
59
+ if(defined?(Rails) && !Rails.logger.nil?)
60
+ Rails.logger
60
61
  else
61
62
  @native_logger = true
62
63
 
metadata CHANGED
@@ -1,7 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerdf_net7
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 7
8
+ - 2
9
+ version: 1.7.2
5
10
  platform: ruby
6
11
  authors:
7
12
  - Eyal Oren
@@ -10,29 +15,37 @@ autorequire: active_rdf
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2010-02-15 00:00:00 +01:00
18
+ date: 2010-07-19 00:00:00 +02:00
14
19
  default_executable:
15
20
  dependencies:
16
21
  - !ruby/object:Gem::Dependency
17
22
  name: gem_plugin
18
- type: :runtime
19
- version_requirement:
20
- version_requirements: !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
21
25
  requirements:
22
26
  - - ">="
23
27
  - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ - 2
31
+ - 1
24
32
  version: 0.2.1
25
- version:
33
+ type: :runtime
34
+ version_requirements: *id001
26
35
  - !ruby/object:Gem::Dependency
27
36
  name: grit
28
- type: :runtime
29
- version_requirement:
30
- version_requirements: !ruby/object:Gem::Requirement
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
31
39
  requirements:
32
40
  - - ">="
33
41
  - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 1
45
+ - 1
34
46
  version: 1.1.1
35
- version:
47
+ type: :runtime
48
+ version_requirements: *id002
36
49
  description: Offers object-oriented access to RDF (with adapters to several datastores). Version of the Talia project. THIS IS NOT THE OFFICIAL VERSION.
37
50
  email: hahn@netseven.it
38
51
  executables: []
@@ -201,13 +214,16 @@ files:
201
214
  - lib/active_rdf/objectmanager/property.rb
202
215
  - lib/active_rdf/objectmanager/property_list.rb
203
216
  - lib/active_rdf/objectmanager/property_lookup.rb
217
+ - lib/active_rdf/objectmanager/reslike
204
218
  - lib/active_rdf/objectmanager/resource.rb
205
219
  - lib/active_rdf/objectmanager/resource_like.rb
206
220
  - lib/active_rdf/objectmanager/resource_query.rb
221
+ - lib/active_rdf/query/query.rb.orig
207
222
  - lib/active_rdf/queryengine/ntriples_parser.rb
208
223
  - lib/active_rdf/queryengine/query.rb
209
224
  - lib/active_rdf/queryengine/query2jars2.rb
210
225
  - lib/active_rdf/queryengine/query2sparql.rb
226
+ - lib/active_rdf/storage/federated_store.rb.orig
211
227
  - lib/active_rdf_helpers.rb
212
228
  - lib/active_rdf_log.rb
213
229
  - CHANGELOG
@@ -226,18 +242,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
226
242
  requirements:
227
243
  - - ">="
228
244
  - !ruby/object:Gem::Version
245
+ segments:
246
+ - 0
229
247
  version: "0"
230
- version:
231
248
  required_rubygems_version: !ruby/object:Gem::Requirement
232
249
  requirements:
233
250
  - - ">="
234
251
  - !ruby/object:Gem::Version
252
+ segments:
253
+ - 0
235
254
  version: "0"
236
- version:
237
255
  requirements: []
238
256
 
239
257
  rubyforge_project:
240
- rubygems_version: 1.3.5
258
+ rubygems_version: 1.3.6
241
259
  signing_key:
242
260
  specification_version: 3
243
261
  summary: Offers object-oriented access to RDF (with adapters to several datastores). Version of the Talia project.