sparql-client 0.0.1 → 0.0.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/README +40 -16
- data/VERSION +1 -1
- data/lib/sparql.rb +3 -1
- data/lib/sparql/client.rb +60 -9
- data/lib/sparql/client/query.rb +267 -0
- data/lib/sparql/client/repository.rb +170 -0
- data/lib/sparql/{version.rb → client/version.rb} +1 -1
- metadata +10 -8
data/README
CHANGED
@@ -8,43 +8,62 @@ This is a pure-Ruby implementation of a [SPARQL][] client for [RDF.rb][].
|
|
8
8
|
Features
|
9
9
|
--------
|
10
10
|
|
11
|
-
*
|
11
|
+
* Executes queries against any SPARQL 1.0-compatible endpoints over HTTP.
|
12
|
+
* Provides a query builder [DSL][] for `ASK`, `SELECT`, `DESCRIBE` and
|
13
|
+
`CONSTRUCT` queries.
|
14
|
+
* Supports tuple result sets in both XML and JSON formats, with JSON being
|
15
|
+
the preferred default for content negotiation purposes.
|
16
|
+
* Supports graph results in any RDF serialization format understood by RDF.rb.
|
17
|
+
* Returns results using the [RDF.rb object model][RDF.rb model].
|
18
|
+
* Supports accessing endpoints as read-only [`RDF::Repository`][RDF::Repository]
|
19
|
+
instances.
|
12
20
|
|
13
21
|
Examples
|
14
22
|
--------
|
15
23
|
|
16
24
|
require 'sparql/client'
|
17
25
|
|
18
|
-
sparql = SPARQL::Client.new(
|
26
|
+
sparql = SPARQL::Client.new("http://dbpedia.org/sparql")
|
19
27
|
|
20
|
-
### Executing a boolean query
|
28
|
+
### Executing a boolean query and outputting the result
|
21
29
|
|
22
|
-
|
30
|
+
# ASK WHERE { ?s ?p ?o }
|
31
|
+
result = sparql.ask.whether([:s, :p, :o]).true?
|
23
32
|
|
24
33
|
puts result.inspect #=> true or false
|
25
34
|
|
26
|
-
### Executing a tuple query
|
35
|
+
### Executing a tuple query and iterating over the returned solutions
|
27
36
|
|
28
|
-
|
37
|
+
# SELECT * WHERE { ?s ?p ?o } OFFSET 100 LIMIT 10
|
38
|
+
query = sparql.select.where([:s, :p, :o]).offset(100).limit(10)
|
29
39
|
|
30
|
-
|
31
|
-
puts
|
40
|
+
query.each_solution do |solution|
|
41
|
+
puts solution.inspect
|
32
42
|
end
|
33
43
|
|
34
|
-
### Executing a graph query
|
44
|
+
### Executing a graph query and iterating over the returned statements
|
35
45
|
|
36
|
-
|
46
|
+
# CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o } LIMIT 10
|
47
|
+
query = sparql.construct([:s, :p, :o]).where([:s, :p, :o]).limit(10)
|
37
48
|
|
38
|
-
|
49
|
+
query.each_statement do |statement|
|
39
50
|
puts statement.inspect
|
40
51
|
end
|
41
52
|
|
53
|
+
### Executing an arbitrary textual SPARQL query string
|
54
|
+
|
55
|
+
result = sparql.query("ASK WHERE { ?s ?p ?o }")
|
56
|
+
|
57
|
+
puts result.inspect #=> true or false
|
58
|
+
|
42
59
|
Documentation
|
43
60
|
-------------
|
44
61
|
|
45
|
-
<http://sparql.rubyforge.org/>
|
62
|
+
<http://sparql.rubyforge.org/client/>
|
46
63
|
|
47
64
|
* {SPARQL::Client}
|
65
|
+
* {SPARQL::Client::Query}
|
66
|
+
* {SPARQL::Client::Repository}
|
48
67
|
|
49
68
|
Dependencies
|
50
69
|
------------
|
@@ -75,7 +94,7 @@ as follows:
|
|
75
94
|
Resources
|
76
95
|
---------
|
77
96
|
|
78
|
-
* <http://sparql.rubyforge.org/>
|
97
|
+
* <http://sparql.rubyforge.org/client/>
|
79
98
|
* <http://github.com/bendiken/sparql-client>
|
80
99
|
* <http://rubygems.org/gems/sparql-client>
|
81
100
|
* <http://rubyforge.org/projects/sparql/>
|
@@ -94,6 +113,11 @@ License
|
|
94
113
|
`SPARQL::Client` is free and unencumbered public domain software. For more
|
95
114
|
information, see <http://unlicense.org/> or the accompanying UNLICENSE file.
|
96
115
|
|
97
|
-
[RDF]:
|
98
|
-
[SPARQL]:
|
99
|
-
[
|
116
|
+
[RDF]: http://www.w3.org/RDF/
|
117
|
+
[SPARQL]: http://en.wikipedia.org/wiki/SPARQL
|
118
|
+
[SPARQL JSON]: http://www.w3.org/TR/rdf-sparql-json-res/
|
119
|
+
[RDF.rb]: http://rdf.rubyforge.org/
|
120
|
+
[RDF.rb model]: http://blog.datagraph.org/2010/03/rdf-for-ruby
|
121
|
+
[RDF::Repository]: http://rdf.rubyforge.org/RDF/Repository.html
|
122
|
+
[DSL]: http://en.wikipedia.org/wiki/Domain-specific_language
|
123
|
+
"domain-specific language"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.2
|
data/lib/sparql.rb
CHANGED
data/lib/sparql/client.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'rdf'
|
3
3
|
require 'rdf/ntriples'
|
4
|
-
require 'sparql/version'
|
5
4
|
|
6
5
|
module SPARQL
|
7
6
|
##
|
8
7
|
# A SPARQL client for RDF.rb.
|
9
8
|
class Client
|
9
|
+
autoload :Query, 'sparql/client/query'
|
10
|
+
autoload :Repository, 'sparql/client/repository'
|
11
|
+
autoload :VERSION, 'sparql/client/version'
|
12
|
+
|
13
|
+
class ClientError < StandardError; end
|
14
|
+
class MalformedQuery < ClientError; end
|
15
|
+
class ServerError < StandardError; end
|
16
|
+
|
10
17
|
RESULT_BOOL = 'text/boolean'.freeze # Sesame-specific
|
11
18
|
RESULT_JSON = 'application/sparql-results+json'.freeze
|
12
19
|
RESULT_XML = 'application/sparql-results+xml'.freeze
|
@@ -21,7 +28,7 @@ module SPARQL
|
|
21
28
|
# @param [Hash{Symbol => Object}] options
|
22
29
|
def initialize(url, options = {}, &block)
|
23
30
|
@url, @options = RDF::URI.new(url.to_s), options
|
24
|
-
@headers = {'Accept' => "#{
|
31
|
+
@headers = {'Accept' => "#{RESULT_JSON}, #{RESULT_XML}, text/plain"}
|
25
32
|
|
26
33
|
if block_given?
|
27
34
|
case block.arity
|
@@ -31,19 +38,63 @@ module SPARQL
|
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
41
|
+
##
|
42
|
+
# Executes a boolean `ASK` query.
|
43
|
+
#
|
44
|
+
# @return [Query]
|
45
|
+
def ask(*args)
|
46
|
+
client = self
|
47
|
+
result = Query.ask(*args)
|
48
|
+
(class << result; self; end).send(:define_method, :execute) do
|
49
|
+
client.query(self)
|
50
|
+
end
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Executes a tuple `SELECT` query.
|
56
|
+
#
|
57
|
+
# @param [Array<Symbol>] variables
|
58
|
+
# @return [Query]
|
59
|
+
def select(*args)
|
60
|
+
client = self
|
61
|
+
result = Query.select(*args)
|
62
|
+
(class << result; self; end).send(:define_method, :execute) do
|
63
|
+
client.query(self)
|
64
|
+
end
|
65
|
+
result
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Executes a graph `CONSTRUCT` query.
|
70
|
+
#
|
71
|
+
# @param [Array<Symbol>] pattern
|
72
|
+
# @return [Query]
|
73
|
+
def construct(*args)
|
74
|
+
client = self
|
75
|
+
result = Query.construct(*args)
|
76
|
+
(class << result; self; end).send(:define_method, :execute) do
|
77
|
+
client.query(self)
|
78
|
+
end
|
79
|
+
result
|
80
|
+
end
|
81
|
+
|
34
82
|
##
|
35
83
|
# Executes a SPARQL query.
|
36
84
|
#
|
37
85
|
# @param [String, #to_s] url
|
38
86
|
# @param [Hash{Symbol => Object}] options
|
87
|
+
# @return [Array<RDF::Query::Solution>]
|
39
88
|
def query(query, options = {})
|
40
|
-
get(query
|
89
|
+
get(query) do |response|
|
41
90
|
case response
|
42
|
-
when Net::
|
43
|
-
|
44
|
-
when Net::
|
45
|
-
|
46
|
-
when Net::
|
91
|
+
when Net::HTTPBadRequest # 400 Bad Request
|
92
|
+
raise MalformedQuery.new(response.body)
|
93
|
+
when Net::HTTPClientError # 4xx
|
94
|
+
raise ClientError.new(response.body)
|
95
|
+
when Net::HTTPServerError # 5xx
|
96
|
+
raise ServerError.new(response.body)
|
97
|
+
when Net::HTTPSuccess # 2xx
|
47
98
|
parse_response(response)
|
48
99
|
end
|
49
100
|
end
|
@@ -79,7 +130,7 @@ module SPARQL
|
|
79
130
|
when json['results']
|
80
131
|
json['results']['bindings'].map do |row|
|
81
132
|
row = row.inject({}) do |cols, (name, value)|
|
82
|
-
cols.merge(name => parse_json_value(value))
|
133
|
+
cols.merge(name.to_sym => parse_json_value(value))
|
83
134
|
end
|
84
135
|
RDF::Query::Solution.new(row)
|
85
136
|
end
|
@@ -0,0 +1,267 @@
|
|
1
|
+
module SPARQL; class Client
|
2
|
+
##
|
3
|
+
# A SPARQL query builder.
|
4
|
+
#
|
5
|
+
# @example Iterating over all found solutions
|
6
|
+
# query.each_solution { |solution| puts solution.inspect }
|
7
|
+
#
|
8
|
+
class Query < RDF::Query
|
9
|
+
##
|
10
|
+
# @return [Symbol]
|
11
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#QueryForms
|
12
|
+
attr_reader :form
|
13
|
+
|
14
|
+
##
|
15
|
+
# @return [Hash{Symbol => Object}]
|
16
|
+
attr_reader :options
|
17
|
+
|
18
|
+
##
|
19
|
+
# Creates a boolean `ASK` query.
|
20
|
+
#
|
21
|
+
# @param [Hash{Symbol => Object}] options
|
22
|
+
# @return [Query]
|
23
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#ask
|
24
|
+
def self.ask(options = {})
|
25
|
+
self.new(:ask, options)
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Creates a tuple `SELECT` query.
|
30
|
+
#
|
31
|
+
# @param [Array<Symbol>] variables
|
32
|
+
# @param [Hash{Symbol => Object}] options
|
33
|
+
# @return [Query]
|
34
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#select
|
35
|
+
def self.select(*variables)
|
36
|
+
options = variables.last.is_a?(Hash) ? variables.pop : {}
|
37
|
+
self.new(:select, options).select(*variables) # FIXME
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Creates a graph `CONSTRUCT` query.
|
42
|
+
#
|
43
|
+
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
44
|
+
# @param [Hash{Symbol => Object}] options
|
45
|
+
# @return [Query]
|
46
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#construct
|
47
|
+
def self.construct(*patterns)
|
48
|
+
options = patterns.last.is_a?(Hash) ? patterns.pop : {}
|
49
|
+
self.new(:construct, options).construct(*patterns) # FIXME
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# @param [Symbol, #to_s] form
|
54
|
+
# @param [Hash{Symbol => Object}] options
|
55
|
+
# @yield [query]
|
56
|
+
# @yieldparam [Query]
|
57
|
+
def initialize(form = :ask, options = {}, &block)
|
58
|
+
@form = form.respond_to?(:to_sym) ? form.to_sym : form.to_s.to_sym
|
59
|
+
super(options.dup, &block)
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# @return [Query]
|
64
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#ask
|
65
|
+
def ask
|
66
|
+
@form = :ask
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# @param [Array<Symbol>] variables
|
72
|
+
# @param [Hash{Symbol => Object}] options
|
73
|
+
# @return [Query]
|
74
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#select
|
75
|
+
def select(*variables)
|
76
|
+
@form = :select
|
77
|
+
options = variables.last.is_a?(Hash) ? variables.pop : {}
|
78
|
+
@variables = variables.inject({}) do |vars, var|
|
79
|
+
vars.merge(var.to_sym => RDF::Query::Variable.new(var))
|
80
|
+
end
|
81
|
+
self
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
86
|
+
# @return [Query]
|
87
|
+
def construct(*patterns)
|
88
|
+
options[:template] = patterns.map do |pattern|
|
89
|
+
case pattern
|
90
|
+
when RDF::Query::Pattern then pattern
|
91
|
+
else RDF::Query::Pattern.new(*pattern.to_a)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
99
|
+
# @return [Query]
|
100
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#GraphPattern
|
101
|
+
def where(*patterns)
|
102
|
+
@patterns += patterns.map do |pattern|
|
103
|
+
case pattern
|
104
|
+
when RDF::Query::Pattern then pattern
|
105
|
+
else RDF::Query::Pattern.new(*pattern.to_a)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
self
|
109
|
+
end
|
110
|
+
|
111
|
+
alias_method :whether, :where
|
112
|
+
|
113
|
+
##
|
114
|
+
# @param [Array<Symbol>] variables
|
115
|
+
# @return [Query]
|
116
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#modOrderBy
|
117
|
+
def order(*variables)
|
118
|
+
options[:order_by] = variables
|
119
|
+
self
|
120
|
+
end
|
121
|
+
|
122
|
+
alias_method :order_by, :order
|
123
|
+
|
124
|
+
##
|
125
|
+
# @return [Query]
|
126
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#modDistinct
|
127
|
+
def distinct(state = true)
|
128
|
+
options[:distinct] = state
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# @return [Query]
|
134
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#modReduced
|
135
|
+
def reduced(state = true)
|
136
|
+
options[:reduced] = state
|
137
|
+
self
|
138
|
+
end
|
139
|
+
|
140
|
+
##
|
141
|
+
# @param [Integer, #to_i] start
|
142
|
+
# @return [Query]
|
143
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#modOffset
|
144
|
+
def offset(start)
|
145
|
+
slice(start, nil)
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# @param [Integer, #to_i] length
|
150
|
+
# @return [Query]
|
151
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#modResultLimit
|
152
|
+
def limit(length)
|
153
|
+
slice(nil, length)
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# @param [Integer, #to_i] start
|
158
|
+
# @param [Integer, #to_i] length
|
159
|
+
# @return [Query]
|
160
|
+
def slice(start, length)
|
161
|
+
options[:offset] = start.to_i if start
|
162
|
+
options[:limit] = length.to_i if length
|
163
|
+
self
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# @private
|
168
|
+
def filter(string)
|
169
|
+
(options[:filters] ||= []) << string
|
170
|
+
self
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# @return [Boolean]
|
175
|
+
def true?
|
176
|
+
case result
|
177
|
+
when TrueClass, FalseClass then result
|
178
|
+
when Enumerable then !result.empty?
|
179
|
+
else false
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# @return [Boolean]
|
185
|
+
def false?
|
186
|
+
!true?
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# @return [Enumerable<RDF::Query::Solution>]
|
191
|
+
def solutions
|
192
|
+
result
|
193
|
+
end
|
194
|
+
|
195
|
+
##
|
196
|
+
# @yield [statement]
|
197
|
+
# @yieldparam [RDF::Statement]
|
198
|
+
# @return [Enumerator]
|
199
|
+
def each_statement(&block)
|
200
|
+
result.each_statement(&block)
|
201
|
+
end
|
202
|
+
|
203
|
+
##
|
204
|
+
# @return [Object]
|
205
|
+
def result
|
206
|
+
@result ||= execute
|
207
|
+
end
|
208
|
+
|
209
|
+
##
|
210
|
+
# @return [Object]
|
211
|
+
def execute
|
212
|
+
raise NotImplementedError
|
213
|
+
end
|
214
|
+
|
215
|
+
##
|
216
|
+
# Returns the string representation of this query.
|
217
|
+
#
|
218
|
+
# @return [String]
|
219
|
+
def to_s
|
220
|
+
buffer = [form.to_s.upcase]
|
221
|
+
case form
|
222
|
+
when :select
|
223
|
+
buffer << 'DISTINCT' if options[:distinct]
|
224
|
+
buffer << 'REDUCED' if options[:reduced]
|
225
|
+
buffer << (variables.empty? ? '*' : variables.values.map(&:to_s).join(' '))
|
226
|
+
when :construct
|
227
|
+
buffer << '{'
|
228
|
+
buffer += options[:template].map(&:to_s)
|
229
|
+
buffer << '}'
|
230
|
+
end
|
231
|
+
|
232
|
+
buffer << 'WHERE {'
|
233
|
+
buffer += patterns.map(&:to_s)
|
234
|
+
if options[:filters]
|
235
|
+
buffer += options[:filters].map { |filter| "FILTER(#{filter})" }
|
236
|
+
end
|
237
|
+
buffer << '}'
|
238
|
+
|
239
|
+
if options[:order_by]
|
240
|
+
buffer << 'ORDER BY'
|
241
|
+
buffer += options[:order_by].map { |var| "?#{var}" }
|
242
|
+
end
|
243
|
+
|
244
|
+
buffer << "OFFSET #{options[:offset]}" if options[:offset]
|
245
|
+
buffer << "LIMIT #{options[:limit]}" if options[:limit]
|
246
|
+
|
247
|
+
buffer.join(' ')
|
248
|
+
end
|
249
|
+
|
250
|
+
##
|
251
|
+
# Outputs a developer-friendly representation of this query to `stderr`.
|
252
|
+
#
|
253
|
+
# @return [void]
|
254
|
+
def inspect!
|
255
|
+
warn(inspect)
|
256
|
+
self
|
257
|
+
end
|
258
|
+
|
259
|
+
##
|
260
|
+
# Returns a developer-friendly representation of this query.
|
261
|
+
#
|
262
|
+
# @return [String]
|
263
|
+
def inspect
|
264
|
+
sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, to_s)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end; end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
module SPARQL; class Client
|
2
|
+
##
|
3
|
+
# A read-only repository view of a SPARQL endpoint.
|
4
|
+
#
|
5
|
+
# @see RDF::Repository
|
6
|
+
class Repository < ::RDF::Repository
|
7
|
+
# @return [SPARQL::Client]
|
8
|
+
attr_reader :client
|
9
|
+
|
10
|
+
##
|
11
|
+
# @param [String, #to_s] endpoint
|
12
|
+
# @param [Hash{Symbol => Object}] options
|
13
|
+
def initialize(endpoint, options = {})
|
14
|
+
@options = options.dup
|
15
|
+
@client = SPARQL::Client.new(endpoint, options)
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# Enumerates each RDF statement in this repository.
|
20
|
+
#
|
21
|
+
# @yield [statement]
|
22
|
+
# @yieldparam [RDF::Statement] statement
|
23
|
+
# @return [Enumerator]
|
24
|
+
# @see RDF::Repository#each
|
25
|
+
def each(&block)
|
26
|
+
unless block_given?
|
27
|
+
require 'enumerator' unless defined?(::Enumerable::Enumerator)
|
28
|
+
::Enumerable::Enumerator.new(self, :each)
|
29
|
+
else
|
30
|
+
client.construct([:s, :p, :o]).where([:s, :p, :o]).each_statement(&block)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Returns `true` if this repository contains the given subject.
|
36
|
+
#
|
37
|
+
# @param [RDF::Resource]
|
38
|
+
# @return [Boolean]
|
39
|
+
# @see RDF::Repository#has_subject?
|
40
|
+
def has_subject?(subject)
|
41
|
+
client.ask.whether([subject, :p, :o]).true?
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Returns `true` if this repository contains the given predicate.
|
46
|
+
#
|
47
|
+
# @param [RDF::URI]
|
48
|
+
# @return [Boolean]
|
49
|
+
# @see RDF::Repository#has_predicate?
|
50
|
+
def has_predicate?(predicate)
|
51
|
+
client.ask.whether([:s, predicate, :o]).true?
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Returns `true` if this repository contains the given object.
|
56
|
+
#
|
57
|
+
# @param [RDF::Value]
|
58
|
+
# @return [Boolean]
|
59
|
+
# @see RDF::Repository#has_object?
|
60
|
+
def has_object?(object)
|
61
|
+
client.ask.whether([:s, :p, object]).true?
|
62
|
+
end
|
63
|
+
|
64
|
+
##
|
65
|
+
# Iterates over each subject in this repository.
|
66
|
+
#
|
67
|
+
# @yield [subject]
|
68
|
+
# @yieldparam [RDF::Resource] subject
|
69
|
+
# @return [Enumerator]
|
70
|
+
# @see RDF::Repository#each_subject?
|
71
|
+
def each_subject(&block)
|
72
|
+
unless block_given?
|
73
|
+
require 'enumerator' unless defined?(::Enumerable::Enumerator)
|
74
|
+
::Enumerable::Enumerator.new(self, :each_subject)
|
75
|
+
else
|
76
|
+
client.select(:s, :distinct => true).where([:s, :p, :o]).each { |solution| block.call(solution[:s]) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Iterates over each predicate in this repository.
|
82
|
+
#
|
83
|
+
# @yield [predicate]
|
84
|
+
# @yieldparam [RDF::URI] predicate
|
85
|
+
# @return [Enumerator]
|
86
|
+
# @see RDF::Repository#each_predicate?
|
87
|
+
def each_predicate(&block)
|
88
|
+
unless block_given?
|
89
|
+
require 'enumerator' unless defined?(::Enumerable::Enumerator)
|
90
|
+
::Enumerable::Enumerator.new(self, :each_predicate)
|
91
|
+
else
|
92
|
+
client.select(:p, :distinct => true).where([:s, :p, :o]).each { |solution| block.call(solution[:p]) }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Iterates over each object in this repository.
|
98
|
+
#
|
99
|
+
# @yield [object]
|
100
|
+
# @yieldparam [RDF::Value] object
|
101
|
+
# @return [Enumerator]
|
102
|
+
# @see RDF::Repository#each_object?
|
103
|
+
def each_object(&block)
|
104
|
+
unless block_given?
|
105
|
+
require 'enumerator' unless defined?(::Enumerable::Enumerator)
|
106
|
+
::Enumerable::Enumerator.new(self, :each_object)
|
107
|
+
else
|
108
|
+
client.select(:o, :distinct => true).where([:s, :p, :o]).each { |solution| block.call(solution[:o]) }
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Returns `true` if this repository contains the given `triple`.
|
114
|
+
#
|
115
|
+
# @param [Array<RDF::Resource, RDF::URI, RDF::Value>] triple
|
116
|
+
# @return [Boolean]
|
117
|
+
# @see RDF::Repository#has_triple?
|
118
|
+
def has_triple?(triple)
|
119
|
+
client.ask.whether(triple.to_a[0...3]).true?
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Returns `true` if this repository contains the given `statement`.
|
124
|
+
#
|
125
|
+
# @param [RDF::Statement] statement
|
126
|
+
# @return [Boolean]
|
127
|
+
# @see RDF::Repository#has_statement?
|
128
|
+
def has_statement?(statement)
|
129
|
+
has_triple?(statement.to_triple)
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# Returns the number of statements in this repository.
|
134
|
+
#
|
135
|
+
# @return [Integer]
|
136
|
+
# @see RDF::Repository#count?
|
137
|
+
def count
|
138
|
+
begin
|
139
|
+
binding = client.query("SELECT COUNT(*) WHERE { ?s ?p ?o }").first.to_hash
|
140
|
+
binding[binding.keys.first].value.to_i
|
141
|
+
rescue SPARQL::Client::MalformedQuery => e
|
142
|
+
# SPARQL 1.0 does not include support for aggregate functions:
|
143
|
+
count = 0
|
144
|
+
each_statement { count += 1 } # TODO: optimize this
|
145
|
+
count
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
alias_method :size, :count
|
150
|
+
alias_method :length, :count
|
151
|
+
|
152
|
+
##
|
153
|
+
# Returns `true` if this repository contains no statements.
|
154
|
+
#
|
155
|
+
# @return [Boolean]
|
156
|
+
# @see RDF::Repository#empty?
|
157
|
+
def empty?
|
158
|
+
client.ask.whether([:s, :p, :o]).false?
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Returns `false` to indicate that this is a read-only repository.
|
163
|
+
#
|
164
|
+
# @return [Boolean]
|
165
|
+
# @see RDF::Mutable#mutable?
|
166
|
+
def writable?
|
167
|
+
false
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end; end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Arto Bendiken
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-04-
|
18
|
+
date: 2010-04-12 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -28,8 +28,8 @@ dependencies:
|
|
28
28
|
segments:
|
29
29
|
- 0
|
30
30
|
- 1
|
31
|
-
-
|
32
|
-
version: 0.1.
|
31
|
+
- 6
|
32
|
+
version: 0.1.6
|
33
33
|
type: :development
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
@@ -70,8 +70,8 @@ dependencies:
|
|
70
70
|
segments:
|
71
71
|
- 0
|
72
72
|
- 1
|
73
|
-
-
|
74
|
-
version: 0.1.
|
73
|
+
- 6
|
74
|
+
version: 0.1.6
|
75
75
|
type: :runtime
|
76
76
|
version_requirements: *id004
|
77
77
|
- !ruby/object:Gem::Dependency
|
@@ -101,8 +101,10 @@ files:
|
|
101
101
|
- README
|
102
102
|
- UNLICENSE
|
103
103
|
- VERSION
|
104
|
+
- lib/sparql/client/query.rb
|
105
|
+
- lib/sparql/client/repository.rb
|
106
|
+
- lib/sparql/client/version.rb
|
104
107
|
- lib/sparql/client.rb
|
105
|
-
- lib/sparql/version.rb
|
106
108
|
- lib/sparql.rb
|
107
109
|
has_rdoc: false
|
108
110
|
homepage: http://sparql.rubyforge.org/
|