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.
Files changed (85) hide show
  1. data/CHANGELOG +63 -0
  2. data/activerdf-jena/lib/activerdf_jena/jena.rb +4 -4
  3. data/activerdf-jena/lib/activerdf_jena/jena_adapter.rb +55 -55
  4. data/activerdf-jena/lib/activerdf_jena/lucene.rb +1 -1
  5. data/activerdf-jena/lib/activerdf_jena/ng4j.rb +7 -7
  6. data/activerdf-jena/lib/activerdf_jena/ng4j_adapter.rb +47 -47
  7. data/activerdf-jena/lib/activerdf_jena/pellet.rb +1 -1
  8. data/activerdf-jena/test/test_jena_adapter.rb +121 -120
  9. data/activerdf-jena/test/test_ng4j_adapter.rb +111 -110
  10. data/activerdf-rdflite/lib/activerdf_rdflite/fetching.rb +23 -19
  11. data/activerdf-rdflite/lib/activerdf_rdflite/rdflite.rb +153 -277
  12. data/activerdf-rdflite/lib/activerdf_rdflite/suggesting.rb +2 -2
  13. data/activerdf-rdflite/test/test_fetching.rb +7 -22
  14. data/activerdf-rdflite/test/test_rdflite.rb +44 -257
  15. data/activerdf-redland/lib/activerdf_redland/redland.rb +246 -282
  16. data/activerdf-redland/test/test_redland_adapter.rb +62 -224
  17. data/activerdf-sesame/ext/wrapper-sesame2.jar +0 -0
  18. data/activerdf-sesame/java/build.number +2 -2
  19. data/activerdf-sesame/java/build.xml +0 -0
  20. data/activerdf-sesame/java/lib/junit-3.8.2.jar +0 -0
  21. data/activerdf-sesame/java/settings.xml +0 -0
  22. data/activerdf-sesame/java/src/org/activerdf/wrapper/sesame2/WrapperForSesame2.java +0 -0
  23. data/activerdf-sesame/java/temp/build/org/activerdf/wrapper/sesame2/WrapperForSesame2.class +0 -0
  24. data/activerdf-sesame/java/temp/manifest/MANIFEST.MF +2 -2
  25. data/activerdf-sesame/java/test-src/org/activerdf/wrapper/sesame2/TestWrapperForSesame2.java +0 -0
  26. data/activerdf-sesame/lib/activerdf_sesame/sesame.rb +360 -364
  27. data/activerdf-sesame/test/test_sesame_adapter.rb +85 -83
  28. data/activerdf-sparql/lib/activerdf_sparql/sparql.rb +147 -148
  29. data/activerdf-sparql/lib/activerdf_sparql/sparql_result_parser.rb +5 -5
  30. data/activerdf-sparql/test/test_sparql_adapter.rb +2 -0
  31. data/activerdf-yars/lib/activerdf_yars/jars2.rb +85 -83
  32. data/lib/active_rdf/federation/active_rdf_adapter.rb +26 -39
  33. data/lib/active_rdf/federation/connection_pool.rb +119 -110
  34. data/lib/active_rdf/federation/federation_manager.rb +51 -51
  35. data/lib/active_rdf/objectmanager/bnode.rb +8 -2
  36. data/lib/active_rdf/objectmanager/literal.rb +81 -50
  37. data/lib/active_rdf/objectmanager/namespace.rb +117 -84
  38. data/lib/active_rdf/objectmanager/object_manager.rb +101 -96
  39. data/lib/active_rdf/objectmanager/ordered_set.rb +1 -1
  40. data/lib/active_rdf/objectmanager/property.rb +345 -0
  41. data/lib/active_rdf/objectmanager/property_list.rb +4 -4
  42. data/lib/active_rdf/objectmanager/property_lookup.rb +57 -0
  43. data/lib/active_rdf/objectmanager/resource.rb +293 -501
  44. data/lib/active_rdf/objectmanager/resource_like.rb +2 -2
  45. data/lib/active_rdf/objectmanager/resource_query.rb +85 -0
  46. data/lib/active_rdf/queryengine/ntriples_parser.rb +75 -68
  47. data/lib/active_rdf/queryengine/query.rb +237 -183
  48. data/lib/active_rdf/queryengine/query2jars2.rb +17 -15
  49. data/lib/active_rdf/queryengine/query2sparql.rb +107 -101
  50. data/lib/active_rdf.rb +28 -17
  51. data/lib/active_rdf_helpers.rb +37 -5
  52. data/lib/active_rdf_log.rb +11 -11
  53. data/test/adapters/test_activerdf_adapter.rb +138 -0
  54. data/test/{test_adapters.rb → adapters/test_adapters.rb} +6 -24
  55. data/test/adapters/test_bnode_capable_adapter.rb +31 -0
  56. data/test/adapters/test_context_aware_adapter.rb +31 -0
  57. data/test/adapters/test_network_aware_adapter.rb +29 -0
  58. data/test/adapters/test_persistent_adapter.rb +21 -0
  59. data/test/adapters/test_read_only_adapter.rb +15 -0
  60. data/test/adapters/test_reasoning_adapter.rb +11 -0
  61. data/test/adapters/test_writable_adapter.rb +163 -0
  62. data/test/common.rb +78 -96
  63. data/test/federation/test_connection_pool.rb +25 -44
  64. data/test/federation/test_federation_manager.rb +45 -45
  65. data/test/objectmanager/test_literal.rb +47 -26
  66. data/test/objectmanager/test_namespace.rb +3 -1
  67. data/test/objectmanager/test_object_manager.rb +35 -45
  68. data/test/objectmanager/test_ordered_set.rb +1 -1
  69. data/test/objectmanager/test_property.rb +261 -0
  70. data/test/objectmanager/test_resource_reading.rb +196 -104
  71. data/test/objectmanager/test_resource_reasoning.rb +26 -0
  72. data/test/objectmanager/test_resource_writing.rb +34 -25
  73. data/test/queryengine/my_external_resource.rb +5 -1
  74. data/test/queryengine/test_external_resource_class.rb +1 -8
  75. data/test/queryengine/test_ntriples_parser.rb +5 -3
  76. data/test/queryengine/test_query.rb +3 -3
  77. data/test/queryengine/test_query2jars2.rb +2 -2
  78. data/test/queryengine/test_query2sparql.rb +2 -2
  79. data/test/queryengine/test_query_engine.rb +46 -28
  80. metadata +16 -8
  81. data/activerdf-rdflite/test/test_bnode_data.nt +0 -5
  82. data/activerdf-rdflite/test/test_data.nt +0 -32
  83. data/activerdf-rdflite/test/test_escaped_data.nt +0 -2
  84. data/activerdf-redland/test/test_person_data.nt +0 -42
  85. data/test/objectmanager/test_talia_syntax.rb +0 -68
@@ -8,11 +8,12 @@ require 'rdf/redland'
8
8
 
9
9
  # Adapter to Redland database
10
10
  # uses SPARQL for querying
11
- class RedlandAdapter < ActiveRdfAdapter
11
+ module ActiveRDF
12
+ class RedlandAdapter < ActiveRdfAdapter
12
13
  ActiveRdfLogger::log_info "Loading Redland adapter", self
13
- ConnectionPool.register_adapter(:redland,self)
14
+ ConnectionPool.register_adapter(:redland,self)
14
15
 
15
- # instantiate connection to Redland database
16
+ # instantiate connection to Redland database
16
17
  # * location: Data location (:memory, :mysql, :postgresql)
17
18
  # * database: Database name
18
19
  # * new: Create new database
@@ -21,342 +22,305 @@ class RedlandAdapter < ActiveRdfAdapter
21
22
  # * port: Database server port
22
23
  # * reconnect: Set automatic reconnect to database server
23
24
  # * user: Username
24
- def initialize(params = {})
25
- super()
26
-
27
- if params[:location] and params[:location] == :postgresql
28
- initialize_postgresql(params)
29
- return
30
- end
31
-
32
- if params[:location] and params[:location] != :memory
33
- # setup file defaults for redland database
34
- type = 'bdb'
35
- want_new = false # create new or use existing store
36
- write = true
37
- contexts = true
38
-
39
- if params[:want_new] == true
40
- want_new = true
41
- end
42
- if params[:write] == false
43
- write = false
44
- end
45
- if params[:contexts] == false
46
- contexts = false
47
- end
25
+ def initialize(params = {})
26
+ super
27
+ location = params[:location]
28
+ name = params[:name] || ''
29
+ options = {}
30
+ options[:write],options[:new],options[:contexts] = [@writes,@new,@contexts].collect{|bool| bool ? 'yes' : 'no'}
31
+
32
+ # supported storage modules: mysql, postgresql, sqlite, hashes(as 'memory' or 'bdb')
33
+ # unsupported storage modules: uri, file, memory, tstore, trees
34
+ # see http://librdf.org/docs/api/redland-storage-modules.html
35
+ case location
36
+ when 'postgresql','mysql','sqlite'
37
+ store_type = location
38
+ if location == 'postgresql' or location == 'mysql'
39
+ [:host, :port, :database, :user, :password].each{|k| options[k] = params[k] if params[k]}
40
+ options[:host] ||= 'localhost'
41
+ end
42
+ when 'memory',nil
43
+ # use storage module hashes with hash-type 'memory' instead of non-indexing storage module memory
44
+ store_type = 'hashes'
45
+ options[:hash_type] = 'memory';
46
+ options.delete(:new) # not used with this hash-type
47
+ else
48
+ # use storage module hashes with hash-type 'bdb' instead of non-indexing storage module file
49
+ store_type = 'hashes'
50
+ options[:hash_type] = 'bdb'
48
51
 
49
- if params[:location].include?('/')
50
- path, file = File.split(params[:location])
51
- else
52
- path = '.'
53
- file = params[:location]
52
+ if location.include?('/')
53
+ options[:dir], name = File.split(location)
54
+ else
55
+ options[:dir] = '.'
56
+ name = location
57
+ end
54
58
  end
55
- else
56
- # fall back to in-memory redland
57
- type = 'memory'; path = ''; file = '.'; want_new = false; write = true; contexts = true
58
- end
59
59
 
60
- ActiveRdfLogger::log_info(self) { "Initializing with type: #{type} file: #{file} path: #{path}" }
60
+ hash_type = options.delete(:hash_type)
61
+ options = options.collect{|k,v| "#{k}='#{v}'"}.join(',')
62
+ options << "hash-type='#{hash_type}'" if hash_type # convert option key from hash_type to hash-type. :hash-type is an invalid symbol
63
+ @model = Redland::Model.new Redland::TripleStore.new(store_type, name, options)
64
+ @options = options
65
+ ActiveRDFLogger::log_inf(self) { "RedlandAdapter: initialized adapter with type=\'#{store_type}\', name=\'#{name}\' options: #{options} => #{@model.inspect}" }
61
66
 
62
- begin
63
- @store = Redland::HashStore.new(type, file, path, want_new, write, contexts)
64
- @model = Redland::Model.new @store
65
- @reads = true
66
- @writes = true
67
- ActiveRdfLogger.log_info(self) { "Initialised Redland adapter to #{@model.inspect}" }
68
-
69
- rescue Redland::RedlandError => e
70
- raise ActiveRdfError, "Could not initialise Redland database: #{e.message}"
67
+ rescue Redland::RedlandError => e
68
+ raise ActiveRdfError, "RedlandAdapter: could not initialise Redland database: #{e.message}\nstore_type=\'#{store_type}\', name=\'#{name}\' options: #{options}"
71
69
  end
72
- end
73
70
 
74
- # instantiate connection to Redland database in Postgres or MySQL
75
- # * database: Database name
76
- # * new: Create new database
77
- # * host: Database server address
78
- # * password: Password
79
- # * port: Database server port
80
- # * reconnect: Set automatic reconnect to database server
81
- # * user: Username
82
- def initialize_postgresql(params = {})
83
- # author: Richard Dale
84
- type = 'postgresql'
85
- name = params[:name]
86
-
87
- options = []
88
- options << "new='#{params[:new]}'" if params[:new]
89
- options << "bulk='#{params[:bulk]}'" if params[:bulk]
90
- options << "merge='#{params[:merge]}'" if params[:merge]
91
- options << "host='#{params[:host]}'" if params[:host]
92
- options << "database='#{params[:database]}'" if params[:database]
93
- options << "user='#{params[:user]}'" if params[:user]
94
- options << "password='#{params[:password]}'" if params[:password]
95
- options << "port='#{params[:port]}'" if params[:port]
96
-
97
-
98
- ActiveRdfLogger::log_info "Initializing with type: #{type} name: #{name} options: #{options.join(',')}", self
99
-
100
- begin
101
- @store = Redland::TripleStore.new(type, name, options.join(','))
102
- @model = Redland::Model.new @store
103
- @reads = true
104
- @writes = true
105
- rescue Redland::RedlandError => e
106
- raise ActiveRdfError, "Could not initialise Redland database: #{e.message}"
107
- end
108
- end
109
-
110
- # load a file from the given location with the given syntax into the model.
111
- # use Redland syntax strings, e.g. "ntriples" or "rdfxml", defaults to "ntriples"
71
+ # load a file from the given location with the given syntax into the model.
72
+ # use Redland syntax strings, e.g. "ntriples" or "rdfxml", defaults to "ntriples"
112
73
  # * location: location of file to load.
113
74
  # * syntax: syntax of file
114
- def load(location, syntax="ntriples")
115
- parser = Redland::Parser.new(syntax, "", nil)
116
- if location =~ /^http/
117
- raise ActiveRdfError, "Redland load error for #{location}" unless (parser.parse_into_model(@model, location) == 0)
118
- else
119
- raise ActiveRdfError, "Redland load error for #{location}" unless (parser.parse_into_model(@model, "file:#{location}") == 0)
75
+ def load(location, syntax="ntriples")
76
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
77
+ parser = Redland::Parser.new(syntax, "", nil)
78
+ unless location =~ /^http/
79
+ location = "file:#{location}"
80
+ end
81
+
82
+ context = @contexts ? Redland::Uri.new(location) : nil
83
+ parser.parse_into_model(@model, location, nil, context)
84
+
85
+ save if ConnectionPool.auto_flush?
86
+ rescue Redland::RedlandError => e
87
+ $activerdflog.warn "RedlandAdapter: loading #{location} failed in Redland library: #{e}"
88
+ return false
120
89
  end
121
- end
122
90
 
123
- # yields query results (as many as requested in select clauses) executed on data source
124
- def query(query)
125
- qs = Query2SPARQL.translate(query)
91
+ # yields query results (as many as requested in select clauses) executed on data source
92
+ def execute(query, &block)
93
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
94
+ qs = Query2SPARQL.translate(query)
126
95
  ActiveRdfLogger::log_debug(self) { "Executing SPARQL query #{qs}" }
127
96
 
128
- clauses = query.select_clauses.size
129
- redland_query = Redland::Query.new(qs, 'sparql')
130
- query_results = @model.query_execute(redland_query)
97
+ redland_query = Redland::Query.new(qs, 'sparql')
98
+ query_results = @model.query_execute(redland_query)
131
99
 
132
- # return Redland's answer without parsing if ASK query
133
- return [[query_results.get_boolean?]] if query.ask?
100
+ # return Redland's answer without parsing if ASK query
101
+ return [[query_results.get_boolean?]] if query.ask?
134
102
 
135
103
  ActiveRdfLogger::log_debug(self) { "Found #{query_results.size} query results" }
136
104
 
137
- # verify if the query has failed
138
- if query_results.nil?
105
+ # verify if the query has failed
106
+ if query_results.nil?
139
107
  ActiveRdfLogger::log_debug "Query has failed with nil result", self
140
- return false
141
- end
108
+ return false
109
+ end
142
110
 
143
- if not query_results.is_bindings?
111
+ if not query_results.is_bindings?
144
112
  ActiveRdfLogger::log_debug "Query has failed without bindings", self
145
- return false
146
- end
147
-
148
- # convert the result to array
149
- #TODO: if block is given we should not parse all results into array first
150
- results = query_result_to_array(query_results, false, query.resource_class)
113
+ return false
114
+ end
151
115
 
152
- if block_given?
153
- results.each do |clauses|
154
- yield(*clauses)
116
+ if query.count?
117
+ while not query_results.finished?
118
+ query_results.next
119
+ end
120
+ [[query_results.count]]
121
+ else
122
+ # convert the results to array
123
+ query_result_to_array(query_results, &block)
155
124
  end
156
- else
157
- results
158
125
  end
159
- end
160
126
 
161
- # executes query and returns results as SPARQL JSON or XML results
162
- # requires svn version of redland-ruby bindings
163
- # * query: ActiveRDF Query object
164
- # * result_format: :json or :xml
165
- def get_query_results(query, result_format=nil)
127
+ # executes query and returns results as SPARQL JSON or XML results
128
+ # requires svn version of redland-ruby bindings
129
+ # * query: ActiveRDF Query object
130
+ # * result_format: :json or :xml
131
+ def get_query_results(query, result_format=nil)
132
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
166
133
  get_sparql_query_results(Query2SPARQL.translate(query), result_format, query.resource_class)
167
- end
134
+ end
168
135
 
169
- # executes sparql query and returns results as SPARQL JSON or XML results
170
- # * query: sparql query string
171
- # * result_format: :json or :xml
136
+ # executes sparql query and returns results as SPARQL JSON or XML results
137
+ # * query: sparql query string
138
+ # * result_format: :json or :xml
172
139
  # * result_type: Is the type that is used for "resource" results
173
140
  def get_sparql_query_results(qs, result_type, result_format=nil)
174
- # author: Eric Hanson
175
-
176
- # set uri for result formatting
177
- result_uri =
178
- case result_format
179
- when :json
180
- Redland::Uri.new('http://www.w3.org/2001/sw/DataAccess/json-sparql/')
181
- when :xml
182
- Redland::Uri.new('http://www.w3.org/TR/2004/WD-rdf-sparql-XMLres-20041221/')
183
- end
141
+ # author: Eric Hanson
142
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
143
+
144
+ # set uri for result formatting
145
+ result_uri =
146
+ case result_format
147
+ when :json
148
+ Redland::Uri.new('http://www.w3.org/2001/sw/DataAccess/json-sparql/')
149
+ when :xml
150
+ Redland::Uri.new('http://www.w3.org/TR/2004/WD-rdf-sparql-XMLres-20041221/')
151
+ end
184
152
 
185
- # query redland
186
- redland_query = Redland::Query.new(qs, 'sparql')
187
- query_results = @model.query_execute(redland_query)
153
+ # query redland
154
+ redland_query = Redland::Query.new(qs, 'sparql')
155
+ query_results = @model.query_execute(redland_query)
188
156
 
189
157
  if (result_format != :array)
190
158
  # get string representation in requested result_format (json or xml)
191
- query_results.to_string()
192
- else
193
- # get array result
194
- query_result_to_array(query_results, true, result_type)
159
+ query_results.to_string(result_uri)
195
160
  end
196
161
  end
197
162
 
198
- # add triple to datamodel
199
- # * s: subject
200
- # * p: predicate
201
- # * o: object
202
- def add(s, p, o, c=nil)
203
- result = false
204
- ActiveRdfLogger::log_debug(self) { "Adding triple #{s} #{p} #{o}" }
163
+ # add triple to datamodel
164
+ def add(s,p,o,c=nil)
165
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
166
+ ActiveRdfLogger::log_warn(self) { "Adapter does not support contexts" } if (!@contexts and !c.nil?)
167
+ ActiveRdfLogger::log_debug(self) { "Adding triple #{s} #{p} #{o} #{c}" }
205
168
 
206
- # verify input
207
- if s.nil? || p.nil? || o.nil?
169
+ # verify input
170
+ if s.nil? || p.nil? || o.nil?
208
171
  ActiveRdfLogger::log_debug "Cannot add triple with empty subject, exiting", self
209
- return false
210
- end
211
-
212
- unless (((s.class == String) && (p.class == String) && (o.class == String)) &&
213
- ((s[0..0] == '<') && (s[-1..-1] == '>')) &&
214
- ((p[0..0] == '<') && (p[-1..-1] == '>'))) || (s.respond_to?(:uri) && p.respond_to?(:uri))
215
- ActiveRdfLogger::log_debug "Cannot add triple where s/p are not resources, exiting", self
216
- return false
217
- end
218
-
219
- begin
220
- if ((s.class != String) || (p.class != String) || (o.class != String))
221
- result = (@model.add(wrap(s), wrap(p), wrap(o)) == 0)
222
- else
223
- result = (@model.add(wrapString(s), wrapString(p), wrapString(o)) == 0)
172
+ return false
224
173
  end
225
- if (result == true)
226
- result = save if ConnectionPool.auto_flush?
174
+
175
+ unless s.respond_to?(:uri) && p.respond_to?(:uri)
176
+ ActiveRdfLogger::log_info(self) { "RedlandAdapter: cannot add triple where s/p are not resources, exiting" }
177
+ return false
227
178
  end
228
- return result
229
- rescue Redland::RedlandError => e
230
- ActiveRdfLogger::log_warn "Adding triple failed in Redland library: #{e}", self
231
- return false
232
- end
233
- end
179
+ quad = [s,p,o,c].collect{|e| to_redland(e)}
234
180
 
235
- # deletes triple(s,p,o) from datastore
236
- # nil parameters match anything: delete(nil,nil,nil) will delete all triples
237
- # * s: subject
238
- # * p: predicate
239
- # * o: object
240
- def delete(s,p,o,c=nil)
241
- if ((s.class != String) && (p.class != String) && (o.class != String))
242
- s = wrap(s) unless s.nil?
243
- p = wrap(p) unless p.nil?
244
- o = wrap(o) unless o.nil?
245
-
246
- # if any parameter is nil we need to iterate over all matching triples
247
- if (s.nil? or p.nil? or o.nil?)
248
- @model.find(s,p,o) { |s,p,o| @model.delete(s,p,o) }
181
+ @model.add(*quad)
182
+ save if ConnectionPool.auto_flush?
183
+ rescue Redland::RedlandError => e
184
+ ActiveRdfLogger::log_warn "Adding triple (#{quad}) failed in Redland library: #{e}", self
185
+ return false
186
+ end
187
+
188
+ # deletes triple(s,p,o) from datastore
189
+ # nil parameters match anything: delete(nil,nil,nil) will delete all triples
190
+ def delete(s,p,o,c=nil)
191
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
192
+ quad = [s,p,o,c].collect{|e| to_redland(e)}
193
+ if quad.all?{|t| t.nil?}
194
+ clear
195
+ elsif quad[0..2].any?{|t| t.nil?}
196
+ @model.find(*quad).each{|stmt| @model.delete_statement(stmt,c)}
249
197
  else
250
- @model.delete(s,p,o)
198
+ @model.delete(*quad)
251
199
  end
200
+ save if ConnectionPool.auto_flush?
201
+ rescue Redland::RedlandError => e
202
+ $activerdflog.warn "RedlandAdapter: deleting triple failed in Redland library: #{e}"
203
+ return false
252
204
  end
253
205
 
254
- @model.delete(s,p,o) == 0
255
- end
256
-
257
- # saves updates to the model into the redland file location
258
- def save
259
- Redland::librdf_model_sync(@model.model) == 0
260
- end
261
- alias flush save
206
+ # saves updates to the model into the redland file location
207
+ def save
208
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
209
+ Redland::librdf_model_sync(@model.model).nil?
210
+ end
211
+ alias flush save
212
+
213
+ # returns all triples in the datastore
214
+ def dump
215
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
216
+ arr = []
217
+ @model.triples{|s,p,o| arr << [s.to_s,p.to_s,o.to_s]}
218
+ arr
219
+ end
262
220
 
263
- # returns all triples in the datastore
264
- # * type: dump syntax
265
- def dump(type = 'ntriples')
266
- Redland.librdf_model_to_string(@model.model, nil, type)
267
- end
221
+ def contexts
222
+ @model.contexts
223
+ end
268
224
 
269
- # returns size of datasources as number of triples
270
- # warning: expensive method as it iterates through all statements
271
- def size
272
- # we cannot use @model.size, because redland does not allow counting of
273
- # file-based models (@model.size raises an error if used on a file)
274
- # instead, we just dump all triples, and count them
275
- @model.triples.size
276
- end
225
+ # returns size of datasources as number of triples
226
+ # warning: expensive method as it iterates through all statements
227
+ def size
228
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
229
+ # we cannot use @model.size, because redland does not allow counting of
230
+ # file-based models (@model.size raises an error if used on a file)
231
+ # instead, we just dump all triples, and count them
232
+ @model.triples.size
233
+ end
277
234
 
278
- # clear all real triples of adapter
279
- def clear
280
- @model.find(nil, nil, nil) {|s,p,o| @model.delete(s,p,o)}
281
- end
235
+ # clear all real triples of adapter
236
+ def clear
237
+ raise ActiveRdfError, "RedlandAdapter: adapter is closed" unless @enabled
238
+ @model.triples.each{|stmt| @model.delete_statement(stmt)}
239
+ end
282
240
 
283
- # close adapter and remove it from the ConnectionPool
284
- def close
285
- ConnectionPool.remove_data_source(self)
286
- end
241
+ # close adapter and remove it from the ConnectionPool
242
+ def close
243
+ if @enabled
244
+ ConnectionPool.remove_data_source(self)
245
+ flush # sync model with datastore
246
+ @model = nil # remove reference to model for removal by GC
247
+ @enabled = false
248
+ end
249
+ end
287
250
 
288
- private
289
- ################ helper methods ####################
290
- #TODO: if block is given we should not parse all results into array first
291
- # result_type is the type that should be used for "resource" properties.
292
- def query_result_to_array(query_results, to_string, result_type)
293
- results = []
294
- number_bindings = query_results.binding_names.size
295
-
296
- # walk through query results, and construct results array
297
- # by looking up each result (if it is a resource) and adding it to the result-array
298
- # for literals we only add the values
299
-
300
- # redland results are set that needs to be iterated
301
- while not query_results.finished?
302
- # we collect the bindings in each row and add them to results
303
- results << (0..number_bindings-1).collect do |i|
304
- # node is the query result for one binding
305
- node = query_results.binding_value(i)
306
-
307
- # we determine the node type
308
- if node.literal?
309
- # for literal nodes we just return the value
310
- Redland.librdf_node_get_literal_value(node.node)
311
- elsif node.blank?
312
- # blank nodes we ignore
313
- if to_string == false
251
+ private
252
+ ################ helper methods ####################
253
+ def query_result_to_array(query_results, &block)
254
+ results = []
255
+ number_bindings = query_results.binding_names.size
256
+
257
+ # redland results are set that needs to be iterated
258
+ while not query_results.finished?
259
+ # we collect the bindings in each row and add them to results
260
+ row = (0..number_bindings-1).collect do |i|
261
+ # node is the query result for one binding
262
+ node = query_results.binding_value(i)
263
+
264
+ # we determine the node type
265
+ if node.nil?
314
266
  nil
315
- else
316
- # check blank node id
317
- if node.blank_identifier
318
- "_:#{node.blank_identifier}"
267
+ elsif node.literal?
268
+ value = Redland.librdf_node_get_literal_value(node.node)
269
+
270
+ lang_uri_ref = Redland.librdf_node_get_literal_value_language(node.node)
271
+ dt_uri_ref = Redland.librdf_node_get_literal_value_datatype_uri(node.node)
272
+ if lang_uri_ref
273
+ LocalizedString.new(value,Redland::Uri.new(lang_uri_ref).to_s)
274
+ elsif dt_uri_ref
275
+ type = RDFS::Resource.new(Redland::Uri.new(dt_uri_ref).to_s)
276
+ RDFS::Literal.typed(value,type)
277
+ elsif lang_uri_ref and dt_uri_ref
278
+ raise ActiveRdfError, "cannot have both datatype and lang set"
319
279
  else
320
- "_:"
280
+ RDFS::Literal.typed(value,XSD::string) # string is default type if none specified
321
281
  end
322
- end
323
- else
324
- # other nodes are rdfs:resources
325
- if to_string == false
326
- result_type.new(node.uri.to_s)
282
+ elsif node.blank?
283
+ # blank nodes are not currently supported
284
+ nil
327
285
  else
328
- "<#{node.uri.to_s}>"
286
+ # other nodes are rdfs:resources
287
+ RDFS::Resource.new(node.uri.to_s)
329
288
  end
330
289
  end
290
+ if block_given?
291
+ yield row
292
+ else
293
+ results << row
294
+ end
295
+ # iterate through result set
296
+ query_results.next
331
297
  end
332
- # iterate through result set
333
- query_results.next
298
+ results unless block_given?
334
299
  end
335
300
 
336
- results
337
- end
338
-
339
- def wrap node
340
- if(node.respond_to?(:uri))
341
- Redland::Uri.new(node.uri.to_s)
342
- else
343
- Redland::Literal.new(node.to_s)
344
- end
345
- end
346
-
347
- def wrapString node
348
- node = node.to_s
349
- if ((node[0..0] == '<') && (node[-1..-1] == '>'))
350
- return Redland::Uri.new(node[1..-2])
351
- elsif (node[0..1] == '_:')
352
- if (node.length > 2)
353
- return Redland::BNode.new(node[2..-1])
354
- else
355
- return Redland::BNode.new
301
+ def to_redland(obj)
302
+ case obj
303
+ when RDFS::Resource
304
+ Redland::Uri.new(obj.uri)
305
+ when RDFS::Literal
306
+ str = obj.kind_of?(Time) ? obj.xmlschema : obj.to_s
307
+ if not $activerdf_without_datatype
308
+ if obj.kind_of?(LocalizedString)
309
+ Redland::Literal.new(str, obj.lang)
310
+ else
311
+ Redland::Literal.new(str,nil,Redland::Uri.new(obj.datatype.uri))
312
+ end
313
+ else
314
+ Redland::Literal.new(str)
315
+ end
316
+ when Class
317
+ raise ActiveRdfError, "RedlandAdapter: class must inherit from RDFS::Resource" unless obj.ancestors.include?(RDFS::Resource)
318
+ Redland::Uri.new(obj.class_uri.to_s)
319
+ when Symbol, nil
320
+ nil
321
+ else
322
+ Redland::Literal.new(obj.to_s)
356
323
  end
357
- else
358
- return Redland::Literal.new(node)
359
- end
324
+ end
360
325
  end
361
-
362
326
  end