rdf_context 0.5.9.1 → 0.5.10

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.
Files changed (63) hide show
  1. data/.gitignore +0 -1
  2. data/History.rdoc +23 -2
  3. data/Rakefile +17 -17
  4. data/VERSION +1 -1
  5. data/bin/rdf_context +1 -4
  6. data/lib/rdf_context.rb +55 -19
  7. data/lib/rdf_context/aggregate_graph.rb +0 -2
  8. data/lib/rdf_context/bnode.rb +14 -1
  9. data/lib/rdf_context/conjunctive_graph.rb +0 -2
  10. data/lib/rdf_context/graph.rb +9 -10
  11. data/lib/rdf_context/literal.rb +39 -56
  12. data/lib/rdf_context/n3_grammar.treetop +2 -2
  13. data/lib/rdf_context/n3parser.rb +7 -5
  14. data/lib/rdf_context/parser.rb +2 -3
  15. data/lib/rdf_context/quoted_graph.rb +0 -2
  16. data/lib/rdf_context/rdfaparser.rb +93 -68
  17. data/lib/rdf_context/rdfxmlparser.rb +1 -1
  18. data/lib/rdf_context/resource.rb +56 -0
  19. data/lib/rdf_context/serializer/abstract_serializer.rb +0 -2
  20. data/lib/rdf_context/serializer/nt_serializer.rb +0 -2
  21. data/lib/rdf_context/serializer/recursive_serializer.rb +0 -4
  22. data/lib/rdf_context/serializer/turtle_serializer.rb +0 -2
  23. data/lib/rdf_context/serializer/xml_serializer.rb +0 -2
  24. data/lib/rdf_context/store/abstract_sql_store.rb +3 -1
  25. data/lib/rdf_context/store/active_record_store.rb +272 -0
  26. data/lib/rdf_context/store/list_store.rb +2 -2
  27. data/lib/rdf_context/store/memory_store.rb +2 -2
  28. data/lib/rdf_context/store/sqlite3_store.rb +112 -48
  29. data/lib/rdf_context/term_utils.rb +0 -4
  30. data/lib/rdf_context/triple.rb +1 -3
  31. data/lib/rdf_context/uriref.rb +14 -1
  32. data/rdf_context.gemspec +872 -0
  33. data/script/tc +4 -4
  34. data/spec/active_record_store_spec.rb +61 -0
  35. data/spec/aggregate_graph_spec.rb +1 -1
  36. data/spec/bnode_spec.rb +37 -1
  37. data/spec/conjunctive_graph_spec.rb +1 -1
  38. data/spec/cwm_spec.rb +5 -5
  39. data/spec/duration_spec.rb +1 -1
  40. data/spec/graph_spec.rb +16 -2
  41. data/spec/list_store_spec.rb +1 -1
  42. data/spec/literal_spec.rb +47 -14
  43. data/spec/memory_store_spec.rb +1 -1
  44. data/spec/n3parser_spec.rb +19 -5
  45. data/spec/namespaces_spec.rb +1 -1
  46. data/spec/parser_spec.rb +1 -1
  47. data/spec/rdf_helper.rb +18 -15
  48. data/spec/rdfa_helper.rb +27 -14
  49. data/spec/rdfa_parser_spec.rb +28 -9
  50. data/spec/rdfxml_spec.rb +3 -3
  51. data/spec/spec_helper.rb +10 -5
  52. data/spec/sqlite3_store_spec.rb +1 -1
  53. data/spec/string_hacks_spec.rb +2 -1
  54. data/spec/swap_spec.rb +7 -7
  55. data/spec/swap_test/ref/contexts-1.n3 +12 -0
  56. data/spec/swap_test/ref/prefix2.rdf +33 -0
  57. data/spec/swap_test/ref/xmllit.nt +1 -1
  58. data/spec/swap_test/regression.n3 +18 -18
  59. data/spec/triple_spec.rb +1 -1
  60. data/spec/turtle_serializer_spec.rb +3 -3
  61. data/spec/turtle_spec.rb +3 -3
  62. data/spec/uriref_spec.rb +31 -1
  63. metadata +13 -15
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'parser')
1
+ require File.join(File.dirname(__FILE__), "nokogiri_hacks")
2
2
 
3
3
  module RdfContext
4
4
  class RdfXmlParser < Parser
@@ -0,0 +1,56 @@
1
+ module RdfContext
2
+ # Common super-class for things that are RDF Resources
3
+ class Resource
4
+
5
+ ##
6
+ # Returns `true` to indicate that this value is a resource.
7
+ #
8
+ # @return [Boolean]
9
+ def resource?
10
+ true
11
+ end
12
+
13
+ ##
14
+ # Returns `false`, overridden in Literal
15
+ #
16
+ # @return [Boolean]
17
+ def literal?
18
+ false
19
+ end
20
+
21
+ ##
22
+ # Returns `false`, overridden in URIref
23
+ #
24
+ # @return [Boolean]
25
+ def uri?
26
+ false
27
+ end
28
+
29
+ ##
30
+ # Returns `false`, overridden in BNode
31
+ #
32
+ # @return [Boolean]
33
+ def bnode?
34
+ false
35
+ end
36
+
37
+ ##
38
+ # Returns `false`, overridden in BNode
39
+ #
40
+ # @return [Boolean]
41
+ def graph?
42
+ false
43
+ end
44
+
45
+ # Parse a string to a resource, in NTriples format
46
+ def self.parse(str)
47
+ case str
48
+ when /^_:/ then BNode.parse(str)
49
+ when /^</ then URIRef.parse(str)
50
+ when /^http:/ then URIRef.parse(str)
51
+ when /^\"/ then Literal.parse(str)
52
+ else Literal.parse(str)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,5 +1,3 @@
1
- require File.join(File.dirname(__FILE__), '..', 'uriref')
2
-
3
1
  module RdfContext
4
2
  # Abstract serializer
5
3
  class AbstractSerializer
@@ -1,5 +1,3 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_serializer')
2
-
3
1
  module RdfContext
4
2
  # Serialize RDF graphs in NTriples format
5
3
  class NTSerializer < AbstractSerializer
@@ -1,7 +1,3 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_serializer')
2
- require File.join(File.dirname(__FILE__), '..', 'bnode')
3
- require File.join(File.dirname(__FILE__), '..', 'literal')
4
-
5
1
  module RdfContext
6
2
  # Recursive serializer
7
3
  class RecursiveSerializer < AbstractSerializer
@@ -1,5 +1,3 @@
1
- require File.join(File.dirname(__FILE__), 'recursive_serializer')
2
-
3
1
  module RdfContext
4
2
  # Abstract serializer
5
3
  class TurtleSerializer < RecursiveSerializer
@@ -1,5 +1,3 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_serializer')
2
-
3
1
  module RdfContext
4
2
  # Serialize RDF graphs in NTriples format
5
3
  class XmlSerializer < RecursiveSerializer
@@ -1,7 +1,8 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_store')
2
1
  require 'digest/sha1'
3
2
 
4
3
  module RdfContext
4
+ autoload :AbstractStore, File.join(File.dirname(__FILE__), 'abstract_store')
5
+
5
6
  # SQL-92 formula-aware implementation of an RDF Store.
6
7
  # It stores it's triples in the following partitions:
7
8
  # - Asserted non rdf:type statements
@@ -904,6 +905,7 @@ module RdfContext
904
905
  # Takes a term value, and term type
905
906
  # and Creates a term object. QuotedGraphs are instantiated differently
906
907
  def createTerm(termString,termType,objLanguage=nil,objDatatype=nil)
908
+ #puts "createTerm(#{termString}, #{termType}, ...)" if ::RdfContext::debug?
907
909
  case termType
908
910
  when "L"
909
911
  @literalCache[[termString, objLanguage, objDatatype]] ||= Literal.n3_encoded(termString, objLanguage, objDatatype)
@@ -0,0 +1,272 @@
1
+ gem 'activerecord'
2
+ require 'active_record'
3
+
4
+ module RdfContext
5
+ autoload :AbstractSQLStore, File.join(File.dirname(__FILE__), 'abstract_sql_store')
6
+
7
+ # ActiveRecord store context-ware and formula-aware implementation.
8
+ #
9
+ # Uses an ActiveRecord::Base.connection to run statements
10
+ #
11
+ # It stores it's triples in the following partitions:
12
+ # - Asserted non rdf:type statements
13
+ # - Asserted rdf:type statements (in a table which models Class membership). The motivation for this partition is primarily query speed and scalability as most graphs will always have more rdf:type statements than others
14
+ # - All Quoted statements
15
+ #
16
+ # In addition it persists namespace mappings in a seperate table
17
+ class ActiveRecordStore < AbstractSQLStore
18
+ # Create a new ActiveRecordStore Store
19
+ # @param [URIRef] identifier
20
+ # @param[Hash] configuration Specific to type of storage
21
+ # @return [ActiveRecordStore]
22
+ def initialize(identifier = nil, configuration = {})
23
+ super(identifier, configuration)
24
+ @autocommit_default = false
25
+ end
26
+
27
+ def open(options)
28
+ end
29
+
30
+ def close(commit_pending_transactions = false)
31
+ ActiveRecord::Base.connection.commit_db_transaction if commit_pending_transactions
32
+ end
33
+
34
+ # Create necessary tables and indecies for this database
35
+ def setup
36
+ executeSQL(CREATE_ASSERTED_STATEMENTS_TABLE % @internedId)
37
+ executeSQL(CREATE_ASSERTED_TYPE_STATEMENTS_TABLE % @internedId)
38
+ executeSQL(CREATE_QUOTED_STATEMENTS_TABLE % @internedId)
39
+ executeSQL(CREATE_NS_BINDS_TABLE % @internedId)
40
+ executeSQL(CREATE_LITERAL_STATEMENTS_TABLE % @internedId)
41
+
42
+ # Create indicies
43
+ {
44
+ asserted_table => {
45
+ "#{@internedId}_A_termComb_index" => %w(termComb),
46
+ "#{@internedId}_A_s_index" => %w(subject),
47
+ "#{@internedId}_A_p_index" => %w(predicate),
48
+ "#{@internedId}_A_o_index" => %w(object),
49
+ "#{@internedId}_A_c_index" => %w(context),
50
+ },
51
+ asserted_type_table => {
52
+ "#{@internedId}_T_termComb_index" => %w(termComb),
53
+ "#{@internedId}_T_member_index" => %w(member),
54
+ "#{@internedId}_T_klass_index" => %w(klass),
55
+ "#{@internedId}_T_c_index" => %w(context),
56
+ },
57
+ literal_table => {
58
+ "#{@internedId}_L_termComb_index" => %w(termComb),
59
+ "#{@internedId}_L_s_index" => %w(subject),
60
+ "#{@internedId}_L_p_index" => %w(predicate),
61
+ "#{@internedId}_L_c_index" => %w(context),
62
+ },
63
+ quoted_table => {
64
+ "#{@internedId}_Q_termComb_index" => %w(termComb),
65
+ "#{@internedId}_Q_s_index" => %w(subject),
66
+ "#{@internedId}_Q_p_index" => %w(predicate),
67
+ "#{@internedId}_Q_o_index" => %w(object),
68
+ "#{@internedId}_Q_c_index" => %w(context),
69
+ },
70
+ namespace_binds => {
71
+ "#{@internedId}_uri_index" => %w(uri),
72
+ }
73
+ }.each_pair do |tablename, indicies|
74
+ indicies.each_pair do |index, columns|
75
+ executeSQL("CREATE INDEX #{index} on #{tablename} ('#{columns.join(', ')}')")
76
+ end
77
+ end
78
+ end
79
+
80
+ # Teardown DB files
81
+ def teardown
82
+ # Drop indicies
83
+ {
84
+ asserted_table => {
85
+ "#{@internedId}_A_termComb_index" => %w(termComb),
86
+ "#{@internedId}_A_s_index" => %w(subject),
87
+ "#{@internedId}_A_p_index" => %w(predicate),
88
+ "#{@internedId}_A_o_index" => %w(object),
89
+ "#{@internedId}_A_c_index" => %w(context),
90
+ },
91
+ asserted_type_table => {
92
+ "#{@internedId}_T_termComb_index" => %w(termComb),
93
+ "#{@internedId}_T_member_index" => %w(member),
94
+ "#{@internedId}_T_klass_index" => %w(klass),
95
+ "#{@internedId}_T_c_index" => %w(context),
96
+ },
97
+ literal_table => {
98
+ "#{@internedId}_L_termComb_index" => %w(termComb),
99
+ "#{@internedId}_L_s_index" => %w(subject),
100
+ "#{@internedId}_L_p_index" => %w(predicate),
101
+ "#{@internedId}_L_c_index" => %w(context),
102
+ },
103
+ quoted_table => {
104
+ "#{@internedId}_Q_termComb_index" => %w(termComb),
105
+ "#{@internedId}_Q_s_index" => %w(subject),
106
+ "#{@internedId}_Q_p_index" => %w(predicate),
107
+ "#{@internedId}_Q_o_index" => %w(object),
108
+ "#{@internedId}_Q_c_index" => %w(context),
109
+ },
110
+ namespace_binds => {
111
+ "#{@internedId}_uri_index" => %w(uri),
112
+ }
113
+ }.each_pair do |tablename, indicies|
114
+ tn = "#{@internedId}_#{tablename}"
115
+ indicies.each_pair do |index, columns|
116
+ executeSQL("DROP INDEX #{index} ON #{tn}")
117
+ end
118
+ end
119
+
120
+ # Drop tables
121
+ executeSQL("DROP TABLE #{namespace_binds}")
122
+ executeSQL("DROP TABLE #{quoted_table}")
123
+ executeSQL("DROP TABLE #{literal_table}")
124
+ executeSQL("DROP TABLE #{asserted_type_table}")
125
+ executeSQL("DROP TABLE #{asserted_table}")
126
+ end
127
+
128
+ # Destroy database
129
+ #
130
+ # @option options[String] :path Path to database file defaults to a file in the current directory based on a hash of the store identifier
131
+ def destroy(options = {})
132
+ end
133
+
134
+ protected
135
+
136
+ # Where clase utility functions
137
+ def buildSubjClause(subject, tableName)
138
+ case subject
139
+ # when REGEXTerm
140
+ # when Array
141
+ when Graph
142
+ ["#{tableName}.subject=?", self.normalizeTerm(subject.identifier)]
143
+ else
144
+ ["#{tableName}.subject=?", subject] if subject
145
+ end
146
+ end
147
+
148
+ def buildPredClause(predicate, tableName)
149
+ # case predicate
150
+ # when REGEXTerm
151
+ # when Array
152
+ # else
153
+ ["#{tableName}.predicate=?", predicate] if predicate
154
+ # end
155
+ end
156
+
157
+ # Where clase utility functions
158
+ def buildObjClause(object, tableName)
159
+ case object
160
+ # when REGEXTerm
161
+ # when Array
162
+ when Graph
163
+ ["#{tableName}.object=?", self.normalizeTerm(object.identifier)]
164
+ else
165
+ ["#{tableName}.object=?", object] if object
166
+ end
167
+ end
168
+
169
+ # Where clase utility functions
170
+ def buildContextClause(context, tableName)
171
+ context = normalizeTerm(context) if context
172
+
173
+ # case context
174
+ # when REGEXTerm
175
+ # when Array
176
+ # else
177
+ ["#{tableName}.context=?", context] if context
178
+ # end
179
+ end
180
+
181
+ # Where clase utility functions
182
+ def buildTypeMemberClause(subject, tableName)
183
+ # case context
184
+ # when REGEXTerm
185
+ # when Array
186
+ # else
187
+ ["#{tableName}.member=?", subject] if subject
188
+ # end
189
+ end
190
+
191
+ # Where clase utility functions
192
+ def buildTypeClassClause(object, tableName)
193
+ # case context
194
+ # when REGEXTerm
195
+ # else
196
+ ["#{tableName}.klass=?", object] if object
197
+ # end
198
+ end
199
+
200
+ # This takes the query string and parameters and (depending on the SQL implementation) either fill in
201
+ # the parameter in-place or pass it on to the DB impl (if it supports this).
202
+ # The default (here) is to fill the parameters in-place surrounding each param with quote characters
203
+ #
204
+ # Yields each row
205
+ def executeSQL(qStr, *params, &block)
206
+ conn = ActiveRecord::Base.connection
207
+
208
+ puts "executeSQL: params=#{params.flatten.inspect}" if ::RdfContext::debug?
209
+ puts "executeSQL: '#{params.dup.unshift(qStr).join("', '")}'" if ::RdfContext::debug?
210
+ qStr = ActiveRecord::Base.send(:replace_bind_variables, qStr, params.flatten)
211
+ puts " => '#{qStr}'" if ::RdfContext::debug?
212
+
213
+ if block_given?
214
+ conn.select_rows(qStr).each do |row|
215
+ yield(row)
216
+ end
217
+ else
218
+ puts "executeSQL no block given" if ::RdfContext::debug?
219
+ conn.select_rows(qStr)
220
+ end
221
+ rescue StandardError => e
222
+ puts "SQL Exception (ignored): #{e.message}" if ::RdfContext::debug?
223
+ end
224
+
225
+ CREATE_ASSERTED_STATEMENTS_TABLE = %(
226
+ CREATE TABLE %s_asserted_statements (
227
+ subject text not NULL,
228
+ predicate text not NULL,
229
+ object text not NULL,
230
+ context text not NULL,
231
+ termComb tinyint unsigned not NULL))
232
+
233
+ CREATE_ASSERTED_TYPE_STATEMENTS_TABLE = %(
234
+ CREATE TABLE %s_type_statements (
235
+ member text not NULL,
236
+ klass text not NULL,
237
+ context text not NULL,
238
+ termComb tinyint unsigned not NULL))
239
+
240
+ CREATE_LITERAL_STATEMENTS_TABLE = %(
241
+ CREATE TABLE %s_literal_statements (
242
+ subject text not NULL,
243
+ predicate text not NULL,
244
+ object text,
245
+ context text not NULL,
246
+ termComb tinyint unsigned not NULL,
247
+ objLanguage varchar(3),
248
+ objDatatype text))
249
+
250
+ CREATE_QUOTED_STATEMENTS_TABLE = %(
251
+ CREATE TABLE %s_quoted_statements (
252
+ subject text not NULL,
253
+ predicate text not NULL,
254
+ object text,
255
+ context text not NULL,
256
+ termComb tinyint unsigned not NULL,
257
+ objLanguage varchar(3),
258
+ objDatatype text))
259
+
260
+ CREATE_NS_BINDS_TABLE = %(
261
+ CREATE TABLE %s_namespace_binds (
262
+ prefix varchar(20) UNIQUE not NULL,
263
+ uri text,
264
+ PRIMARY KEY (prefix)))
265
+
266
+ DROP_ASSERTED_STATEMENTS_TABLE = %(DROP TABLE %s_asserted_statements)
267
+ DROP_ASSERTED_TYPE_STATEMENTS_TABLE = %(DROP TABLE %s_type_statements)
268
+ DROP_LITERAL_STATEMENTS_TABLE = %(DROP TABLE %s_literal_statements)
269
+ DROP_QUOTED_STATEMENTS_TABLE = %(DROP TABLE %s_quoted_statements)
270
+ DROP_NS_BINDS_TABLE = %(DROP TABLE %s_namespace_binds)
271
+ end
272
+ end
@@ -1,6 +1,6 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_store')
2
-
3
1
  module RdfContext
2
+ autoload :AbstractStore, File.join(File.dirname(__FILE__), 'abstract_store')
3
+
4
4
  # List storage, most efficient, but slow storage model. Works well for basic parse and serialize.
5
5
  class ListStore < AbstractStore
6
6
  def initialize(identifier = nil, configuration = {})
@@ -1,6 +1,6 @@
1
- require File.join(File.dirname(__FILE__), 'abstract_store')
2
-
3
1
  module RdfContext
2
+ autoload :AbstractStore, File.join(File.dirname(__FILE__), 'abstract_store')
3
+
4
4
  # An integer-key-optimized-context-aware-in-memory store.
5
5
  #
6
6
  # Uses nested dictionaries to store triples and context. Each triple
@@ -1,8 +1,8 @@
1
1
  gem 'sqlite3-ruby', "=1.2.5" # XXX version 1.3.0 & 1.3.1 break executes with multiple arguments: http://groups.google.com/group/sqlite3-ruby/browse_frm/thread/93494ce04bc07fd5
2
2
  require 'sqlite3'
3
- require File.join(File.dirname(__FILE__), 'abstract_sql_store')
4
3
 
5
4
  module RdfContext
5
+ autoload :AbstractSQLStore, File.join(File.dirname(__FILE__), 'abstract_sql_store')
6
6
  # SQLite3 store context-ware and formula-aware implementation.
7
7
  # It stores it's triples in the following partitions:
8
8
  # - Asserted non rdf:type statements
@@ -13,16 +13,18 @@ module RdfContext
13
13
  #
14
14
  # Based on Python RdfLib SQLite
15
15
  class SQLite3Store < AbstractSQLStore
16
- # Create a new SQLite3Store Store, should be subclassed
16
+ # Create a new SQLite3Store Store
17
17
  # @param [URIRef] identifier
18
18
  # @param[Hash] configuration Specific to type of storage
19
+ # @option configuration [String] :db Path to database file
20
+ # @option configuration [String] :connection ActiveRecord::Base.connection.raw_connection
19
21
  # @return [SQLite3Store]
20
22
  def initialize(identifier = nil, configuration = {})
23
+ @path = configuration[:path] ||= File.join(Dir.getwd, "#{@internedId}.db")
24
+
21
25
  super(identifier, configuration)
22
26
 
23
27
  @autocommit_default = false
24
- @path = configuration[:path] || File.join(Dir.getwd, "#{@internedId}.db")
25
- @db = open(:path => @path) unless @db
26
28
  end
27
29
 
28
30
  # Opens the store specified by the configuration hash. If
@@ -34,57 +36,113 @@ module RdfContext
34
36
  #
35
37
  # @option options[String] :path Path to database file defaults to a file in the current directory based on a hash of the store identifier
36
38
  def open(options)
37
- unless File.exist?(options[:path])
39
+ @db ||= options[:connection]
40
+ return @db if @db
41
+
42
+ if options[:path] && !File.exist?(options[:path])
38
43
  @db = SQLite3::Database.new(options[:path])
39
- executeSQL(CREATE_ASSERTED_STATEMENTS_TABLE % @internedId)
40
- executeSQL(CREATE_ASSERTED_TYPE_STATEMENTS_TABLE % @internedId)
41
- executeSQL(CREATE_QUOTED_STATEMENTS_TABLE % @internedId)
42
- executeSQL(CREATE_NS_BINDS_TABLE % @internedId)
43
- executeSQL(CREATE_LITERAL_STATEMENTS_TABLE % @internedId)
44
-
45
- # Create indicies
46
- {
47
- asserted_table => {
48
- "#{@internedId}_A_termComb_index" => %w(termComb),
49
- "#{@internedId}_A_s_index" => %w(subject),
50
- "#{@internedId}_A_p_index" => %w(predicate),
51
- "#{@internedId}_A_o_index" => %w(object),
52
- "#{@internedId}_A_c_index" => %w(context),
53
- },
54
- asserted_type_table => {
55
- "#{@internedId}_T_termComb_index" => %w(termComb),
56
- "#{@internedId}_T_member_index" => %w(member),
57
- "#{@internedId}_T_klass_index" => %w(klass),
58
- "#{@internedId}_T_c_index" => %w(context),
59
- },
60
- literal_table => {
61
- "#{@internedId}_L_termComb_index" => %w(termComb),
62
- "#{@internedId}_L_s_index" => %w(subject),
63
- "#{@internedId}_L_p_index" => %w(predicate),
64
- "#{@internedId}_L_c_index" => %w(context),
65
- },
66
- quoted_table => {
67
- "#{@internedId}_Q_termComb_index" => %w(termComb),
68
- "#{@internedId}_Q_s_index" => %w(subject),
69
- "#{@internedId}_Q_p_index" => %w(predicate),
70
- "#{@internedId}_Q_o_index" => %w(object),
71
- "#{@internedId}_Q_c_index" => %w(context),
72
- },
73
- namespace_binds => {
74
- "#{@internedId}_uri_index" => %w(uri),
75
- }
76
- }.each_pair do |tablename, indicies|
77
- indicies.each_pair do |index, columns|
78
- executeSQL("CREATE INDEX #{index} on #{tablename} ('#{columns.join(', ')}')")
79
- end
80
- end
44
+ setup
81
45
  end
82
46
 
83
47
  raise StoreException.new("Attempt to open missing database file #{options[:path]}") unless File.exist?(options[:path])
84
48
  @db = SQLite3::Database.new(options[:path])
85
49
  end
86
50
 
87
- # Destroy databse
51
+ # Create necessary tables and indecies for this database
52
+ def setup
53
+ executeSQL(CREATE_ASSERTED_STATEMENTS_TABLE % @internedId)
54
+ executeSQL(CREATE_ASSERTED_TYPE_STATEMENTS_TABLE % @internedId)
55
+ executeSQL(CREATE_QUOTED_STATEMENTS_TABLE % @internedId)
56
+ executeSQL(CREATE_NS_BINDS_TABLE % @internedId)
57
+ executeSQL(CREATE_LITERAL_STATEMENTS_TABLE % @internedId)
58
+
59
+ # Create indicies
60
+ {
61
+ asserted_table => {
62
+ "#{@internedId}_A_termComb_index" => %w(termComb),
63
+ "#{@internedId}_A_s_index" => %w(subject),
64
+ "#{@internedId}_A_p_index" => %w(predicate),
65
+ "#{@internedId}_A_o_index" => %w(object),
66
+ "#{@internedId}_A_c_index" => %w(context),
67
+ },
68
+ asserted_type_table => {
69
+ "#{@internedId}_T_termComb_index" => %w(termComb),
70
+ "#{@internedId}_T_member_index" => %w(member),
71
+ "#{@internedId}_T_klass_index" => %w(klass),
72
+ "#{@internedId}_T_c_index" => %w(context),
73
+ },
74
+ literal_table => {
75
+ "#{@internedId}_L_termComb_index" => %w(termComb),
76
+ "#{@internedId}_L_s_index" => %w(subject),
77
+ "#{@internedId}_L_p_index" => %w(predicate),
78
+ "#{@internedId}_L_c_index" => %w(context),
79
+ },
80
+ quoted_table => {
81
+ "#{@internedId}_Q_termComb_index" => %w(termComb),
82
+ "#{@internedId}_Q_s_index" => %w(subject),
83
+ "#{@internedId}_Q_p_index" => %w(predicate),
84
+ "#{@internedId}_Q_o_index" => %w(object),
85
+ "#{@internedId}_Q_c_index" => %w(context),
86
+ },
87
+ namespace_binds => {
88
+ "#{@internedId}_uri_index" => %w(uri),
89
+ }
90
+ }.each_pair do |tablename, indicies|
91
+ indicies.each_pair do |index, columns|
92
+ executeSQL("CREATE INDEX #{index} on #{tablename} ('#{columns.join(', ')}')")
93
+ end
94
+ end
95
+ end
96
+
97
+ # Teardown DB files
98
+ def teardown
99
+ # Drop indicies
100
+ {
101
+ asserted_table => {
102
+ "#{@internedId}_A_termComb_index" => %w(termComb),
103
+ "#{@internedId}_A_s_index" => %w(subject),
104
+ "#{@internedId}_A_p_index" => %w(predicate),
105
+ "#{@internedId}_A_o_index" => %w(object),
106
+ "#{@internedId}_A_c_index" => %w(context),
107
+ },
108
+ asserted_type_table => {
109
+ "#{@internedId}_T_termComb_index" => %w(termComb),
110
+ "#{@internedId}_T_member_index" => %w(member),
111
+ "#{@internedId}_T_klass_index" => %w(klass),
112
+ "#{@internedId}_T_c_index" => %w(context),
113
+ },
114
+ literal_table => {
115
+ "#{@internedId}_L_termComb_index" => %w(termComb),
116
+ "#{@internedId}_L_s_index" => %w(subject),
117
+ "#{@internedId}_L_p_index" => %w(predicate),
118
+ "#{@internedId}_L_c_index" => %w(context),
119
+ },
120
+ quoted_table => {
121
+ "#{@internedId}_Q_termComb_index" => %w(termComb),
122
+ "#{@internedId}_Q_s_index" => %w(subject),
123
+ "#{@internedId}_Q_p_index" => %w(predicate),
124
+ "#{@internedId}_Q_o_index" => %w(object),
125
+ "#{@internedId}_Q_c_index" => %w(context),
126
+ },
127
+ namespace_binds => {
128
+ "#{@internedId}_uri_index" => %w(uri),
129
+ }
130
+ }.each_pair do |tablename, indicies|
131
+ tn = "#{@internedId}_#{tablename}"
132
+ indicies.each_pair do |index, columns|
133
+ executeSQL("DROP INDEX #{index} ON #{tn}")
134
+ end
135
+ end
136
+
137
+ # Drop tables
138
+ executeSQL("DROP TABLE #{namespace_binds}")
139
+ executeSQL("DROP TABLE #{quoted_table}")
140
+ executeSQL("DROP TABLE #{literal_table}")
141
+ executeSQL("DROP TABLE #{asserted_type_table}")
142
+ executeSQL("DROP TABLE #{asserted_table}")
143
+ end
144
+
145
+ # Destroy database
88
146
  #
89
147
  # @option options[String] :path Path to database file defaults to a file in the current directory based on a hash of the store identifier
90
148
  def destroy(options = {})
@@ -171,6 +229,7 @@ module RdfContext
171
229
  if block_given?
172
230
  @db.execute(@statement_cache[qStr], *params) do |row|
173
231
  puts "executeSQL res: #{row.inspect}" if ::RdfContext::debug?
232
+ row = row.keys.select{|k| k.is_a?(Integer)}.sort.map{|k| row[k]} if row.is_a?(Hash)
174
233
  yield(row)
175
234
  end
176
235
  else
@@ -222,5 +281,10 @@ module RdfContext
222
281
  uri text,
223
282
  PRIMARY KEY (prefix)))
224
283
 
284
+ DROP_ASSERTED_STATEMENTS_TABLE = %(DROP TABLE %s_asserted_statements)
285
+ DROP_ASSERTED_TYPE_STATEMENTS_TABLE = %(DROP TABLE %s_type_statements)
286
+ DROP_LITERAL_STATEMENTS_TABLE = %(DROP TABLE %s_literal_statements)
287
+ DROP_QUOTED_STATEMENTS_TABLE = %(DROP TABLE %s_quoted_statements)
288
+ DROP_NS_BINDS_TABLE = %(DROP TABLE %s_namespace_binds)
225
289
  end
226
290
  end