activerdf_rdflite 1.1 → 1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -13,19 +13,20 @@ setup_rdoc ['README', 'LICENSE', 'lib/**/*.rb', 'doc/**/*.rdoc']
13
13
  desc "test and package gem"
14
14
  task :default => [:test, :package]
15
15
 
16
- # get ActiveRdfVersion from commandline
17
- ActiveRdfVersion = ENV['REL'] || '1.0'
16
+ # get VERSION from commandline
17
+ VERSION = '1.2'
18
18
  NAME="activerdf_rdflite"
19
- GEMNAME="#{NAME}-#{ActiveRdfVersion}.gem"
19
+ GEMNAME="#{NAME}-#{VERSION}.gem"
20
20
 
21
21
  # define package task
22
- setup_gem(NAME,ActiveRdfVersion) do |spec|
22
+ setup_gem(NAME,VERSION) do |spec|
23
23
  spec.summary = "an RDF database for usage in ActiveRDF (based on sqlite3)"
24
24
  spec.description = spec.summary
25
25
  spec.author="Eyal Oren <eyal.oren@deri.org"
26
26
  spec.add_dependency('gem_plugin', '>= 0.2.1')
27
- spec.add_dependency('activerdf', '>= 0.9.2')
28
- spec.add_dependency('sqlite3-ruby', '>= 1.1.0')
27
+ spec.add_dependency('uuidtools')
28
+ spec.add_dependency('activerdf', '>= 1.2')
29
+ spec.add_dependency('sqlite3-ruby', '>= 1.1.0.1')
29
30
  end
30
31
 
31
32
  task :install => [:package] do
@@ -39,6 +40,6 @@ end
39
40
  task :reinstall => [:uninstall, :install]
40
41
 
41
42
  task :upload => :package do |task|
42
- sh "scp pkg/#{GEMNAME} eyal@m3pe.org:/home/eyal/webs/activerdf/gems/"
43
+ sh "scp pkg/#{GEMNAME} eyal@activerdf.org:/home/eyal/webs/activerdf/gems/"
43
44
  end
44
45
 
@@ -1,16 +1,8 @@
1
- #class String
2
- # alias _match match
3
- # def match(*args)
4
- # m = _match(args.first)
5
- # if m && m.length > 1
6
- # args[1..-1].each_with_index do |name, index|
7
- # m.instance_eval "def #{name}; self[#{index+1}] end"
8
- # end
9
- # end
10
- # m
11
- # end
12
- #end
1
+ # Author:: Eyal Oren
2
+ # Copyright:: (c) 2005-2006 Eyal Oren
3
+ # License:: LGPL
13
4
 
5
+ # FetchingAdapter is an extension to rdflite for fetching RDF from online sources.
14
6
  class FetchingAdapter < RDFLite
15
7
  ConnectionPool.register_adapter(:fetching,self)
16
8
 
@@ -41,3 +33,17 @@ class FetchingAdapter < RDFLite
41
33
  add_ntriples(triples, context)
42
34
  end
43
35
  end
36
+
37
+ #class String
38
+ # alias _match match
39
+ # def match(*args)
40
+ # m = _match(args.first)
41
+ # if m && m.length > 1
42
+ # args[1..-1].each_with_index do |name, index|
43
+ # m.instance_eval "def #{name}; self[#{index+1}] end"
44
+ # end
45
+ # end
46
+ # m
47
+ # end
48
+ #end
49
+
@@ -5,6 +5,7 @@
5
5
  require 'sqlite3'
6
6
  require 'active_rdf'
7
7
  require 'federation/connection_pool'
8
+ require_gem 'uuidtools'
8
9
 
9
10
  $activerdflog.info "loading RDFLite adapter"
10
11
 
@@ -91,9 +92,9 @@ class RDFLite < ActiveRdfAdapter
91
92
  # symbol parameters match anything: delete(:s,:p,:o) will delete all triples
92
93
  # you can specify a context to limit deletion to that context:
93
94
  # delete(:s,:p,:o, 'http://context') will delete all triples with that context
94
- def delete(s,p,o,c=nil)
95
- # convert input to internal format
96
- quad = [s,p,o,c].collect {|r| internalise(r) }
95
+ def delete(s, p, o, c=nil)
96
+ # convert non-nil input to internal format
97
+ quad = [s,p,o,c].collect {|r| r.nil? ? nil : internalise(r) }
97
98
 
98
99
  # construct where clause for deletion (for all non-nil input)
99
100
  where_clauses = []
@@ -132,8 +133,11 @@ class RDFLite < ActiveRdfAdapter
132
133
  # get internal representation (array)
133
134
  quad = [s,p,o,c].collect {|r| internalise(r) }
134
135
 
135
- # add triple to database
136
- add_internal(@db,*quad)
136
+ # insert the triple into the datastore
137
+ @db.execute('insert into triple values (?,?,?,?)', *quad)
138
+
139
+ # if keyword-search available, insert the object into keyword search
140
+ @ferret << {:subject => s, :object => o} if keyword_search?
137
141
  end
138
142
 
139
143
  # flushes openstanding changes to underlying sqlite3
@@ -148,48 +152,48 @@ class RDFLite < ActiveRdfAdapter
148
152
  ntriples = File.readlines(file)
149
153
  $activerdflog.debug "read #{ntriples.size} triples from file #{file}"
150
154
 
151
- context = "<file:#{file}>"
152
- add_ntriples(ntriples, context)
153
- end
154
-
155
- # adds string of ntriples from given context to database
156
- def add_ntriples(ntriples, context=nil)
157
- # convert context to internal format if RDFS::Resource
158
- context = internalise(context)
155
+ # use filename as context
156
+ context = internalise(RDFS::Resource.new("file:#{file}"))
159
157
 
160
158
  # need unique identifier for this batch of triples (to detect occurence of
161
159
  # same bnodes _:#1
162
- uuid = `uuidgen`
160
+ uuid = UUID.random_create.to_s
163
161
 
164
162
  # add each triple to db
165
- @db.transaction do |tr|
166
- ntriples.each do |triple|
167
- nodes = triple.scan(Node)
168
-
169
- # handle bnodes if necessary (bnodes need to have uri generated)
170
- subject = case nodes[0]
171
- when BNode
172
- "<http://www.activerdf.org/bnode/#$1/#{uuid}>"
173
- else
174
- nodes[0]
175
- end
176
-
177
- predicate = nodes[1]
178
-
179
- # handle bnodes and literals if necessary (literals need unicode fixing)
180
- object = case nodes[2]
181
- when BNode
182
- "<http://www.activerdf.org/bnode/#$1/#{uuid}>"
183
- when Literal
184
- fix_unicode(nodes[2])
185
- else
186
- nodes[2]
187
- end
188
-
189
- add_internal(tr, subject, predicate, object, context)
190
- end
163
+ @db.transaction
164
+ insert = @db.prepare('insert into triple values (?,?,?,?);')
165
+
166
+ ntriples.each do |triple|
167
+ nodes = triple.scan(Node)
168
+
169
+ # handle bnodes if necessary (bnodes need to have uri generated)
170
+ subject = case nodes[0]
171
+ when BNode
172
+ "<http://www.activerdf.org/bnode/#{uuid}/#$1>"
173
+ else
174
+ nodes[0]
175
+ end
176
+
177
+ predicate = nodes[1]
178
+
179
+ # handle bnodes and literals if necessary (literals need unicode fixing)
180
+ object = case nodes[2]
181
+ when BNode
182
+ "<http://www.activerdf.org/bnode/#$1/#{uuid}>"
183
+ when Literal
184
+ fix_unicode(nodes[2])
185
+ else
186
+ nodes[2]
187
+ end
188
+
189
+ # insert triple into database
190
+ insert.execute(subject, predicate, object, context)
191
+
192
+ # if keyword-search available, insert the object into keyword search
193
+ @ferret << {:subject => subject, :object => object} if keyword_search?
191
194
  end
192
195
 
196
+ @db.commit
193
197
  @db
194
198
  end
195
199
 
@@ -200,9 +204,6 @@ class RDFLite < ActiveRdfAdapter
200
204
 
201
205
  # executing query, passing all where-clause values as parameters (so that
202
206
  # sqlite will encode quotes correctly)
203
- #constraints = right_hand_sides.collect { |value| value.to_s }
204
-
205
- # executing query
206
207
  results = @db.execute(sql, *conditions)
207
208
 
208
209
  # if ASK query, we check whether we received a positive result count
@@ -230,16 +231,6 @@ class RDFLite < ActiveRdfAdapter
230
231
  Node = Regexp.union(/_:\S*/,/<[^>]*>/,/"[^"]*"/)
231
232
  SPOC = ['s','p','o','c']
232
233
 
233
- # adds s,p,o into sqlite and ferret
234
- # s,p,o should be in internal format: <uri> and "literal"
235
- def add_internal(db, s, p, o, c)
236
- # insert the triple into the datastore
237
- db.execute('insert into triple values (?,?,?,?)', s,p,o,c)
238
-
239
- # if keyword-search available, insert the object into keyword search
240
- @ferret << {:subject => s, :object => o} if keyword_search?
241
- end
242
-
243
234
  # construct select clause
244
235
  def construct_select(query)
245
236
  # ASK queries counts the results, and return true if results > 0
@@ -375,7 +366,7 @@ class RDFLite < ActiveRdfAdapter
375
366
  raise ActiveRdfError, "where clause #{clause} is not a triple" unless clause.is_a?(Array)
376
367
  clause.each_with_index do |subclause, i|
377
368
  # dont add where clause for variables
378
- unless subclause.is_a?(Symbol)
369
+ unless subclause.is_a?(Symbol) || subclause.nil?
379
370
  conditions = compute_where_condition(i, subclause, query.reasoning? && reasoning?)
380
371
  if conditions.size == 1
381
372
  where << "t#{level}.#{SPOC[i]} = ?"
@@ -1,9 +1,20 @@
1
- require 'pp'
1
+ # Author:: Eyal Oren
2
+ # Copyright:: (c) 2005-2006 Eyal Oren
3
+ # License:: LGPL
4
+
5
+ # The SuggestingAdapter is an extension to rdflite that can recommand
6
+ # additional predicates for a given resource, based on usage statistics in the
7
+ # whole dataset. E.g. given a dataset with FOAF data, one can ask a suggestion
8
+ # for a person and get a recommendation for this person to also use
9
+ # foaf:birthday. You can use this adapter in any collaborative editing setting:
10
+ # it leads the community to converge on terminology (everybody will use the
11
+ # same foaf:birthday to define somebody's birthday).
2
12
  class SuggestingAdapter < FetchingAdapter
3
13
  ConnectionPool.register_adapter(:suggesting,self)
4
14
 
5
15
  alias _old_initialize initialize
6
16
 
17
+ # initialises the adapter, see RDFLite for description of possible parameters.
7
18
  def initialize params
8
19
  _old_initialize(params)
9
20
  @db.execute('drop view if exists occurrence')
@@ -13,6 +24,7 @@ class SuggestingAdapter < FetchingAdapter
13
24
  @db.execute('create view cooccurrence as select t0.p as p1,t1.p as p2, count(distinct t0.s) as count from triple as t0 join triple as t1 on t0.s=t1.s and t0.p!=t1.p group by t0.p, t1.p')
14
25
  end
15
26
 
27
+ # suggests additional predicates that might be applicable for the given resource
16
28
  def suggest(resource)
17
29
  $activerdflog.debug "starting suggestions for #{size} triples"
18
30
  time = Time.now
@@ -29,6 +41,7 @@ class SuggestingAdapter < FetchingAdapter
29
41
 
30
42
  # fetch all predicates co-occurring with our predicates
31
43
  candidates = predicates.collect {|p| cooccurring(p) }
44
+ return nil if candidates.empty?
32
45
 
33
46
  # perform set intersection
34
47
  candidates = candidates.inject {|intersect, n| intersect & n }.flatten
@@ -44,6 +57,7 @@ class SuggestingAdapter < FetchingAdapter
44
57
  suggestions
45
58
  end
46
59
 
60
+ private
47
61
  def construct_occurrence_matrix
48
62
  @occurrence = {}
49
63
  @db.execute('select * from occurrence where count > 1') do |p,count|
@@ -0,0 +1,5 @@
1
+ _:1 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://activerdf.org/test/Person> .
2
+ _:1 <http://activerdf.org/test/age> "27" .
3
+ _:1 <http://activerdf.org/test/name> "Eyal Oren" .
4
+ _:2 <http://activerdf.org/test/age> "27" .
5
+ _:2 <http://activerdf.org/test/eye> "blue" .
data/test/test_rdflite.rb CHANGED
@@ -19,6 +19,7 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
19
19
  def test_registration
20
20
  adapter = ConnectionPool.add_data_source(:type => :rdflite)
21
21
  assert_instance_of RDFLite, adapter
22
+ assert adapter.keyword_search?
22
23
  end
23
24
 
24
25
  def test_initialise
@@ -48,7 +49,7 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
48
49
 
49
50
  adapter.add(eyal, age, test)
50
51
 
51
- result = Query.new.distinct(:s).where(:s, :p, :o).execute
52
+ result = Query.new.distinct(:s).where(:s, :p, :o).execute(:flatten => true)
52
53
  assert_instance_of RDFS::Resource, result
53
54
  assert_equal 'eyaloren.org', result.uri
54
55
  end
@@ -66,7 +67,7 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
66
67
  adapter2.add(eyal, age, test2)
67
68
 
68
69
  # assert only one distinct subject is found (same one in both adapters)
69
- assert_equal 1, Query.new.distinct(:s).where(:s, :p, :o).execute(:flatten=>false).size
70
+ assert_equal 1, Query.new.distinct(:s).where(:s, :p, :o).execute.size
70
71
 
71
72
  # assert two distinct objects are found
72
73
  results = Query.new.distinct(:o).where(:s, :p, :o).execute
@@ -83,7 +84,7 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
83
84
  test = RDFS::Resource.new 'test'
84
85
 
85
86
  adapter.add(eyal, age, test)
86
- Query.new.select(:s,:p).where(:s,:p,:o).execute do |s,p|
87
+ Query.new.select(:s,:p).where(:s,:p,:o).execute(:flatten => false) do |s,p|
87
88
  assert_equal 'eyaloren.org', s.uri
88
89
  assert_equal 'foaf:age', p.uri
89
90
  end
@@ -95,6 +96,24 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
95
96
  assert_equal 32, adapter.size
96
97
  end
97
98
 
99
+ def test_load_bnodes
100
+ adapter = ConnectionPool.add_data_source :type => :rdflite
101
+ adapter.load(File.dirname(File.expand_path(__FILE__)) + '/test_bnode_data.nt')
102
+
103
+ # loaded five triples in total
104
+ assert_equal 5, adapter.size
105
+
106
+ # triples contain two distinct bnodes
107
+ assert_equal 2, Query.new.count.distinct(:s).where(:s,:p,:o).execute
108
+
109
+ # collecting the bnodes
110
+ bnodes = Query.new.distinct(:s).where(:s,:p,:o).execute
111
+ # assert that _:#1 occurs in three triples
112
+ assert_equal 3, Query.new.select(:p,:o).where(bnodes[0], :p, :o).execute.size
113
+ # assert that _:#2 occurs in two triples
114
+ assert_equal 2, Query.new.select(:p,:o).where(bnodes[1], :p, :o).execute.size
115
+ end
116
+
98
117
  def test_count_query
99
118
  adapter = ConnectionPool.add_data_source :type => :rdflite
100
119
  adapter.load(File.dirname(File.expand_path(__FILE__)) + '/test_data.nt')
@@ -107,7 +126,7 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
107
126
  file = File.dirname(File.expand_path(__FILE__)) + '/test_data.nt'
108
127
  adapter.load(file)
109
128
 
110
- context = Query.new.distinct(:c).where(:s,:p,:o,:c).execute
129
+ context = Query.new.distinct(:c).where(:s,:p,:o,:c).execute(:flatten => true)
111
130
  assert_instance_of RDFS::Resource, context
112
131
  assert_equal RDFS::Resource.new("file:#{file}"), context
113
132
  end
@@ -127,8 +146,8 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
127
146
  assert_equal file_context, context[0]
128
147
  assert_equal '', context[1]
129
148
 
130
- n1 = Query.new.distinct(:s).where(:s,:p,:o,'').execute(:flatten => false)
131
- n2 = Query.new.distinct(:s).where(:s,:p,:o,file_context).execute(:flatten => false)
149
+ n1 = Query.new.distinct(:s).where(:s, :p, :o, '').execute
150
+ n2 = Query.new.distinct(:s).where(:s, :p, :o, file_context).execute
132
151
  assert_equal 1, n1.size
133
152
  assert_equal 9, n2.size
134
153
  end
@@ -144,7 +163,7 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
144
163
  type = Namespace.lookup(:rdf, :type)
145
164
  resource = Namespace.lookup(:rdfs,:resource)
146
165
 
147
- color = Query.new.select(:o).where(eyal, eye,:o).execute
166
+ color = Query.new.select(:o).where(eyal, eye,:o).execute(:flatten => true)
148
167
  assert 'blue', color
149
168
  assert_instance_of String, color
150
169
 
@@ -162,7 +181,7 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
162
181
  adapter.delete(eyal, nil, nil)
163
182
  assert_equal 27, adapter.size
164
183
 
165
- adapter.delete(nil,nil,nil)
184
+ adapter.delete(nil, nil, nil)
166
185
  assert_equal 0, adapter.size
167
186
  end
168
187
 
@@ -171,9 +190,9 @@ class TestRdfLiteAdapter < Test::Unit::TestCase
171
190
  adapter.load(File.dirname(File.expand_path(__FILE__)) + '/test_data.nt')
172
191
 
173
192
  eyal = RDFS::Resource.new('http://activerdf.org/test/eyal')
174
- assert_equal eyal, Query.new.distinct(:s).where(:s,:keyword,"blue").execute
175
- assert_equal eyal, Query.new.distinct(:s).where(:s,:keyword,"27").execute
176
- assert_equal eyal, Query.new.distinct(:s).where(:s,:keyword,"eyal oren").execute
193
+ assert_equal eyal, Query.new.distinct(:s).where(:s,:keyword,"blue").execute(:flatten => true)
194
+ assert_equal eyal, Query.new.distinct(:s).where(:s,:keyword,"27").execute(:flatten => true)
195
+ assert_equal eyal, Query.new.distinct(:s).where(:s,:keyword,"eyal oren").execute(:flatten => true)
177
196
  end
178
197
 
179
198
  def test_bnodes
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: activerdf_rdflite
5
5
  version: !ruby/object:Gem::Version
6
- version: "1.1"
7
- date: 2006-12-08 00:00:00 +00:00
6
+ version: "1.2"
7
+ date: 2006-12-21 00:00:00 +01:00
8
8
  summary: an RDF database for usage in ActiveRDF (based on sqlite3)
9
9
  require_paths:
10
10
  - lib
@@ -34,6 +34,7 @@ files:
34
34
  - Rakefile
35
35
  - test/test_rdflite.rb
36
36
  - test/test_data.nt
37
+ - test/test_bnode_data.nt
37
38
  - lib/activerdf_rdflite
38
39
  - lib/activerdf_rdflite/init.rb
39
40
  - lib/activerdf_rdflite/rdflite.rb
@@ -61,6 +62,15 @@ dependencies:
61
62
  - !ruby/object:Gem::Version
62
63
  version: 0.2.1
63
64
  version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: uuidtools
67
+ version_requirement:
68
+ version_requirements: !ruby/object:Gem::Version::Requirement
69
+ requirements:
70
+ - - ">"
71
+ - !ruby/object:Gem::Version
72
+ version: 0.0.0
73
+ version:
64
74
  - !ruby/object:Gem::Dependency
65
75
  name: activerdf
66
76
  version_requirement:
@@ -68,7 +78,7 @@ dependencies:
68
78
  requirements:
69
79
  - - ">="
70
80
  - !ruby/object:Gem::Version
71
- version: 0.9.2
81
+ version: "1.2"
72
82
  version:
73
83
  - !ruby/object:Gem::Dependency
74
84
  name: sqlite3-ruby
@@ -77,5 +87,5 @@ dependencies:
77
87
  requirements:
78
88
  - - ">="
79
89
  - !ruby/object:Gem::Version
80
- version: 1.1.0
90
+ version: 1.1.0.1
81
91
  version: