rdf-sparql 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +0 -0
- data/UNLICENSE +25 -0
- data/VERSION +1 -0
- data/lib/lib/common.rb +106 -0
- data/lib/lib/extensions/variable.rb +69 -0
- data/lib/lib/format.rb +11 -0
- data/lib/lib/reader.rb +291 -0
- data/lib/lib/version.rb +25 -0
- data/lib/lib/writer.rb +250 -0
- data/lib/rdf-sparql.rb +13 -0
- metadata +98 -0
data/README.rdoc
ADDED
File without changes
|
data/UNLICENSE
ADDED
@@ -0,0 +1,25 @@
|
|
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, contact Alex Serebryakov [serebryakov@gmail.com]
|
25
|
+
or visit <http://unlicense.org/>
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.2
|
data/lib/lib/common.rb
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
module RDF
|
2
|
+
module SPARQL
|
3
|
+
module Common
|
4
|
+
|
5
|
+
##
|
6
|
+
# Yields each statement of SPARQL query
|
7
|
+
# @yield [statement]
|
8
|
+
# @yieldparam [Statement]
|
9
|
+
# @return [Reader]
|
10
|
+
##
|
11
|
+
def each_statement(&block)
|
12
|
+
@graph.each_statement { |statement| block.call(statement) }
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Yields each triple of SPARQL query
|
18
|
+
# @yield [triple]
|
19
|
+
# @yieldparam [Array(Value)]
|
20
|
+
# @return [Reader]
|
21
|
+
##
|
22
|
+
def each_triple(&block)
|
23
|
+
@graph.each_triple { |*triple| block.call(*triple) }
|
24
|
+
self
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Yields each target variable in SPARQL query
|
29
|
+
# @yield [variable]
|
30
|
+
# @yieldparam [Variable]
|
31
|
+
# @return [Reader]
|
32
|
+
##
|
33
|
+
def each_target(&block)
|
34
|
+
@targets.each { |target| block.call(target) }
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Yields each variable in SPARQL query
|
40
|
+
# @yield [variable]
|
41
|
+
# @yieldparam [Variable]
|
42
|
+
# @return [Reader]
|
43
|
+
##
|
44
|
+
def each_variable(&block)
|
45
|
+
variables.each { |variable| block.call(variable) }
|
46
|
+
self
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# [-]
|
51
|
+
##
|
52
|
+
def targets
|
53
|
+
@targets
|
54
|
+
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# [-]
|
58
|
+
##
|
59
|
+
def statements
|
60
|
+
@graph.statements
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# [-]
|
65
|
+
##
|
66
|
+
def triples
|
67
|
+
@graph.triples
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# [-]
|
72
|
+
##
|
73
|
+
def variables
|
74
|
+
Hash[@graph.map { |pattern|
|
75
|
+
pattern.variables.values
|
76
|
+
}.flatten.uniq.map { |variable|
|
77
|
+
[variable.name, variable]
|
78
|
+
}]
|
79
|
+
end
|
80
|
+
|
81
|
+
##
|
82
|
+
# [-]
|
83
|
+
##
|
84
|
+
def type
|
85
|
+
@type || @options[:type]
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Check whether `distinct` flag was specified
|
90
|
+
# @return [Boolean]
|
91
|
+
##
|
92
|
+
def distinct?
|
93
|
+
@options[:distinct] == true
|
94
|
+
end
|
95
|
+
|
96
|
+
##
|
97
|
+
# Check whether `reduced` flag was specified
|
98
|
+
# @return [Boolean]
|
99
|
+
##
|
100
|
+
def reduced?
|
101
|
+
@options[:reduced] == true
|
102
|
+
end
|
103
|
+
|
104
|
+
end # Common
|
105
|
+
end # SPARQL
|
106
|
+
end # RDF
|
@@ -0,0 +1,69 @@
|
|
1
|
+
class RDF::Query
|
2
|
+
class Variable
|
3
|
+
|
4
|
+
attr_reader :modifier
|
5
|
+
|
6
|
+
def initialize(name = nil, value = nil)
|
7
|
+
name = 'v%s' % rand(100000) if name.nil?
|
8
|
+
@name, @values = name.to_sym, []
|
9
|
+
@strict = true
|
10
|
+
bind(value) unless value.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def unbound?
|
14
|
+
@values.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def literal?
|
18
|
+
value.class == String && values.length == 1 && modifier == "="
|
19
|
+
end
|
20
|
+
|
21
|
+
def value
|
22
|
+
@values.first.nil? ? nil : @values.first.last
|
23
|
+
end
|
24
|
+
|
25
|
+
def values
|
26
|
+
@values.dup
|
27
|
+
end
|
28
|
+
|
29
|
+
def bind(value, modifier = "=", strict = true)
|
30
|
+
value = if value.respond_to?(:object)
|
31
|
+
value.object
|
32
|
+
else
|
33
|
+
value
|
34
|
+
end
|
35
|
+
|
36
|
+
@modifier = case modifier
|
37
|
+
when :eq then "="
|
38
|
+
when :nq then "!="
|
39
|
+
when :lt then "<"
|
40
|
+
when :lte then "<="
|
41
|
+
when :gt then ">"
|
42
|
+
when :gte then ">="
|
43
|
+
else modifier
|
44
|
+
end
|
45
|
+
|
46
|
+
@strict = strict
|
47
|
+
add(value, modifier)
|
48
|
+
end
|
49
|
+
|
50
|
+
def strict?
|
51
|
+
@strict
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_s
|
55
|
+
unbound? ? "?#{name}" : "#{name}#{modifier}#{value}"
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def add(value, modifier)
|
61
|
+
new_value = [modifier, value]
|
62
|
+
unless @values.include?(new_value)
|
63
|
+
@values << new_value
|
64
|
+
end
|
65
|
+
@values.last
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
data/lib/lib/format.rb
ADDED
data/lib/lib/reader.rb
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
module RDF::SPARQL
|
2
|
+
class Reader < RDF::Reader
|
3
|
+
|
4
|
+
include RDF::SPARQL::Common
|
5
|
+
format RDF::SPARQL::Format
|
6
|
+
|
7
|
+
##
|
8
|
+
# @param [IO, File, String] input
|
9
|
+
# @yield [reader]
|
10
|
+
# @yieldparam [Reader] reader
|
11
|
+
##
|
12
|
+
def initialize(input = $stdin, options = {}, &block)
|
13
|
+
@line = input.respond_to?(:read) ? input.read : input
|
14
|
+
@graph = RDF::Graph.new
|
15
|
+
@type = nil
|
16
|
+
@prefixes = {}
|
17
|
+
@variables = {}
|
18
|
+
@targets = []
|
19
|
+
@options = {}
|
20
|
+
read_query
|
21
|
+
block.call(self) if block_given?
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
|
27
|
+
##
|
28
|
+
# Reads prologue of SPARQL query (prefixes and targets)
|
29
|
+
##
|
30
|
+
def read_prologue
|
31
|
+
while (read_prefix || read_target); end
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Reads next `PREFIX`
|
36
|
+
##
|
37
|
+
def read_prefix
|
38
|
+
full, ns, uri = match(/\s*PREFIX\s+([a-z]+):\s+<([^>]+)>/)
|
39
|
+
full.nil? ? nil : add_prefix(ns, uri)
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Reads targets of SPARQL query
|
44
|
+
##
|
45
|
+
def read_target
|
46
|
+
read_select_target || read_describe_target || read_construct_target || read_ask_target
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Reads targets of a `SELECT` query
|
51
|
+
##
|
52
|
+
def read_select_target
|
53
|
+
full, flag = match(/\s*SELECT\s+(DISTINCT|REDUCED|)\s*/)
|
54
|
+
return nil if full.nil?
|
55
|
+
case flag
|
56
|
+
when 'DISTINCT' then @options[:distinct] = true
|
57
|
+
when 'REDUCED' then @options[:reduced] = true
|
58
|
+
end
|
59
|
+
@type = :select
|
60
|
+
while
|
61
|
+
var = read_variable
|
62
|
+
var.nil? ? break : add_target(var)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Reads targets of a `DESCRIBE` query
|
68
|
+
##
|
69
|
+
def read_describe_target
|
70
|
+
return nil if match(/\s*DESCRIBE\s+/).nil?
|
71
|
+
@type = :describe
|
72
|
+
while
|
73
|
+
var = (read_variable || read_uri)
|
74
|
+
var.nil? ? break : add_target(var)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Reads targets of a `CONSTRUCT` query
|
80
|
+
##
|
81
|
+
def read_construct_target
|
82
|
+
return nil
|
83
|
+
@type = :construct
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Reads targets of an `ASK` query
|
88
|
+
##
|
89
|
+
def read_ask_target
|
90
|
+
return nil
|
91
|
+
@type = :ask
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Reads all triples & filters of a query
|
96
|
+
##
|
97
|
+
def read_where
|
98
|
+
full = match(/(WHERE|)\s*\{/)
|
99
|
+
return nil if full.nil?
|
100
|
+
while (read_triple || read_filter); end
|
101
|
+
end
|
102
|
+
|
103
|
+
##
|
104
|
+
# Main parser loop: reads prologue, conditions and epilogue
|
105
|
+
##
|
106
|
+
def read_query #nodoc
|
107
|
+
while (read_prologue || read_where || read_epilogue); end
|
108
|
+
end
|
109
|
+
|
110
|
+
##
|
111
|
+
# Reads a triple
|
112
|
+
##
|
113
|
+
def read_triple
|
114
|
+
shortcut = read_triple_ending
|
115
|
+
@subject = (read_variable || read_uri) if shortcut == '.'
|
116
|
+
@predicate = (read_variable || read_uri) if shortcut != ','
|
117
|
+
@object = (read_variable || read_uri || read_literal)
|
118
|
+
return nil if @subject.nil?
|
119
|
+
add_triple(@subject, @predicate, @object)
|
120
|
+
end
|
121
|
+
|
122
|
+
##
|
123
|
+
# Finds any formatting shortcuts (a comma, a semicolon)
|
124
|
+
##
|
125
|
+
def read_triple_ending
|
126
|
+
full, symbol = match(/\s*([\.|,|;])\s*/)
|
127
|
+
full.nil? ? '.' : (symbol.empty? ? '.' : symbol)
|
128
|
+
end
|
129
|
+
|
130
|
+
##
|
131
|
+
# Reads a filter
|
132
|
+
##
|
133
|
+
def read_filter
|
134
|
+
full = match(/FILTER\s*\(\s*/)
|
135
|
+
return nil if full.nil?
|
136
|
+
while (read_filter_condition || read_filter_ending); end
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
# Reads next condition specified in a filter
|
141
|
+
##
|
142
|
+
def read_filter_condition
|
143
|
+
modifier = read_filter_modifier
|
144
|
+
variable = read_variable
|
145
|
+
comparison = read_comparison_operator
|
146
|
+
value = (read_variable || read_literal || read_numeric)
|
147
|
+
return nil if variable.nil?
|
148
|
+
variable.bind(value, comparison, (modifier != "||"))
|
149
|
+
end
|
150
|
+
|
151
|
+
##
|
152
|
+
# Returns filter modifier (|| or &&)
|
153
|
+
##
|
154
|
+
def read_filter_modifier
|
155
|
+
full, symbols = match(/\s*(\|{2}|&{2})+\s*/)
|
156
|
+
full.nil? ? nil : symbols
|
157
|
+
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# Moves pointer to the end of `FILTER` expression
|
161
|
+
##
|
162
|
+
def read_filter_ending
|
163
|
+
match(/\s*\)\s*/)
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Returns comparison operator (> < != =)
|
168
|
+
##
|
169
|
+
def read_comparison_operator
|
170
|
+
full, symbol = match(/\s*([!=|>|<|=])\s*/)
|
171
|
+
full.nil? ? nil : symbol
|
172
|
+
end
|
173
|
+
|
174
|
+
##
|
175
|
+
# Reads query epilogue (order, limit, group)
|
176
|
+
##
|
177
|
+
def read_epilogue
|
178
|
+
nil
|
179
|
+
end
|
180
|
+
|
181
|
+
##
|
182
|
+
# Reads next `PREFIX`
|
183
|
+
##
|
184
|
+
def read_prefix
|
185
|
+
full, ns, uri = match(/\s*PREFIX\s+([a-z]+):\s+<([^>]+)>/)
|
186
|
+
full.nil? ? nil : add_prefix(ns, uri)
|
187
|
+
end
|
188
|
+
|
189
|
+
##
|
190
|
+
# Reads an URI (as a full URI, namespaced or RDF type shortcut)
|
191
|
+
##
|
192
|
+
def read_uri
|
193
|
+
read_full_uri || read_type_shortcut || read_ns_uri
|
194
|
+
end
|
195
|
+
|
196
|
+
##
|
197
|
+
# Returns RDF.type if URI is an RDF type shortcut
|
198
|
+
##
|
199
|
+
def read_type_shortcut
|
200
|
+
full, symbol = match(/\s*(a)\s*/)
|
201
|
+
full.nil? ? nil : (symbol == 'a' ? RDF.type : nil)
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Returns URI if this is a non-abridged URI (no shortcuts or namespaces)
|
206
|
+
##
|
207
|
+
def read_full_uri
|
208
|
+
full, uri = match(/^<([^>]+)>/)
|
209
|
+
full.nil? ? nil : RDF::URI.new(uri)
|
210
|
+
end
|
211
|
+
|
212
|
+
##
|
213
|
+
# Returns URI that was namespaced in prefixes
|
214
|
+
##
|
215
|
+
def read_ns_uri
|
216
|
+
full, ns, uri = match(/([a-zA-Z]+):([a-zA-Z]+)/)
|
217
|
+
full.nil? ? nil : RDF::URI.new(@prefixes[ns].to_s + uri)
|
218
|
+
end
|
219
|
+
|
220
|
+
##
|
221
|
+
# Reads a variable
|
222
|
+
##
|
223
|
+
def read_variable
|
224
|
+
full, name = match(/\?([A-Za-z0-9_]+)\s*/)
|
225
|
+
full.nil? ? nil : add_variable(name)
|
226
|
+
end
|
227
|
+
|
228
|
+
##
|
229
|
+
# Reads a literal value
|
230
|
+
##
|
231
|
+
def read_literal
|
232
|
+
full, string = match(/\s*"([^"]*)"/)
|
233
|
+
return nil if full.nil?
|
234
|
+
full, language = match(/@([a-z]+[\-a-z0-9]*)/)
|
235
|
+
if language
|
236
|
+
RDF::Literal.new(string, :language => language)
|
237
|
+
elsif match(/(\^\^)/)
|
238
|
+
RDF::Literal.new(string, :datatype => read_uri)
|
239
|
+
else
|
240
|
+
RDF::Literal.new(string)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
##
|
245
|
+
# Reads a numeric value
|
246
|
+
##
|
247
|
+
def read_numeric
|
248
|
+
full = match(/\d+/)
|
249
|
+
full.nil? ? nil : full.first
|
250
|
+
end
|
251
|
+
|
252
|
+
##
|
253
|
+
# Registers a triple
|
254
|
+
##
|
255
|
+
def add_triple(subject, predicate, object)
|
256
|
+
@graph << RDF::Query::Pattern.new(subject, predicate, object)
|
257
|
+
end
|
258
|
+
|
259
|
+
##
|
260
|
+
# Registers a prefix
|
261
|
+
##
|
262
|
+
def add_prefix(ns, uri)
|
263
|
+
@prefixes[ns] = uri
|
264
|
+
end
|
265
|
+
|
266
|
+
##
|
267
|
+
# Registers a variable
|
268
|
+
##
|
269
|
+
def add_variable(name)
|
270
|
+
@variables[name] ||= RDF::Query::Variable.new(name)
|
271
|
+
end
|
272
|
+
|
273
|
+
##
|
274
|
+
# Registers a target
|
275
|
+
##
|
276
|
+
def add_target(var)
|
277
|
+
@targets << var
|
278
|
+
end
|
279
|
+
|
280
|
+
##
|
281
|
+
# Returns a match array
|
282
|
+
##
|
283
|
+
def match(pattern)
|
284
|
+
if (@line =~ pattern) == 0
|
285
|
+
@line = $'.lstrip
|
286
|
+
Regexp.last_match.to_a
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
end
|
data/lib/lib/version.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
module RDF
|
2
|
+
module SPARQL
|
3
|
+
module VERSION
|
4
|
+
MAJOR = 0
|
5
|
+
MINOR = 0
|
6
|
+
TINY = 2
|
7
|
+
EXTRA = nil
|
8
|
+
|
9
|
+
STRING = [MAJOR, MINOR, TINY].join('.')
|
10
|
+
STRING << "-#{EXTRA}" if EXTRA
|
11
|
+
|
12
|
+
##
|
13
|
+
# @return [String]
|
14
|
+
def self.to_s() STRING end
|
15
|
+
|
16
|
+
##
|
17
|
+
# @return [String]
|
18
|
+
def self.to_str() STRING end
|
19
|
+
|
20
|
+
##
|
21
|
+
# @return [Array(Integer, Integer, Integer)]
|
22
|
+
def self.to_a() [MAJOR, MINOR, TINY] end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/lib/writer.rb
ADDED
@@ -0,0 +1,250 @@
|
|
1
|
+
module RDF::SPARQL
|
2
|
+
class Writer < RDF::Writer
|
3
|
+
|
4
|
+
include RDF::SPARQL::Common
|
5
|
+
format RDF::SPARQL::Format
|
6
|
+
|
7
|
+
##
|
8
|
+
# @param [IO, File] output
|
9
|
+
# @yield [writer]
|
10
|
+
# @yieldparam [Writer] writer
|
11
|
+
##
|
12
|
+
def initialize(output = $stdout, options = {}, &block)
|
13
|
+
@output, @options = output, options
|
14
|
+
@graph = RDF::Graph.new
|
15
|
+
@targets = []
|
16
|
+
if block_given?
|
17
|
+
block.call(self)
|
18
|
+
write_query
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
##
|
24
|
+
# Stores the SPARQL representation of a triple.
|
25
|
+
#
|
26
|
+
# @param [RDF::Resource] subject
|
27
|
+
# @param [RDF::URI] predicate
|
28
|
+
# @param [RDF::Value] object
|
29
|
+
# @return [void]
|
30
|
+
##
|
31
|
+
def write_triple(subject, predicate, object)
|
32
|
+
@graph << RDF::Query::Pattern.new(subject, predicate, object)
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# @param [Array<Array(Value)>] triples
|
37
|
+
def write_triples(triples)
|
38
|
+
triples.each { |triple| write_triple(*triple) }
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
# [-]
|
43
|
+
##
|
44
|
+
def new_target(name_or_uri = nil)
|
45
|
+
@targets << case name_or_uri
|
46
|
+
when String then RDF::Query::Variable.new(name_or_uri)
|
47
|
+
when RDF::URI then name_or_uri
|
48
|
+
else RDF::Query::Variable.new('v%s' % rand(10000))
|
49
|
+
end
|
50
|
+
@targets.last
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# [-]
|
55
|
+
##
|
56
|
+
def write_query
|
57
|
+
puts format_prologue
|
58
|
+
puts format_where
|
59
|
+
puts write_epilogue
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
##
|
65
|
+
# [-]
|
66
|
+
##
|
67
|
+
def format_prologue
|
68
|
+
format_prefix
|
69
|
+
case type
|
70
|
+
when :select then write_select_target
|
71
|
+
when :describe then write_describe_target
|
72
|
+
when :construct then write_construct_target
|
73
|
+
when :ask then write_ask_target
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# [-]
|
79
|
+
##
|
80
|
+
def format_prefix
|
81
|
+
""
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# [-]
|
86
|
+
##
|
87
|
+
def write_select_target
|
88
|
+
"SELECT %s %s %s \n" % [
|
89
|
+
distinct? ? "DISTINCT" : "",
|
90
|
+
reduced? ? "REDUCED" : "",
|
91
|
+
write_targets ]
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# [-]
|
96
|
+
##
|
97
|
+
def write_describe_target
|
98
|
+
"DESCRIBE %s \n" % [
|
99
|
+
write_targets ]
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# [-]
|
104
|
+
##
|
105
|
+
def write_construct_target
|
106
|
+
raise NotImplementedError, '`CONSTRUCT` queries are not yet supported'
|
107
|
+
end
|
108
|
+
|
109
|
+
##
|
110
|
+
# [-]
|
111
|
+
##
|
112
|
+
def write_ask_target
|
113
|
+
raise NotImplementedError, '`ASK` queries are not yet supported'
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# [-]
|
118
|
+
##
|
119
|
+
def write_targets
|
120
|
+
@targets.map { |target| format_value(target) }.join(' ')
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# [-]
|
125
|
+
##
|
126
|
+
def format_where
|
127
|
+
"WHERE { %s %s }" % [
|
128
|
+
triples.map { |triple| format_triple(*triple) }.join("\n"),
|
129
|
+
variables.map { |variable| format_filter(variable) }.join("\n") ]
|
130
|
+
end
|
131
|
+
|
132
|
+
##
|
133
|
+
# [-]
|
134
|
+
##
|
135
|
+
def write_epilogue(options = {})
|
136
|
+
""
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
# Returns the SPARQL representation of a statement.
|
141
|
+
#
|
142
|
+
# @param [RDF::Statement] statement
|
143
|
+
# @return [String]
|
144
|
+
##
|
145
|
+
def format_statement(statement)
|
146
|
+
format_triple(*statement.to_triple)
|
147
|
+
end
|
148
|
+
|
149
|
+
##
|
150
|
+
# Returns the SPARQL representation of a triple.
|
151
|
+
#
|
152
|
+
# @param [RDF::Resource] subject
|
153
|
+
# @param [RDF::URI] predicate
|
154
|
+
# @param [RDF::Value] object
|
155
|
+
# @return [String]
|
156
|
+
##
|
157
|
+
def format_triple(subject, predicate, object)
|
158
|
+
"%s %s %s ." % [subject, predicate, object].map { |value| format_value(value) }
|
159
|
+
end
|
160
|
+
|
161
|
+
##
|
162
|
+
# Returns the SPARQL representation of a URI reference.
|
163
|
+
#
|
164
|
+
# @param [RDF::URI] literal
|
165
|
+
# @param [Hash{Symbol => Object}] options
|
166
|
+
# @return [String]
|
167
|
+
##
|
168
|
+
def format_uri(uri, options = {})
|
169
|
+
"<%s>" % uri_for(uri)
|
170
|
+
end
|
171
|
+
|
172
|
+
##
|
173
|
+
# Returns the SPARQL representation of a blank node.
|
174
|
+
#
|
175
|
+
# @param [RDF::Node] node
|
176
|
+
# @param [Hash{Symbol => Object}] options
|
177
|
+
# @return [String]
|
178
|
+
##
|
179
|
+
def format_node(node, options = {})
|
180
|
+
"_:%s" % node.id
|
181
|
+
end
|
182
|
+
|
183
|
+
##
|
184
|
+
# Returns the SPARQL representation of a variable.
|
185
|
+
#
|
186
|
+
# @param [RDF::Variable] node
|
187
|
+
# @param [Hash{Symbol => Object}] options
|
188
|
+
# @return [String]
|
189
|
+
##
|
190
|
+
def format_variable(variable, options = {})
|
191
|
+
if variable.literal?
|
192
|
+
'"%s"' % variable.value
|
193
|
+
else
|
194
|
+
"?%s" % variable.name
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
##
|
199
|
+
# Returns the N-Triples representation of a blank node.
|
200
|
+
#
|
201
|
+
# @param [RDF::Node] node
|
202
|
+
# @param [Hash{Symbol => Object}] options
|
203
|
+
# @return [String]
|
204
|
+
##
|
205
|
+
def format_filter(variable, options = {})
|
206
|
+
# "FILTER(%s %s %s)" % [format_variable(variable), variable.comparison, variable.value]
|
207
|
+
""
|
208
|
+
end
|
209
|
+
|
210
|
+
##
|
211
|
+
# @param [Value] value
|
212
|
+
# @return [String]
|
213
|
+
##
|
214
|
+
def format_value(value, options = {})
|
215
|
+
case value
|
216
|
+
when String
|
217
|
+
format_literal(value, options)
|
218
|
+
when RDF::Literal
|
219
|
+
format_literal(value, options)
|
220
|
+
when RDF::URI
|
221
|
+
format_uri(value, options)
|
222
|
+
when RDF::Node
|
223
|
+
format_node(value, options)
|
224
|
+
when RDF::Query::Variable
|
225
|
+
format_variable(value, options)
|
226
|
+
else nil
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
##
|
231
|
+
# Returns the N-Triples representation of a literal.
|
232
|
+
#
|
233
|
+
# @param [RDF::Literal, String, #to_s] literal
|
234
|
+
# @param [Hash{Symbol => Object}] options
|
235
|
+
# @return [String]
|
236
|
+
##
|
237
|
+
def format_literal(literal, options = {})
|
238
|
+
case literal
|
239
|
+
when RDF::Literal
|
240
|
+
text = quoted(escaped(literal.value))
|
241
|
+
text << "@#{literal.language}" if literal.has_language?
|
242
|
+
text << "^^<#{uri_for(literal.datatype)}>" if literal.has_datatype?
|
243
|
+
text
|
244
|
+
else
|
245
|
+
quoted(escaped(literal.to_s))
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
end
|
data/lib/rdf-sparql.rb
ADDED
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rdf-sparql
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: 0.0.2
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Alex Serebryakov
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-05-26 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 3
|
30
|
+
- 0
|
31
|
+
version: 1.3.0
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rdf
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 1
|
44
|
+
- 1
|
45
|
+
version: 0.1.1
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
description: RDF.rb plugin for parsing / writing SPARQL queries
|
49
|
+
email: serebryakov@gmail.com
|
50
|
+
executables: []
|
51
|
+
|
52
|
+
extensions: []
|
53
|
+
|
54
|
+
extra_rdoc_files: []
|
55
|
+
|
56
|
+
files:
|
57
|
+
- README.rdoc
|
58
|
+
- UNLICENSE
|
59
|
+
- VERSION
|
60
|
+
- lib/lib/common.rb
|
61
|
+
- lib/lib/extensions/variable.rb
|
62
|
+
- lib/lib/format.rb
|
63
|
+
- lib/lib/reader.rb
|
64
|
+
- lib/lib/version.rb
|
65
|
+
- lib/lib/writer.rb
|
66
|
+
- lib/rdf-sparql.rb
|
67
|
+
has_rdoc: true
|
68
|
+
homepage: http://github.com/42cities/rdf-sparql/
|
69
|
+
licenses: []
|
70
|
+
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
requirements: []
|
91
|
+
|
92
|
+
rubyforge_project: rdf-sparql
|
93
|
+
rubygems_version: 1.3.6
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: RDF.rb plugin for parsing / writing SPARQL queries
|
97
|
+
test_files: []
|
98
|
+
|