rdf-sparql 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.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
|
+
|