sparql 3.0.1 → 3.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +188 -73
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/bin/sparql +44 -24
- data/lib/rack/sparql.rb +1 -1
- data/lib/rack/sparql/conneg.rb +3 -3
- data/lib/sinatra/sparql.rb +5 -5
- data/lib/sparql.rb +17 -16
- data/lib/sparql/algebra.rb +15 -23
- data/lib/sparql/algebra/aggregate.rb +4 -4
- data/lib/sparql/algebra/evaluatable.rb +2 -2
- data/lib/sparql/algebra/expression.rb +63 -40
- data/lib/sparql/algebra/extensions.rb +180 -33
- data/lib/sparql/algebra/operator.rb +37 -16
- data/lib/sparql/algebra/operator/abs.rb +2 -2
- data/lib/sparql/algebra/operator/add.rb +3 -3
- data/lib/sparql/algebra/operator/alt.rb +4 -4
- data/lib/sparql/algebra/operator/and.rb +7 -7
- data/lib/sparql/algebra/operator/asc.rb +3 -3
- data/lib/sparql/algebra/operator/ask.rb +4 -14
- data/lib/sparql/algebra/operator/avg.rb +6 -4
- data/lib/sparql/algebra/operator/base.rb +10 -10
- data/lib/sparql/algebra/operator/bgp.rb +1 -1
- data/lib/sparql/algebra/operator/bnode.rb +5 -5
- data/lib/sparql/algebra/operator/bound.rb +3 -3
- data/lib/sparql/algebra/operator/ceil.rb +2 -2
- data/lib/sparql/algebra/operator/clear.rb +3 -3
- data/lib/sparql/algebra/operator/coalesce.rb +3 -13
- data/lib/sparql/algebra/operator/compare.rb +8 -8
- data/lib/sparql/algebra/operator/concat.rb +4 -4
- data/lib/sparql/algebra/operator/construct.rb +4 -14
- data/lib/sparql/algebra/operator/contains.rb +2 -2
- data/lib/sparql/algebra/operator/copy.rb +3 -3
- data/lib/sparql/algebra/operator/count.rb +3 -3
- data/lib/sparql/algebra/operator/create.rb +3 -3
- data/lib/sparql/algebra/operator/dataset.rb +6 -17
- data/lib/sparql/algebra/operator/datatype.rb +1 -1
- data/lib/sparql/algebra/operator/day.rb +1 -1
- data/lib/sparql/algebra/operator/delete.rb +9 -7
- data/lib/sparql/algebra/operator/delete_data.rb +3 -3
- data/lib/sparql/algebra/operator/delete_where.rb +6 -6
- data/lib/sparql/algebra/operator/desc.rb +1 -1
- data/lib/sparql/algebra/operator/describe.rb +3 -13
- data/lib/sparql/algebra/operator/distinct.rb +4 -14
- data/lib/sparql/algebra/operator/divide.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +3 -3
- data/lib/sparql/algebra/operator/encode_for_uri.rb +3 -3
- data/lib/sparql/algebra/operator/equal.rb +2 -2
- data/lib/sparql/algebra/operator/exists.rb +5 -5
- data/lib/sparql/algebra/operator/exprlist.rb +3 -13
- data/lib/sparql/algebra/operator/extend.rb +19 -18
- data/lib/sparql/algebra/operator/filter.rb +6 -16
- data/lib/sparql/algebra/operator/floor.rb +2 -2
- data/lib/sparql/algebra/operator/graph.rb +6 -17
- data/lib/sparql/algebra/operator/greater_than.rb +5 -5
- data/lib/sparql/algebra/operator/greater_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/group.rb +25 -25
- data/lib/sparql/algebra/operator/group_concat.rb +6 -6
- data/lib/sparql/algebra/operator/hours.rb +1 -1
- data/lib/sparql/algebra/operator/if.rb +5 -15
- data/lib/sparql/algebra/operator/in.rb +4 -14
- data/lib/sparql/algebra/operator/insert.rb +7 -5
- data/lib/sparql/algebra/operator/insert_data.rb +3 -3
- data/lib/sparql/algebra/operator/iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_blank.rb +1 -1
- data/lib/sparql/algebra/operator/is_iri.rb +1 -1
- data/lib/sparql/algebra/operator/is_literal.rb +1 -1
- data/lib/sparql/algebra/operator/is_numeric.rb +1 -1
- data/lib/sparql/algebra/operator/join.rb +12 -10
- data/lib/sparql/algebra/operator/lang.rb +1 -1
- data/lib/sparql/algebra/operator/lang_matches.rb +3 -3
- data/lib/sparql/algebra/operator/lcase.rb +2 -2
- data/lib/sparql/algebra/operator/left_join.rb +15 -12
- data/lib/sparql/algebra/operator/less_than.rb +5 -5
- data/lib/sparql/algebra/operator/less_than_or_equal.rb +5 -5
- data/lib/sparql/algebra/operator/load.rb +3 -3
- data/lib/sparql/algebra/operator/max.rb +6 -4
- data/lib/sparql/algebra/operator/md5.rb +1 -1
- data/lib/sparql/algebra/operator/min.rb +6 -4
- data/lib/sparql/algebra/operator/minus.rb +12 -11
- data/lib/sparql/algebra/operator/minutes.rb +1 -1
- data/lib/sparql/algebra/operator/modify.rb +4 -4
- data/lib/sparql/algebra/operator/month.rb +1 -1
- data/lib/sparql/algebra/operator/move.rb +3 -3
- data/lib/sparql/algebra/operator/multiply.rb +1 -1
- data/lib/sparql/algebra/operator/negate.rb +1 -1
- data/lib/sparql/algebra/operator/not.rb +1 -1
- data/lib/sparql/algebra/operator/not_equal.rb +2 -2
- data/lib/sparql/algebra/operator/notexists.rb +4 -4
- data/lib/sparql/algebra/operator/notin.rb +4 -14
- data/lib/sparql/algebra/operator/notoneof.rb +5 -6
- data/lib/sparql/algebra/operator/now.rb +1 -1
- data/lib/sparql/algebra/operator/or.rb +7 -7
- data/lib/sparql/algebra/operator/order.rb +6 -16
- data/lib/sparql/algebra/operator/path.rb +6 -5
- data/lib/sparql/algebra/operator/path_opt.rb +16 -16
- data/lib/sparql/algebra/operator/path_plus.rb +8 -8
- data/lib/sparql/algebra/operator/path_star.rb +4 -4
- data/lib/sparql/algebra/operator/plus.rb +3 -3
- data/lib/sparql/algebra/operator/prefix.rb +10 -10
- data/lib/sparql/algebra/operator/project.rb +4 -14
- data/lib/sparql/algebra/operator/rand.rb +1 -1
- data/lib/sparql/algebra/operator/reduced.rb +4 -14
- data/lib/sparql/algebra/operator/regex.rb +6 -6
- data/lib/sparql/algebra/operator/replace.rb +4 -4
- data/lib/sparql/algebra/operator/reverse.rb +4 -4
- data/lib/sparql/algebra/operator/round.rb +2 -2
- data/lib/sparql/algebra/operator/same_term.rb +8 -5
- data/lib/sparql/algebra/operator/sample.rb +3 -3
- data/lib/sparql/algebra/operator/seconds.rb +1 -1
- data/lib/sparql/algebra/operator/seq.rb +5 -6
- data/lib/sparql/algebra/operator/sequence.rb +4 -4
- data/lib/sparql/algebra/operator/sha1.rb +1 -1
- data/lib/sparql/algebra/operator/sha256.rb +1 -1
- data/lib/sparql/algebra/operator/sha384.rb +1 -1
- data/lib/sparql/algebra/operator/sha512.rb +1 -1
- data/lib/sparql/algebra/operator/slice.rb +4 -14
- data/lib/sparql/algebra/operator/str.rb +1 -1
- data/lib/sparql/algebra/operator/strafter.rb +2 -2
- data/lib/sparql/algebra/operator/strbefore.rb +2 -2
- data/lib/sparql/algebra/operator/strdt.rb +2 -2
- data/lib/sparql/algebra/operator/strends.rb +2 -2
- data/lib/sparql/algebra/operator/strlang.rb +2 -2
- data/lib/sparql/algebra/operator/strlen.rb +2 -2
- data/lib/sparql/algebra/operator/strstarts.rb +2 -2
- data/lib/sparql/algebra/operator/struuid.rb +1 -1
- data/lib/sparql/algebra/operator/substr.rb +4 -4
- data/lib/sparql/algebra/operator/subtract.rb +1 -1
- data/lib/sparql/algebra/operator/sum.rb +6 -4
- data/lib/sparql/algebra/operator/table.rb +3 -3
- data/lib/sparql/algebra/operator/timezone.rb +1 -1
- data/lib/sparql/algebra/operator/tz.rb +1 -1
- data/lib/sparql/algebra/operator/ucase.rb +2 -2
- data/lib/sparql/algebra/operator/union.rb +9 -8
- data/lib/sparql/algebra/operator/update.rb +4 -4
- data/lib/sparql/algebra/operator/using.rb +4 -4
- data/lib/sparql/algebra/operator/uuid.rb +1 -1
- data/lib/sparql/algebra/operator/with.rb +7 -7
- data/lib/sparql/algebra/operator/year.rb +1 -1
- data/lib/sparql/algebra/query.rb +2 -2
- data/lib/sparql/algebra/update.rb +2 -2
- data/lib/sparql/algebra/version.rb +1 -1
- data/lib/sparql/extensions.rb +5 -5
- data/lib/sparql/grammar.rb +111 -11
- data/lib/sparql/grammar/meta.rb +2340 -907
- data/lib/sparql/grammar/parser11.rb +69 -69
- data/lib/sparql/grammar/terminals11.rb +2 -0
- data/lib/sparql/results.rb +73 -46
- data/lib/sparql/version.rb +1 -1
- metadata +38 -65
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7ddc77cee587255c81cfcb3cd9d05759a3c98398821e23a25c3111f71e9b44c9
|
4
|
+
data.tar.gz: 48290eb8ba7ab1539c73c2fc3477b4004b8a15c5f09624ef24de5e3fe692ab03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71b0e62c9d8d418e508befea92ca5723a24a0ccce9fcebf43f40ce7ee4a8299c81fdad5ae4302465defd04708abd04ef10c863ef1538f25c71c5a24ea45e826a
|
7
|
+
data.tar.gz: 6c1b568ed72dcdda4f68f613bcbf3de38512b8cde4b1c6b2a20d51370fb5bd4efce7dee766e3cfde64222853c52937890d5fcbeb48d4448a2694f0dce0729d0c
|
data/README.md
CHANGED
@@ -2,15 +2,14 @@
|
|
2
2
|
|
3
3
|
This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][].
|
4
4
|
|
5
|
-
[![Gem Version](https://badge.fury.io/rb/sparql.png)](
|
6
|
-
|
7
|
-
[![Build Status](https://travis-ci.org/ruby-rdf/sparql.png?branch=master)](http://travis-ci.org/ruby-rdf/sparql)
|
8
|
-
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/sparql.png)](https://badge.fury.io/rb/sparql)
|
6
|
+
[![Build Status](https://github.com/ruby-rdf/sparql/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/sparql/actions?query=workflow%3ACI)
|
9
7
|
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/sparql/badge.svg)](https://coveralls.io/r/ruby-rdf/sparql)
|
8
|
+
[![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)
|
10
9
|
|
11
10
|
## Features
|
12
11
|
|
13
|
-
* 100% free and unencumbered [public domain](
|
12
|
+
* 100% free and unencumbered [public domain](https://unlicense.org/) software.
|
14
13
|
* Complete [SPARQL 1.1 Query][] parsing and execution
|
15
14
|
* SPARQL results as [XML][SPARQL XML], [JSON][SPARQL JSON],
|
16
15
|
[CSV][SPARQL 1.1 Query Results CSV and TSV Formats],
|
@@ -27,6 +26,7 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][].
|
|
27
26
|
* Compatible with Ruby >= 2.2.2.
|
28
27
|
* Compatible with older Ruby versions with the help of the [Backports][] gem.
|
29
28
|
* Supports Unicode query strings both on all versions of Ruby.
|
29
|
+
* Provisional support for [SPARQL*][].
|
30
30
|
|
31
31
|
## Description
|
32
32
|
|
@@ -45,20 +45,20 @@ The {SPARQL} gem uses the [SPARQL 1.1 Query][] {file:etc/sparql11.html EBNF gram
|
|
45
45
|
|
46
46
|
The SPARQL gem now implements the following [SPARQL 1.1 Query][] operations:
|
47
47
|
|
48
|
-
* [Functions](
|
49
|
-
* [BIND](
|
50
|
-
* [GROUP BY](
|
51
|
-
* [Aggregates](
|
52
|
-
* [Subqueries](
|
53
|
-
* [Inline Data](
|
54
|
-
* [Inline Data](
|
55
|
-
* [Exists](
|
56
|
-
* [Negation](
|
57
|
-
* [Property Paths](
|
48
|
+
* [Functions](https://www.w3.org/TR/sparql11-query/#SparqlOps)
|
49
|
+
* [BIND](https://www.w3.org/TR/sparql11-query/#bind)
|
50
|
+
* [GROUP BY](https://www.w3.org/TR/sparql11-query/#groupby)
|
51
|
+
* [Aggregates](https://www.w3.org/TR/sparql11-query/#aggregates)
|
52
|
+
* [Subqueries](https://www.w3.org/TR/sparql11-query/#subqueries)
|
53
|
+
* [Inline Data](https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#inline-data)
|
54
|
+
* [Inline Data](https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#inline-data)
|
55
|
+
* [Exists](https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-filter-exists)
|
56
|
+
* [Negation](https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#negation)
|
57
|
+
* [Property Paths](https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#propertypaths)
|
58
58
|
|
59
59
|
The gem also includes the following [SPARQL 1.1 Update][] operations:
|
60
|
-
* [Graph Update](
|
61
|
-
* [Graph Management](
|
60
|
+
* [Graph Update](https://www.w3.org/TR/sparql11-update/#graphUpdate)
|
61
|
+
* [Graph Management](https://www.w3.org/TR/sparql11-update/#graphManagement)
|
62
62
|
|
63
63
|
Not supported:
|
64
64
|
|
@@ -70,15 +70,15 @@ Not supported:
|
|
70
70
|
either in this, or related gems.
|
71
71
|
|
72
72
|
### Updates for RDF 1.1
|
73
|
-
Starting with version 1.1.2, the SPARQL gem uses the 1.1 version of the [RDF.rb][], which adheres to [RDF 1.1 Concepts](
|
73
|
+
Starting with version 1.1.2, the SPARQL gem uses the 1.1 version of the [RDF.rb][], which adheres to [RDF 1.1 Concepts](https://www.w3.org/TR/rdf11-concepts/) rather than [RDF 1.0](https://www.w3.org/TR/rdf-concepts/). The main difference is that there is now no difference between a _Simple Literal_ (a literal with no datatype or language) and a Literal with datatype _xsd:string_; this causes some minor differences in the way in which queries are understood, and when expecting different results.
|
74
74
|
|
75
75
|
Additionally, queries now take a block, or return an `Enumerator`; this is in keeping with much of the behavior of [RDF.rb][] methods, including `Queryable#query`, and with version 1.1 or [RDF.rb][], Query#execute. As a consequence, all queries which used to be of the form `query.execute(repository)` may equally be called as `repository.query(query)`. Previously, results were returned as a concrete class implementing `RDF::Queryable` or `RDF::Query::Solutions`, these are now `Enumerators`.
|
76
76
|
|
77
77
|
### SPARQL Extension Functions
|
78
78
|
Extension functions may be defined, which will be invoked during query evaluation. For example:
|
79
79
|
|
80
|
-
# Register a function using the IRI <
|
81
|
-
crypt_iri = RDF::URI("
|
80
|
+
# Register a function using the IRI <https://rubygems#crypt>
|
81
|
+
crypt_iri = RDF::URI("https://rubygems#crypt")
|
82
82
|
SPARQL::Algebra::Expression.register_extension(crypt_iri) do |literal|
|
83
83
|
raise TypeError, "argument must be a literal" unless literal.literal?
|
84
84
|
RDF::Literal(literal.to_s.crypt)
|
@@ -86,7 +86,7 @@ Extension functions may be defined, which will be invoked during query evaluatio
|
|
86
86
|
|
87
87
|
Then, use the function in a query:
|
88
88
|
|
89
|
-
PREFIX rsp: <
|
89
|
+
PREFIX rsp: <https://rubygems#>
|
90
90
|
PREFIX schema: <http://schema.org/>
|
91
91
|
SELECT ?crypted
|
92
92
|
{
|
@@ -96,6 +96,117 @@ Then, use the function in a query:
|
|
96
96
|
|
97
97
|
See {SPARQL::Algebra::Expression.register_extension} for details.
|
98
98
|
|
99
|
+
### SPARQLStar (SPARQL*)
|
100
|
+
|
101
|
+
The gem supports [SPARQL*][] where patterns may include sub-patterns recursively, for a kind of Reification.
|
102
|
+
|
103
|
+
For example, the following Turtle* file uses a statement as the subject of another statement:
|
104
|
+
|
105
|
+
@prefix : <http://bigdata.com/> .
|
106
|
+
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
|
107
|
+
@prefix ex: <http://example.org/> .
|
108
|
+
|
109
|
+
:bob foaf:name "Bob" .
|
110
|
+
<<:bob foaf:age 23>> ex:certainty 0.9 .
|
111
|
+
|
112
|
+
This can be queried using the following query:
|
113
|
+
|
114
|
+
PREFIX : <http://bigdata.com/>
|
115
|
+
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
|
116
|
+
PREFIX ex: <http://example.org/>
|
117
|
+
|
118
|
+
SELECT ?age ?c WHERE {
|
119
|
+
?bob foaf:name "Bob" .
|
120
|
+
<<?bob foaf:age ?age>> ex:certainty ?c .
|
121
|
+
}
|
122
|
+
|
123
|
+
This treats `<<:bob foaf:age 23>>` as a subject resource, and the pattern `<<?bob foaf:age ?age>>` to match that resource and bind the associated variables.
|
124
|
+
|
125
|
+
**Note: This feature is subject to change or elimination as the standards process progresses.**
|
126
|
+
|
127
|
+
#### BIND
|
128
|
+
|
129
|
+
There is an alternate syntax using the `BIND` operator:
|
130
|
+
|
131
|
+
PREFIX : <http://bigdata.com>
|
132
|
+
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
|
133
|
+
PREFIX dct: <http://purl.org/dc/elements/1.1/>
|
134
|
+
|
135
|
+
SELECT ?a ?b ?c WHERE {
|
136
|
+
?bob foaf:name "Bob" .
|
137
|
+
BIND( <<?bob foaf:age ?age>> AS ?a ) .
|
138
|
+
?t ?b ?c .
|
139
|
+
}
|
140
|
+
|
141
|
+
When binding, the triple can be either in Property Graph (`:PG`) or Separate Assertions (`:SA`) mode, as the query matches based on the pattern matching as a subject (or object) and does not need to be specifically asserted in the graph. When parsing in Property Graph mode, such triples will also be added to the enclosing graph. Thus, querying for `<<?bob foaf:age ?age>>` and `?bob foaf:age ?age` may not represent the same results.
|
142
|
+
|
143
|
+
When binding an embedded triple to a variable, it is the matched triples which are bound, not the pattern. Thus, the example above with `SELECT ?a ?b ?c` would end up binding `?a` to `:bob foaf:name 23`.
|
144
|
+
|
145
|
+
#### Construct
|
146
|
+
|
147
|
+
As well as a `CONSTRUCT`:
|
148
|
+
|
149
|
+
PREFIX : <http://bigdata.com>
|
150
|
+
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
|
151
|
+
PREFIX dct: <http://purl.org/dc/elements/1.1/>
|
152
|
+
|
153
|
+
CONSTRUCT {
|
154
|
+
?bob foaf:name "Bob" .
|
155
|
+
<<?bob foaf:age ?age>> ?b ?c .
|
156
|
+
}
|
157
|
+
WHERE {
|
158
|
+
?bob foaf:name "Bob" .
|
159
|
+
<<?bob foaf:age ?age>> ?b ?c .
|
160
|
+
}
|
161
|
+
|
162
|
+
Note that results can be serialized only when the format supports [RDF*][].
|
163
|
+
|
164
|
+
#### SPARQL results
|
165
|
+
|
166
|
+
The SPARQL results formats are extended to serialize embedded triples as described for [RDF4J](https://rdf4j.org/documentation/programming/rdfstar/):
|
167
|
+
|
168
|
+
{
|
169
|
+
"head" : {
|
170
|
+
"vars" : [
|
171
|
+
"a",
|
172
|
+
"b",
|
173
|
+
"c"
|
174
|
+
]
|
175
|
+
},
|
176
|
+
"results" : {
|
177
|
+
"bindings": [
|
178
|
+
{ "a" : {
|
179
|
+
"type" : "triple",
|
180
|
+
"value" : {
|
181
|
+
"s" : {
|
182
|
+
"type" : "uri",
|
183
|
+
"value" : "http://example.org/bob"
|
184
|
+
},
|
185
|
+
"p" : {
|
186
|
+
"type" : "uri",
|
187
|
+
"value" : "http://xmlns.com/foaf/0.1/name"
|
188
|
+
},
|
189
|
+
"o" : {
|
190
|
+
"datatype" : "http://www.w3.org/2001/XMLSchema#integer",
|
191
|
+
"type" : "literal",
|
192
|
+
"value" : "23"
|
193
|
+
}
|
194
|
+
}
|
195
|
+
},
|
196
|
+
"b": {
|
197
|
+
"type": "uri",
|
198
|
+
"value": "http://example.org/certainty"
|
199
|
+
},
|
200
|
+
"c" : {
|
201
|
+
"datatype" : "http://www.w3.org/2001/XMLSchema#decimal",
|
202
|
+
"type" : "literal",
|
203
|
+
"value" : "0.9"
|
204
|
+
}
|
205
|
+
}
|
206
|
+
]
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
99
210
|
### Middleware
|
100
211
|
|
101
212
|
{Rack::SPARQL} is a superset of [Rack::LinkedData][] to allow content negotiated results
|
@@ -150,12 +261,12 @@ a full set of RDF formats.
|
|
150
261
|
result.inspect
|
151
262
|
end
|
152
263
|
|
153
|
-
### Updating a
|
264
|
+
### Updating a repository
|
154
265
|
|
155
266
|
queryable = RDF::Repository.load("etc/doap.ttl")
|
156
267
|
sse = SPARQL.parse(%(
|
157
268
|
PREFIX doap: <http://usefulinc.com/ns/doap#>
|
158
|
-
INSERT DATA { <
|
269
|
+
INSERT DATA { <https://rubygems> doap:implements <http://www.w3.org/TR/sparql11-update/>}
|
159
270
|
), update: true)
|
160
271
|
sse.execute(queryable)
|
161
272
|
|
@@ -257,14 +368,14 @@ Full documentation available on [Rubydoc.info][SPARQL doc]
|
|
257
368
|
|
258
369
|
## Dependencies
|
259
370
|
|
260
|
-
* [Ruby](
|
261
|
-
* [RDF.rb](
|
371
|
+
* [Ruby](https://ruby-lang.org/) (>= 2.2.2)
|
372
|
+
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.0)
|
262
373
|
* [SPARQL::Client](https://rubygems.org/gems/sparql-client) (~> 3.0)
|
263
374
|
* [SXP](https://rubygems.org/gems/sxp) (~> 1.0)
|
264
375
|
* [Builder](https://rubygems.org/gems/builder) (>= 3.0.0)
|
265
376
|
* [JSON](https://rubygems.org/gems/json) (>= 1.8.2)
|
266
377
|
* Soft dependency on [Linked Data][] (>= 3.0)
|
267
|
-
* Soft dependency on [Nokogiri](
|
378
|
+
* Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (>= 1.7)
|
268
379
|
Falls back to REXML for XML parsing Builder for XML serializing. Nokogiri is much more efficient
|
269
380
|
* Soft dependency on [Equivalent XML](https://rubygems.org/gems/equivalent-xml) (>= 0.3.0)
|
270
381
|
Equivalent XML performs more efficient comparisons of XML Literals when Nokogiri is included
|
@@ -273,7 +384,7 @@ Full documentation available on [Rubydoc.info][SPARQL doc]
|
|
273
384
|
|
274
385
|
## Installation
|
275
386
|
|
276
|
-
The recommended installation method is via [RubyGems](
|
387
|
+
The recommended installation method is via [RubyGems](https://rubygems.org/).
|
277
388
|
To install the latest official release of the `SPARQL` gem, do:
|
278
389
|
|
279
390
|
% [sudo] gem install sparql
|
@@ -286,13 +397,13 @@ To get a local working copy of the development repository, do:
|
|
286
397
|
|
287
398
|
## Mailing List
|
288
399
|
|
289
|
-
* <
|
400
|
+
* <https://lists.w3.org/Archives/Public/public-rdf-ruby/>
|
290
401
|
|
291
402
|
## Authors
|
292
403
|
|
293
|
-
* [Gregg Kellogg](
|
294
|
-
* [Arto Bendiken](
|
295
|
-
* [Pius Uzamere](
|
404
|
+
* [Gregg Kellogg](https://github.com/gkellogg) - <https://greggkellogg.net/>
|
405
|
+
* [Arto Bendiken](https://github.com/artob) - <https://ar.to/>
|
406
|
+
* [Pius Uzamere](https://github.com/pius) - <https://pius.me/>
|
296
407
|
|
297
408
|
## Contributing
|
298
409
|
This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange development and release activity. All submissions _must_ be on a feature branch based on the _develop_ branch to ease staging and integration.
|
@@ -307,54 +418,58 @@ This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange develo
|
|
307
418
|
list in the the `README`. Alphabetical order applies.
|
308
419
|
* Do note that in order for us to merge any non-trivial changes (as a rule
|
309
420
|
of thumb, additions larger than about 15 lines of code), we need an
|
310
|
-
explicit [public domain dedication][PDD] on record from you
|
421
|
+
explicit [public domain dedication][PDD] on record from you,
|
422
|
+
which you will be asked to agree to on the first commit to a repo within the organization.
|
423
|
+
Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization.
|
311
424
|
|
312
425
|
## License
|
313
426
|
|
314
427
|
This is free and unencumbered public domain software. For more information,
|
315
|
-
see <
|
428
|
+
see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
316
429
|
|
317
|
-
A copy of the [SPARQL EBNF][] and derived parser files are included in the repository, which are not covered under the UNLICENSE. These files are covered via the [W3C Document License](
|
430
|
+
A copy of the [SPARQL EBNF][] and derived parser files are included in the repository, which are not covered under the UNLICENSE. These files are covered via the [W3C Document License](https://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231).
|
318
431
|
|
319
432
|
A copy of the [SPARQL 1.0 tests][] and [SPARQL 1.1 tests][] are also included in the repository, which are not covered under the UNLICENSE; see the references for test copyright information.
|
320
433
|
|
321
|
-
[Ruby]:
|
322
|
-
[RDF]:
|
323
|
-
[RDF::DO]:
|
324
|
-
[RDF::Mongo]:
|
325
|
-
[Rack::LinkedData]:
|
326
|
-
[YARD]:
|
327
|
-
[YARD-GS]:
|
328
|
-
[PDD]:
|
329
|
-
[SPARQL]:
|
330
|
-
[SPARQL 1.0]:
|
331
|
-
[SPARQL 1.0 tests]:
|
332
|
-
[SPARQL 1.1 tests]:
|
333
|
-
[SSE]:
|
334
|
-
[SXP]:
|
335
|
-
[grammar]:
|
336
|
-
[RDF 1.1]:
|
337
|
-
[RDF.rb]:
|
338
|
-
[
|
339
|
-
[
|
340
|
-
[
|
341
|
-
[
|
342
|
-
[SPARQL
|
343
|
-
[SPARQL
|
344
|
-
|
345
|
-
[
|
346
|
-
|
347
|
-
[
|
348
|
-
[
|
349
|
-
|
350
|
-
[
|
351
|
-
|
352
|
-
[SPARQL 1.1
|
353
|
-
[SPARQL 1.1
|
354
|
-
[SPARQL 1.1
|
355
|
-
[SPARQL 1.1 Query
|
356
|
-
[SPARQL Query Results
|
357
|
-
[SPARQL 1.1
|
358
|
-
[SPARQL
|
359
|
-
[SPARQL 1.1
|
434
|
+
[Ruby]: https://ruby-lang.org/
|
435
|
+
[RDF]: https://www.w3.org/RDF/
|
436
|
+
[RDF::DO]: https://rubygems.org/gems/rdf-do
|
437
|
+
[RDF::Mongo]: https://rubygems.org/gems/rdf-mongo
|
438
|
+
[Rack::LinkedData]: https://rubygems.org/gems/rack-linkeddata
|
439
|
+
[YARD]: https://yardoc.org/
|
440
|
+
[YARD-GS]: https://rubydoc.info/docs/yard/file/docs/GettingStarted.md
|
441
|
+
[PDD]: https://unlicense.org/#unlicensing-contributions
|
442
|
+
[SPARQL]: https://en.wikipedia.org/wiki/SPARQL
|
443
|
+
[SPARQL 1.0]: https://www.w3.org/TR/sparql11-query/
|
444
|
+
[SPARQL 1.0 tests]:https://www.w3.org/2001/sw/DataAccess/tests/
|
445
|
+
[SPARQL 1.1 tests]: https://www.w3.org/2009/sparql/docs/tests/
|
446
|
+
[SSE]: https://jena.apache.org/documentation/notes/sse.html
|
447
|
+
[SXP]: https://www.rubydoc.info/github/dryruby/sxp
|
448
|
+
[grammar]: https://www.w3.org/TR/sparql11-query/#grammar
|
449
|
+
[RDF 1.1]: https://www.w3.org/TR/rdf11-concepts
|
450
|
+
[RDF.rb]: https://rubydoc.info/github/ruby-rdf/rdf
|
451
|
+
[RDF*]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html
|
452
|
+
[SPARQL*]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#sparql-query-language
|
453
|
+
[Backports]: https://rubygems.org/gems/backports
|
454
|
+
[Linked Data]: https://rubygems.org/gems/linkeddata
|
455
|
+
[SPARQL doc]: https://rubydoc.info/github/ruby-rdf/sparql/frames
|
456
|
+
[SPARQL XML]: https://www.w3.org/TR/rdf-sparql-XMLres/
|
457
|
+
[SPARQL JSON]: https://www.w3.org/TR/rdf-sparql-json-res/
|
458
|
+
[SPARQL EBNF]: https://www.w3.org/TR/sparql11-query/#sparqlGrammar
|
459
|
+
|
460
|
+
[SSD]: https://www.w3.org/TR/sparql11-service-description/
|
461
|
+
[Rack]: https://rack.github.io
|
462
|
+
[Sinatra]: https://www.sinatrarb.com/
|
463
|
+
[conneg]: https://en.wikipedia.org/wiki/Content_negotiation
|
464
|
+
|
465
|
+
[SPARQL 1.1 Query]: https://www.w3.org/TR/sparql11-query/
|
466
|
+
[SPARQL 1.1 Update]: https://www.w3.org/TR/sparql11-update/
|
467
|
+
[SPARQL 1.1 Service Description]: https://www.w3.org/TR/sparql11-service-description/
|
468
|
+
[SPARQL 1.1 Federated Query]: https://www.w3.org/TR/sparql11-federated-query/
|
469
|
+
[SPARQL 1.1 Query Results JSON Format]: https://www.w3.org/TR/sparql11-results-json/
|
470
|
+
[SPARQL 1.1 Query Results CSV and TSV Formats]: https://www.w3.org/TR/sparql11-results-csv-tsv/
|
471
|
+
[SPARQL Query Results XML Format]: https://www.w3.org/TR/rdf-sparql-XMLres/
|
472
|
+
[SPARQL 1.1 Entailment Regimes]: https://www.w3.org/TR/sparql11-entailment/
|
473
|
+
[SPARQL 1.1 Protocol]: https://www.w3.org/TR/sparql11-protocol/
|
474
|
+
[SPARQL 1.1 Graph Store HTTP Protocol]: https://www.w3.org/TR/sparql11-http-rdf-update/
|
360
475
|
|
data/UNLICENSE
CHANGED
@@ -21,4 +21,4 @@ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
21
21
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
22
22
|
OTHER DEALINGS IN THE SOFTWARE.
|
23
23
|
|
24
|
-
For more information, please refer to <
|
24
|
+
For more information, please refer to <https://unlicense.org/>
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.1.4
|
data/bin/sparql
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'rubygems'
|
3
|
-
$:.unshift(
|
3
|
+
$:.unshift("../../lib", __FILE__)
|
4
4
|
require 'sparql'
|
5
5
|
begin
|
6
6
|
require 'linkeddata'
|
@@ -9,16 +9,24 @@ rescue LoadError
|
|
9
9
|
end
|
10
10
|
require 'getoptlong'
|
11
11
|
|
12
|
-
def display_results(res, options)
|
12
|
+
def display_results(res, **options)
|
13
13
|
puts res.inspect if options[:verbose]
|
14
14
|
puts case res
|
15
|
-
when RDF::Graph then res.dump(:ttl, base_uri: query.base_uri, prefixes: query.prefixes, standard_prefixes: true)
|
15
|
+
when RDF::Graph then res.dump(options.fetch(:format, :ttl), base_uri: query.base_uri, prefixes: query.prefixes, standard_prefixes: true)
|
16
16
|
when RDF::Literal then res.inspect
|
17
|
-
else
|
17
|
+
else
|
18
|
+
case options[:format]
|
19
|
+
when :json then res.to_json
|
20
|
+
when :html then res.to_html
|
21
|
+
when :xml then res.to_xml
|
22
|
+
when :csv then res.to_csv
|
23
|
+
when :tsv then res.to_tsv
|
24
|
+
else res.map {|s| s.bindings.map {|k,v| "#{k}: #{v}"}}.join("\n")
|
25
|
+
end
|
18
26
|
end
|
19
27
|
end
|
20
28
|
|
21
|
-
def run(input, options
|
29
|
+
def run(input, **options)
|
22
30
|
if options[:debug]
|
23
31
|
puts "input graph:\n#{options[:dataset].dump(:trig, standard_prefixes: true)}\n" if options[:dataset]
|
24
32
|
puts "query:\n#{input}\n"
|
@@ -30,17 +38,17 @@ def run(input, options = {})
|
|
30
38
|
end
|
31
39
|
|
32
40
|
query = if options[:sse]
|
33
|
-
SPARQL::Algebra.parse(input,
|
41
|
+
SPARQL::Algebra.parse(input, logger: options[:logger], update: options[:update])
|
34
42
|
else
|
35
43
|
# Only do grammar debugging if we're generating SSE
|
36
|
-
SPARQL::Grammar.parse(input, options)
|
44
|
+
SPARQL::Grammar.parse(input, **options)
|
37
45
|
end
|
38
46
|
|
39
47
|
puts ("\nSSE:\n" + query.to_sse) if options[:debug] || options[:to_sse]
|
40
48
|
|
41
49
|
unless options[:to_sse]
|
42
|
-
res = query.execute(options[:dataset],
|
43
|
-
display_results(res, options)
|
50
|
+
res = query.execute(options[:dataset], logger: options[:logger])
|
51
|
+
display_results(res, **options)
|
44
52
|
end
|
45
53
|
end
|
46
54
|
|
@@ -52,9 +60,14 @@ def server(options)
|
|
52
60
|
register Sinatra::SPARQL
|
53
61
|
set :repository, repository
|
54
62
|
|
63
|
+
before do
|
64
|
+
options[:logger].info "#{request.request_method} [#{request.path_info}], " +
|
65
|
+
params.merge(Accept: request.accept.map(&:to_s)).map {|k,v| "#{k}=#{v}" unless k.to_s == "content"}.join(" ")
|
66
|
+
end
|
67
|
+
|
55
68
|
get '/' do
|
56
69
|
if params["query"]
|
57
|
-
query = params["query"].to_s.match(/^http:/) ? RDF::Util::File.open_file(params["query"]) : ::
|
70
|
+
query = params["query"].to_s.match(/^http:/) ? RDF::Util::File.open_file(params["query"]) : ::CGI.unescape(params["query"].to_s)
|
58
71
|
SPARQL.execute(query, settings.repository)
|
59
72
|
else
|
60
73
|
settings.sparql_options.replace(standard_prefixes: true)
|
@@ -70,23 +83,23 @@ def server(options)
|
|
70
83
|
SPARQL.execute(params['query'], settings.repository)
|
71
84
|
end
|
72
85
|
end
|
73
|
-
Rack::Server.start(app: app)
|
86
|
+
Rack::Server.start(app: app, Port: options.fetch(:port, 9292))
|
74
87
|
rescue LoadError
|
75
88
|
$stderr.puts "Running SPARQL server requires Rack to be in environment: #{$!.message}"
|
76
89
|
end
|
77
90
|
|
78
91
|
def usage
|
79
|
-
puts "Usage: #{$0} execute [options] query-file Execute a query against the specified dataset"
|
80
|
-
puts " #{$0} parse [options] query-file Parse a query into SPARQL S-Expressions (SSE)"
|
81
|
-
puts " #{$0} query [options] end-point query-file Run the query against a remote end-point"
|
82
|
-
puts " #{$0} server [options] dataset-file Start a server initialized from the specified dataset"
|
92
|
+
puts "Usage: #{File.basename($0)} execute [options] query-file Execute a query against the specified dataset"
|
93
|
+
puts " #{File.basename($0)} parse [options] query-file Parse a query into SPARQL S-Expressions (SSE)"
|
94
|
+
puts " #{File.basename($0)} query [options] end-point query-file Run the query against a remote end-point"
|
95
|
+
puts " #{File.basename($0)} server [options] dataset-file Start a server initialized from the specified dataset"
|
83
96
|
puts "Options:"
|
84
|
-
puts " --execute,-e: Use option argument as the SPARQL input if no query-file given"
|
85
97
|
puts " --dataset: File containing RDF graph or dataset"
|
86
98
|
puts " --debug: Display detailed debug output"
|
99
|
+
puts " --execute,-e: Use option argument as the SPARQL input if no query-file given"
|
100
|
+
puts " --format: Output format for results"
|
87
101
|
puts " --port,-p Port on which to run server; defaults to 9292"
|
88
102
|
puts " --sse: Query input is in SSE format"
|
89
|
-
puts " --debug: Display detailed debug output"
|
90
103
|
puts " --update: Process query as a SPARQL Update"
|
91
104
|
puts " --verbose: Display details of processing"
|
92
105
|
puts " --help,-?: This message"
|
@@ -98,27 +111,34 @@ cmd, input = ARGV.shift, nil
|
|
98
111
|
opts = GetoptLong.new(
|
99
112
|
["--dataset", GetoptLong::REQUIRED_ARGUMENT],
|
100
113
|
["--debug", GetoptLong::NO_ARGUMENT],
|
114
|
+
["--execute", "-e", GetoptLong::REQUIRED_ARGUMENT],
|
115
|
+
["--format", GetoptLong::REQUIRED_ARGUMENT],
|
101
116
|
["--port", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
102
|
-
["--verbose", GetoptLong::NO_ARGUMENT],
|
103
117
|
["--sse", GetoptLong::NO_ARGUMENT],
|
104
118
|
["--update", GetoptLong::NO_ARGUMENT],
|
105
|
-
["--
|
119
|
+
["--verbose", GetoptLong::NO_ARGUMENT],
|
106
120
|
["--help", "-?", GetoptLong::NO_ARGUMENT]
|
107
121
|
)
|
108
122
|
|
123
|
+
logger = Logger.new(STDERR)
|
124
|
+
logger.level = Logger::WARN
|
125
|
+
logger.formatter = lambda {|severity, datetime, progname, msg| "%5s %s\n" % [severity, msg]}
|
126
|
+
|
109
127
|
options = {
|
110
128
|
dataset: RDF::Repository.new,
|
129
|
+
logger: logger,
|
111
130
|
}
|
112
131
|
|
113
132
|
opts.each do |opt, arg|
|
114
133
|
case opt
|
115
|
-
when '--dataset' then options[:dataset].load(arg)
|
134
|
+
when '--dataset' then options[:dataset].load(arg, rdfstar: true)
|
135
|
+
when '--debug' then options[:debug] = true ; logger.level = Logger::DEBUG
|
116
136
|
when '--execute' then input = arg
|
137
|
+
when '--format' then options[:format] = arg.to_sym
|
117
138
|
when '--port' then options[:port] = arg.to_i
|
118
139
|
when '--sse' then options[:sse] = true
|
119
|
-
when '--debug' then options[:debug] = true
|
120
140
|
when '--update' then options[:update] = true
|
121
|
-
when '--verbose' then options[:verbose] = true
|
141
|
+
when '--verbose' then options[:verbose] = true ; logger.level = Logger::INFO
|
122
142
|
when "--help" then usage
|
123
143
|
end
|
124
144
|
end
|
@@ -132,7 +152,7 @@ case cmd
|
|
132
152
|
when 'execute', 'parse'
|
133
153
|
options[:to_sse] = true if cmd == 'parse'
|
134
154
|
input ||= ARGV.empty? ? $stdin.read : RDF::Util::File.open_file(ARGV.first).read
|
135
|
-
run(input, options)
|
155
|
+
run(input, **options)
|
136
156
|
when 'query'
|
137
157
|
endpoint = ARGV.shift
|
138
158
|
unless endpoint
|
@@ -142,7 +162,7 @@ when 'query'
|
|
142
162
|
input ||= ARGV.empty? ? $stdin.read : RDF::Util::File.open_file(ARGV.first).read
|
143
163
|
SPARQL::Client.new(endpoint) do |client|
|
144
164
|
res = client.query(input)
|
145
|
-
display_results(res, options)
|
165
|
+
display_results(res, **options)
|
146
166
|
end
|
147
167
|
when 'server'
|
148
168
|
if data_file = ARGV.shift
|