rdf-4store 0.0.1

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/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ Fumihiro Kato <fumi@fumi.me>
data/README ADDED
@@ -0,0 +1,43 @@
1
+ # 4store Storage Adapter for RDF.rb
2
+
3
+ This is an [RDF.rb][] storage adapter that allows you to use the [4store][] RDF Database.
4
+
5
+ See <http://blog.datagraph.org/2010/04/rdf-repository-howto> for an overview.
6
+
7
+ ## Status
8
+
9
+ This is still in alpha status, don't use in production environment.
10
+
11
+ ## Requirements
12
+
13
+ This plugin depends on the unsafe mode of 4s-httpd.
14
+
15
+ $ 4s-backend demo
16
+ $ 4s-httpd -U -s -1 demo
17
+
18
+ ## Resources
19
+
20
+ * <http://rdf.rubyforge.org> - RDF.rb's home page
21
+ * <http://rdf.rubyforge.org/RDF/Repository.html> - RDF.rb's Repository documentation
22
+ * <http://4store.org> - 4store's home page
23
+ * <http://github.com/fumi/rdf-4store>
24
+
25
+ ### Support
26
+
27
+ Please post questions or feedback to the [W3C-ruby-rdf mailing list][].
28
+
29
+ ### Author
30
+
31
+ * Fumihiro Kato <fumi@fumi.me> | <http://github.com/fumi> | <http://fumi.me>
32
+
33
+ ### 'License'
34
+
35
+ This is free and unemcumbered software released into the public domain. For
36
+ more information, see the accompanying UNLICENSE file.
37
+
38
+ If you're unfamiliar with public domain, that means it's perfectly fine to
39
+ start with this skeleton and code away, later relicensing as you see fit.
40
+
41
+ [RDF.rb]: http://rdf.rubyforge.org/
42
+ [4store]: http://4store.org/
43
+ [W3C-ruby-rdf mailing list]: http://lists.w3.org/Archives/Public/public-rdf-ruby/
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,9 @@
1
+ require 'rdf'
2
+
3
+ module RDF
4
+ module FourStore
5
+ autoload :Repository, 'rdf/four_store/repository'
6
+ autoload :VERSION, 'rdf/four_store/version'
7
+ end
8
+ end
9
+
@@ -0,0 +1,296 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'open-uri'
4
+ require 'enumerator'
5
+ require 'rdf'
6
+ require 'sparql/client'
7
+ require 'nokogiri'
8
+
9
+ module RDF::FourStore
10
+
11
+ ##
12
+ # RDF::Repository backend for 4store
13
+ #
14
+ # @see http://4store.org
15
+ # @see
16
+ class Repository < ::SPARQL::Client::Repository
17
+
18
+ attr_reader :endpointURI, :dataURI, :updateURI, :statusURI, :sizeURI
19
+
20
+ DEFAULT_CONTEXT = "local:".freeze
21
+
22
+ ##
23
+ # Constructor of RDF::FourStore::Repository
24
+ #
25
+ # @param [String] uri
26
+ # @param [Hash] options
27
+ # @return [RDF::FourStore::Repository]
28
+ # @example
29
+ # RDF::FourStore::Respository.new('http://localhost:8080')
30
+ #
31
+ def initialize(uri_or_options = {})
32
+ case uri_or_options
33
+ when String
34
+ @options = {}
35
+ @uri = uri_or_options.to_s
36
+ when Hash
37
+ @options = uri_or_options.dup
38
+ @uri = @options.delete([:uri])
39
+ else
40
+ raise ArgumentError, "expected String or Hash, but got #{uri_or_options.inspect}"
41
+ end
42
+ @uri.sub!(/\/$/, '')
43
+ @endpointURI = @uri + "/sparql/"
44
+ @dataURI = @uri + "/data/"
45
+ @updateURI = @uri + "/update/"
46
+ @statusURI = @uri + "/status/"
47
+ @sizeURI = @statusURI + "size/"
48
+
49
+ super(@endpointURI, options)
50
+ end
51
+
52
+ ##
53
+ # Loads RDF statements from the given file or URL into `self`.
54
+ #
55
+ # @see RDF::Mutable#load
56
+ # @param [String, #to_s] filename
57
+ # @param [Hash{Symbol => Object}] options
58
+ # @return [void]
59
+ def load(filename, options = {})
60
+ return super(filename, options) if /^https?:\/\//.match(filename)
61
+
62
+ uri = nil
63
+
64
+ if options[:context]
65
+ uri = @dataURI + options[:context]
66
+ else
67
+ uri = @dataURI + 'file://' + File.expand_path(filename)
68
+ end
69
+
70
+ uri = URI.parse(uri)
71
+ content = open(filename).read
72
+ begin
73
+ req = Net::HTTP::Put.new(uri.path)
74
+ Net::HTTP.start(uri.host, uri.port) do |http|
75
+ http.request(req, content)
76
+ end
77
+ rescue Errno::ECONNREFUSED, Errno::ECONNRESET, TimeoutError
78
+ retry
79
+ end
80
+ end
81
+
82
+ alias_method :load!, :load
83
+
84
+ ##
85
+ # Returns the number of statements in this repository.
86
+ # @see RDF::Repository#count
87
+ # @return [Integer]
88
+ def count
89
+ c = 0
90
+ doc = Nokogiri::HTML(open(@sizeURI))
91
+ doc.search('tr').each do |tr|
92
+ td = tr.search('td')
93
+ c = td[0].content if td[0]
94
+ end
95
+ c.to_i # the last one is the total number
96
+ end
97
+ alias_method :size, :count
98
+ alias_method :length, :count
99
+
100
+ ##
101
+ # Enumerates each RDF statement in this repository.
102
+ #
103
+ # @yield [statement]
104
+ # @yieldparam [RDF::Statement] statement
105
+ # @return [Enumerator]
106
+ # @see RDF::Repository#each
107
+ # @see SPARQL::Client::Rpository#each
108
+ def each(&block)
109
+ unless block_given?
110
+ RDF::Enumerator.new(self, :each)
111
+ else
112
+ # TODO: check why @client.construct does not work here.
113
+ statements = @client.query("CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }")
114
+ statements.each_statement(&block) if statements
115
+ end
116
+ end
117
+
118
+ ##
119
+ # @private
120
+ # @see RDF::Enumerable#has_triple?
121
+ def has_triple?(triple)
122
+ has_statement?(RDF::Statement.from(triple))
123
+ end
124
+
125
+ ##
126
+ # @private
127
+ # @see RDF::Enumerable#has_quad?
128
+ def has_quad?(quad)
129
+ has_statement?(RDF::Statement.new(quad[0], quad[1], quad[2], :context => quad[3]))
130
+ end
131
+
132
+ ##
133
+ # @private
134
+ # @see RDF::Enumerable#has_statement?
135
+ def has_statement?(statement)
136
+ context = statement.context
137
+ dump = dump_statement(statement)
138
+ if context
139
+ @client.query("ASK { GRAPH <#{context}> { #{dump} } } ")
140
+ else
141
+ @client.query("ASK { #{dump} } ")
142
+ end
143
+ end
144
+
145
+ ##
146
+ # @see RDF::Mutable#insert_statement
147
+ # @private
148
+ def insert_statement(statement)
149
+ #TODO: save the given RDF::Statement. Don't save duplicates.
150
+ #
151
+ #unless has_statement?(statement)
152
+ dump = dump_statement(statement)
153
+ post_data(dump, statement.context)
154
+ #end
155
+ end
156
+
157
+ ##
158
+ # @see RDF::Mutable#delete_statement
159
+ # @private
160
+ def delete_statement(statement)
161
+ if has_statement?(statement)
162
+ context = statement.context || DEFAULT_CONTEXT
163
+ dump = dump_statement(statement)
164
+ q = "DELETE DATA { GRAPH <#{context}> { #{dump} } }"
165
+ post_update(q, context)
166
+ end
167
+ end
168
+
169
+ ##
170
+ # @private
171
+ # @see RDF::Mutable#clear
172
+ def clear_statements
173
+ q = "SELECT ?g WHERE { GRAPH ?g { ?s ?p ?o . } FILTER (?g != <#{DEFAULT_CONTEXT}>) }"
174
+ @client.query(q).each do |solution|
175
+ post_update("CLEAR GRAPH <#{solution[:g]}>")
176
+ end
177
+ post_update("CLEAR GRAPH <#{DEFAULT_CONTEXT}>")
178
+ end
179
+
180
+ ##
181
+ # Queries `self` for RDF statements matching the given `pattern`.
182
+ #
183
+ # @param [Query, Statement, Array(Value), Hash] pattern
184
+ # @yield [statement]
185
+ # @yieldparam [Statement]
186
+ # @return [Enumerable<Statement>]
187
+ def query(pattern, &block)
188
+ case pattern
189
+ when RDF::Statement
190
+ h = {
191
+ :subject => pattern.subject || :s,
192
+ :predicate => pattern.predicate || :p,
193
+ :object => pattern.object || :o,
194
+ :context => pattern.context || nil
195
+ }
196
+ super(RDF::Query::Pattern.new(h), &block)
197
+ when Array
198
+ h = {
199
+ :subject => pattern[0] || :s,
200
+ :predicate => pattern[1] || :p,
201
+ :object => pattern[2] || :o,
202
+ :context => pattern[3] || nil
203
+ }
204
+ super(RDF::Query::Pattern.new(h), &block)
205
+ when Hash
206
+ pattern[:subject] ||= :s
207
+ pattern[:predicate] ||= :p
208
+ pattern[:object] ||= :o
209
+ super(RDF::Query::Pattern.new(pattern), &block)
210
+ else
211
+ super(pattern, &block)
212
+ end
213
+ end
214
+
215
+ def query_pattern(pattern, &block)
216
+ context = pattern.context || DEFAULT_CONTEXT
217
+ str = pattern.to_s
218
+ q = "CONSTRUCT { #{str} } WHERE { GRAPH <#{context}> { #{str} } } "
219
+ result = @client.query(q)
220
+ if result
221
+ if block_given?
222
+ result.each_statement(&block)
223
+ else
224
+ result
225
+ end
226
+ end
227
+ end
228
+
229
+ def dump_statement(statement)
230
+ dump_statements([statement])
231
+ end
232
+
233
+ def dump_statements(statements)
234
+ graph = RDF::Graph.new
235
+ graph.insert_statements(statements)
236
+ RDF::Writer.for(:ntriples).dump(graph)
237
+ end
238
+
239
+ def post_data(content, context = nil)
240
+ context ||= DEFAULT_CONTEXT
241
+ uri = URI.parse(@dataURI)
242
+
243
+ req = Net::HTTP::Post.new(uri.path)
244
+ req.form_data = {
245
+ 'data' => content,
246
+ 'graph' => context,
247
+ 'mime-type' => 'application/x-turtle'
248
+ }
249
+
250
+ Net::HTTP.start(uri.host, uri.port) do |http|
251
+ http.request(req)
252
+ end
253
+ end
254
+
255
+ def post_update(content, context = nil)
256
+ context ||= DEFAULT_CONTEXT
257
+ uri = URI.parse(@updateURI)
258
+
259
+ req = Net::HTTP::Post.new(uri.path)
260
+ req.form_data = {
261
+ 'update' => content,
262
+ 'graph' => context,
263
+ 'content-type' => 'triples',
264
+ }
265
+
266
+ Net::HTTP.start(uri.host, uri.port) do |http|
267
+ http.request(req)
268
+ end
269
+ end
270
+
271
+ ##
272
+ # @private
273
+ # @see RDF::Writable#writable?
274
+ # @return [Boolean]
275
+ def writable?
276
+ true
277
+ end
278
+
279
+ ##
280
+ # @private
281
+ # @see RDF::Durable#durable?
282
+ # @return [Boolean]
283
+ def durable?
284
+ true
285
+ end
286
+
287
+ ##
288
+ # @private
289
+ # @see RDF::Countable#empty?
290
+ # @return [Boolean]
291
+ def empty?
292
+ count.zero?
293
+ end
294
+
295
+ end
296
+ end
@@ -0,0 +1,23 @@
1
+ module RDF::FourStore
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 0
5
+ TINY = 1
6
+ EXTRA = nil
7
+
8
+ STRING = [MAJOR, MINOR, TINY].join('.')
9
+ STRING << ".#{EXTRA}" if EXTRA
10
+
11
+ ##
12
+ # @return [String]
13
+ def self.to_s() STRING end
14
+
15
+ ##
16
+ # @return [String]
17
+ def self.to_str() STRING end
18
+
19
+ ##
20
+ # @return [Array(Integer, Integer, Integer)]
21
+ def self.to_a() [MAJOR, MINOR, TINY] end
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,154 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rdf-4store
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Fumihiro Kato
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-15 00:00:00 +09:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rdf-spec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 0
32
+ - 2
33
+ - 0
34
+ version: 0.2.0
35
+ type: :development
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 27
46
+ segments:
47
+ - 1
48
+ - 3
49
+ - 0
50
+ version: 1.3.0
51
+ type: :development
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: rdf
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ hash: 19
62
+ segments:
63
+ - 0
64
+ - 2
65
+ - 2
66
+ version: 0.2.2
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ hash: 5
78
+ segments:
79
+ - 1
80
+ - 4
81
+ - 1
82
+ version: 1.4.1
83
+ type: :runtime
84
+ version_requirements: *id004
85
+ - !ruby/object:Gem::Dependency
86
+ name: sparql-client
87
+ prerelease: false
88
+ requirement: &id005 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 23
94
+ segments:
95
+ - 0
96
+ - 0
97
+ - 4
98
+ version: 0.0.4
99
+ type: :runtime
100
+ version_requirements: *id005
101
+ description: RDF.rb plugin providing 4store storage adapter.
102
+ email: fumi@fumi.me
103
+ executables: []
104
+
105
+ extensions: []
106
+
107
+ extra_rdoc_files: []
108
+
109
+ files:
110
+ - AUTHORS
111
+ - README
112
+ - UNLICENSE
113
+ - VERSION
114
+ - lib/rdf/4store.rb
115
+ - lib/rdf/four_store/repository.rb
116
+ - lib/rdf/four_store/version.rb
117
+ has_rdoc: true
118
+ homepage: http://github.com/fumi/rdf-4store
119
+ licenses:
120
+ - Public Domain
121
+ post_install_message:
122
+ rdoc_options: []
123
+
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ hash: 57
132
+ segments:
133
+ - 1
134
+ - 8
135
+ - 7
136
+ version: 1.8.7
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ none: false
139
+ requirements:
140
+ - - ">="
141
+ - !ruby/object:Gem::Version
142
+ hash: 3
143
+ segments:
144
+ - 0
145
+ version: "0"
146
+ requirements:
147
+ - 4store 1.0.3 or greater
148
+ rubyforge_project: rdf
149
+ rubygems_version: 1.3.7
150
+ signing_key:
151
+ specification_version: 3
152
+ summary: 4store adapter for RDF.rb.
153
+ test_files: []
154
+