activerdf_rdflite 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
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: