sparql 3.0.0 → 3.1.3
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.
- checksums.yaml +5 -5
- data/README.md +184 -70
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/bin/sparql +28 -17
- 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 +14 -10
- 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 +28 -21
- data/lib/sparql/algebra/extensions.rb +142 -16
- 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 +5 -16
- 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 +7 -5
- data/lib/sparql/algebra/operator/delete_data.rb +3 -3
- data/lib/sparql/algebra/operator/delete_where.rb +5 -5
- 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 +3 -3
- 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 +21 -20
- 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 +5 -16
- 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 +6 -4
- 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 +6 -4
- 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 +10 -9
- 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 +6 -6
- 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 +1372 -333
- data/lib/sparql/grammar/parser11.rb +56 -42
- data/lib/sparql/grammar/terminals11.rb +1 -0
- data/lib/sparql/results.rb +63 -44
- data/lib/sparql/version.rb +1 -1
- metadata +40 -47
@@ -6,8 +6,8 @@ module SPARQL::Grammar
|
|
6
6
|
##
|
7
7
|
# A parser for the SPARQL 1.1 grammar.
|
8
8
|
#
|
9
|
-
# @see
|
10
|
-
# @see
|
9
|
+
# @see https://www.w3.org/TR/sparql11-query/#grammar
|
10
|
+
# @see https://en.wikipedia.org/wiki/LR_parser
|
11
11
|
class Parser
|
12
12
|
include SPARQL::Grammar::Meta
|
13
13
|
include SPARQL::Grammar::Terminals
|
@@ -216,7 +216,7 @@ module SPARQL::Grammar
|
|
216
216
|
unless resolve_iris?
|
217
217
|
# Only output if we're not resolving URIs internally
|
218
218
|
add_prod_datum(:BaseDecl, data[:BaseDecl])
|
219
|
-
add_prod_datum(:PrefixDecl, data[:PrefixDecl])
|
219
|
+
add_prod_datum(:PrefixDecl, data[:PrefixDecl])
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
@@ -624,11 +624,14 @@ module SPARQL::Grammar
|
|
624
624
|
if (lhs = (input.delete(:query) || []).first) && !lhs.empty?
|
625
625
|
query = SPARQL::Algebra::Operator::Join.new(lhs, query)
|
626
626
|
end
|
627
|
+
if data[:path]
|
628
|
+
query = SPARQL::Algebra::Operator::Join.new(query, Array(data[:path]).first)
|
629
|
+
end
|
627
630
|
add_prod_datum(:query, query)
|
628
631
|
elsif !Array(data[:query]).empty?
|
629
632
|
# Join query and path
|
630
633
|
add_prod_datum(:query, SPARQL::Algebra::Operator::Join.new(data[:path].first, data[:query].first))
|
631
|
-
|
634
|
+
elsif data[:path]
|
632
635
|
add_prod_datum(:query, data[:path])
|
633
636
|
end
|
634
637
|
end
|
@@ -698,9 +701,9 @@ module SPARQL::Grammar
|
|
698
701
|
end
|
699
702
|
end
|
700
703
|
|
701
|
-
# [60] Bind ::= 'BIND' '(' Expression 'AS' Var ')'
|
704
|
+
# [60] Bind ::= 'BIND' '(' (Expression || EmbTP) 'AS' Var ')'
|
702
705
|
production(:Bind) do |input, data, callback|
|
703
|
-
add_prod_datum :extend, [data[:Expression].unshift(data[:Var].first)]
|
706
|
+
add_prod_datum :extend, [(data[:Expression] || data[:pattern]).unshift(data[:Var].first)]
|
704
707
|
end
|
705
708
|
|
706
709
|
# [61] InlineData ::= 'VALUES' DataBlock
|
@@ -716,7 +719,7 @@ module SPARQL::Grammar
|
|
716
719
|
production(:InlineDataOneVar) do |input, data, callback|
|
717
720
|
add_prod_datum :Var, data[:Var]
|
718
721
|
|
719
|
-
data[:DataBlockValue].each do |d|
|
722
|
+
Array(data[:DataBlockValue]).each do |d|
|
720
723
|
add_prod_datum :row, [[:row, data[:Var].dup << d]]
|
721
724
|
end
|
722
725
|
end
|
@@ -856,11 +859,8 @@ module SPARQL::Grammar
|
|
856
859
|
data[:Subject] = prod_data[:Subject]
|
857
860
|
error(nil, "Expected Subject", production: :ObjectList) if !prod_data[:Subject] && validate?
|
858
861
|
error(nil, "Expected Verb", production: :ObjectList) if !(prod_data[:Verb] || prod_data[:VerbPath]) && validate?
|
859
|
-
if prod_data[:Verb]
|
860
|
-
|
861
|
-
else
|
862
|
-
data[:VerbPath] = prod_data[:VerbPath]
|
863
|
-
end
|
862
|
+
data[:Verb] = prod_data[:Verb] if prod_data[:Verb]
|
863
|
+
data[:VerbPath] = prod_data[:VerbPath] if prod_data[:VerbPath]
|
864
864
|
end
|
865
865
|
production(:ObjectList) do |input, data, callback|
|
866
866
|
add_prod_datum(:pattern, data[:pattern])
|
@@ -874,7 +874,7 @@ module SPARQL::Grammar
|
|
874
874
|
if prod_data[:Verb]
|
875
875
|
add_pattern(:Object, subject: prod_data[:Subject], predicate: prod_data[:Verb], object: object)
|
876
876
|
add_prod_datum(:pattern, data[:pattern])
|
877
|
-
|
877
|
+
elsif prod_data[:VerbPath]
|
878
878
|
add_prod_datum(:path,
|
879
879
|
SPARQL::Algebra::Expression(:path,
|
880
880
|
prod_data[:Subject].first,
|
@@ -886,11 +886,8 @@ module SPARQL::Grammar
|
|
886
886
|
|
887
887
|
# [81] TriplesSameSubjectPath ::= VarOrTerm PropertyListPathNotEmpty | TriplesNode PropertyListPath
|
888
888
|
production(:TriplesSameSubjectPath) do |input, data, callback|
|
889
|
-
|
890
|
-
|
891
|
-
else
|
892
|
-
add_prod_datum(:path, data[:path])
|
893
|
-
end
|
889
|
+
add_prod_datum(:pattern, data[:pattern])
|
890
|
+
add_prod_datum(:path, data[:path])
|
894
891
|
end
|
895
892
|
|
896
893
|
# [83] PropertyListPathNotEmpty ::= ( VerbPath | VerbSimple ) ObjectList ( ';' ( ( VerbPath | VerbSimple ) ObjectList )? )*
|
@@ -900,16 +897,14 @@ module SPARQL::Grammar
|
|
900
897
|
data[:Subject] = subject
|
901
898
|
end
|
902
899
|
production(:PropertyListPathNotEmpty) do |input, data, callback|
|
903
|
-
|
904
|
-
|
905
|
-
else
|
906
|
-
add_prod_datum(:path, data[:path])
|
907
|
-
end
|
900
|
+
add_prod_datum(:pattern, data[:pattern])
|
901
|
+
add_prod_datum(:path, data[:path])
|
908
902
|
end
|
909
903
|
|
910
904
|
# [84] VerbPath ::= Path
|
911
905
|
production(:VerbPath) do |input, data, callback|
|
912
906
|
if data[:Path]
|
907
|
+
input.delete(:Verb)
|
913
908
|
input[:VerbPath] = data[:Path]
|
914
909
|
else
|
915
910
|
input[:Verb] = data[:iri]
|
@@ -1109,11 +1104,21 @@ module SPARQL::Grammar
|
|
1109
1104
|
data.values.each {|v| add_prod_datum(:VarOrTerm, v)}
|
1110
1105
|
end
|
1111
1106
|
|
1107
|
+
# [106s] VarOrTermOrEmbTP ::= Var | GraphTerm | EmbTP
|
1108
|
+
production(:VarOrTermOrEmbTP) do |input, data, callback|
|
1109
|
+
data.values.each {|v| add_prod_datum(:VarOrTerm, v)}
|
1110
|
+
end
|
1111
|
+
|
1112
1112
|
# [107] VarOrIri ::= Var | iri
|
1113
1113
|
production(:VarOrIri) do |input, data, callback|
|
1114
1114
|
data.values.each {|v| add_prod_datum(:VarOrIri, v)}
|
1115
1115
|
end
|
1116
1116
|
|
1117
|
+
# [107s] VarOrBlankNodeOrIriOrEmbTP ::= Var | BlankNode| iri | EmbTP
|
1118
|
+
production(:VarOrBlankNodeOrIriOrEmbTP) do |input, data, callback|
|
1119
|
+
data.values.each {|v| add_prod_datum(:VarOrBlankNodeOrIriOrEmbTP, v)}
|
1120
|
+
end
|
1121
|
+
|
1117
1122
|
# [109] GraphTerm ::= iri | RDFLiteral | NumericLiteral
|
1118
1123
|
# | BooleanLiteral | BlankNode | NIL
|
1119
1124
|
production(:GraphTerm) do |input, data, callback|
|
@@ -1124,6 +1129,17 @@ module SPARQL::Grammar
|
|
1124
1129
|
data[:NIL])
|
1125
1130
|
end
|
1126
1131
|
|
1132
|
+
# [1xx] EmbTP ::= '<<' VarOrBlankNodeOrIriOrEmbTP Verb VarOrTermOrEmbTP '>>'
|
1133
|
+
production(:EmbTP) do |input, data, callback|
|
1134
|
+
subject = data[:VarOrBlankNodeOrIriOrEmbTP]
|
1135
|
+
predicate = data[:Verb]
|
1136
|
+
object = data[:VarOrTerm]
|
1137
|
+
add_pattern(:EmbTP,
|
1138
|
+
subject: subject,
|
1139
|
+
predicate: predicate,
|
1140
|
+
object: object)
|
1141
|
+
end
|
1142
|
+
|
1127
1143
|
# [110] Expression ::= ConditionalOrExpression
|
1128
1144
|
production(:Expression) do |input, data, callback|
|
1129
1145
|
add_prod_datum(:Expression, data[:Expression])
|
@@ -1420,7 +1436,7 @@ module SPARQL::Grammar
|
|
1420
1436
|
str = lit.delete(:string)
|
1421
1437
|
lit[:datatype] = lit.delete(:iri) if lit[:iri]
|
1422
1438
|
lit[:language] = lit.delete(:language).last.downcase if lit[:language]
|
1423
|
-
input[:literal] = RDF::Literal.new(str, lit) if str
|
1439
|
+
input[:literal] = RDF::Literal.new(str, **lit) if str
|
1424
1440
|
end
|
1425
1441
|
end
|
1426
1442
|
|
@@ -1471,7 +1487,7 @@ module SPARQL::Grammar
|
|
1471
1487
|
# @yieldparam [SPARQL::Grammar::Parser] parser
|
1472
1488
|
# @yieldreturn [void] ignored
|
1473
1489
|
# @return [SPARQL::Grammar::Parser]
|
1474
|
-
def initialize(input = nil, options
|
1490
|
+
def initialize(input = nil, **options, &block)
|
1475
1491
|
@input = case input
|
1476
1492
|
when IO, StringIO then input.read
|
1477
1493
|
else input.to_s.dup
|
@@ -1532,13 +1548,16 @@ module SPARQL::Grammar
|
|
1532
1548
|
# @param [Symbol, #to_s] prod The starting production for the parser.
|
1533
1549
|
# It may be a URI from the grammar, or a symbol representing the local_name portion of the grammar URI.
|
1534
1550
|
# @return [Array]
|
1535
|
-
# @see
|
1536
|
-
# @see
|
1551
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
1552
|
+
# @see https://axel.deri.ie/sparqltutorial/ESWC2007_SPARQL_Tutorial_unit2b.pdf
|
1537
1553
|
def parse(prod = START)
|
1538
|
-
ll1_parse(@input,
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1554
|
+
ll1_parse(@input,
|
1555
|
+
prod.to_sym,
|
1556
|
+
branch: BRANCH,
|
1557
|
+
first: FIRST,
|
1558
|
+
follow: FOLLOW,
|
1559
|
+
whitespace: WS,
|
1560
|
+
**@options
|
1542
1561
|
) do |context, *data|
|
1543
1562
|
case context
|
1544
1563
|
when :trace
|
@@ -1723,9 +1742,7 @@ module SPARQL::Grammar
|
|
1723
1742
|
|
1724
1743
|
if id
|
1725
1744
|
@vars[id] ||= begin
|
1726
|
-
|
1727
|
-
v.distinguished = distinguished
|
1728
|
-
v
|
1745
|
+
RDF::Query::Variable.new(id, distinguished: distinguished)
|
1729
1746
|
end
|
1730
1747
|
else
|
1731
1748
|
unless distinguished
|
@@ -1733,9 +1750,7 @@ module SPARQL::Grammar
|
|
1733
1750
|
id = @nd_var_gen
|
1734
1751
|
@nd_var_gen = id.succ
|
1735
1752
|
end
|
1736
|
-
|
1737
|
-
v.distinguished = distinguished
|
1738
|
-
v
|
1753
|
+
RDF::Query::Variable.new(id, distinguished: distinguished)
|
1739
1754
|
end
|
1740
1755
|
end
|
1741
1756
|
|
@@ -1763,7 +1778,7 @@ module SPARQL::Grammar
|
|
1763
1778
|
end
|
1764
1779
|
|
1765
1780
|
# Create a literal
|
1766
|
-
def literal(value, options
|
1781
|
+
def literal(value, **options)
|
1767
1782
|
options = options.dup
|
1768
1783
|
# Internal representation is to not use xsd:string, although it could arguably go the other way.
|
1769
1784
|
options.delete(:datatype) if options[:datatype] == RDF::XSD.string
|
@@ -1772,7 +1787,7 @@ module SPARQL::Grammar
|
|
1772
1787
|
"options: #{options.inspect}, " +
|
1773
1788
|
"validate: #{validate?.inspect}, "
|
1774
1789
|
end
|
1775
|
-
RDF::Literal.new(value,
|
1790
|
+
RDF::Literal.new(value, validate: validate?, **options)
|
1776
1791
|
end
|
1777
1792
|
|
1778
1793
|
# Take collection of objects and create RDF Collection using rdf:first, rdf:rest and rdf:nil
|
@@ -1803,7 +1818,7 @@ module SPARQL::Grammar
|
|
1803
1818
|
#
|
1804
1819
|
# @param [String] production Production generating pattern
|
1805
1820
|
# @param [Hash{Symbol => Object}] options
|
1806
|
-
def add_pattern(production, options)
|
1821
|
+
def add_pattern(production, **options)
|
1807
1822
|
progress(production, "[:pattern, #{options[:subject]}, #{options[:predicate]}, #{options[:object]}]")
|
1808
1823
|
triple = {}
|
1809
1824
|
options.each_pair do |r, v|
|
@@ -1885,8 +1900,7 @@ module SPARQL::Grammar
|
|
1885
1900
|
avf.first
|
1886
1901
|
else
|
1887
1902
|
# Allocate a temporary variable for this function, and retain the mapping for outside the group
|
1888
|
-
av = RDF::Query::Variable.new(".#{agg}")
|
1889
|
-
av.distinguished = false
|
1903
|
+
av = RDF::Query::Variable.new(".#{agg}", distinguished: false)
|
1890
1904
|
agg += 1
|
1891
1905
|
aggregates << [av, function]
|
1892
1906
|
av
|
data/lib/sparql/results.rb
CHANGED
@@ -14,28 +14,38 @@ module SPARQL
|
|
14
14
|
##
|
15
15
|
# Generate Solutions as JSON
|
16
16
|
# @return [String]
|
17
|
-
# @see
|
17
|
+
# @see https://www.w3.org/TR/rdf-sparql-json-res/
|
18
18
|
def to_json
|
19
19
|
require 'json' unless defined?(::JSON)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
{
|
28
|
-
|
29
|
-
|
30
|
-
{n => {type: "typed-literal", datatype: s.datatype.to_s, value: s.to_s }}
|
31
|
-
elsif s.language
|
32
|
-
{n => {type: "literal", "xml:lang" => s.language.to_s, value: s.to_s }}
|
33
|
-
else
|
34
|
-
{n => {type: "literal", value: s.to_s }}
|
35
|
-
end
|
20
|
+
|
21
|
+
format = ->(value) do
|
22
|
+
case value
|
23
|
+
when RDF::URI then {type: "uri", value: value.to_s }
|
24
|
+
when RDF::Node then {type: "bnode", value: value.id }
|
25
|
+
when RDF::Literal
|
26
|
+
if value.datatype?
|
27
|
+
{type: "typed-literal", datatype: value.datatype.to_s, value: value.to_s }
|
28
|
+
elsif value.language?
|
29
|
+
{type: "literal", "xml:lang" => value.language.to_s, value: value.to_s }
|
36
30
|
else
|
37
|
-
{}
|
31
|
+
{type: "literal", value: value.to_s }
|
38
32
|
end
|
33
|
+
when RDF::Statement
|
34
|
+
{
|
35
|
+
type: 'triple',
|
36
|
+
value: {
|
37
|
+
s: format.call(value.subject),
|
38
|
+
p: format.call(value.predicate),
|
39
|
+
o: format.call(value.object)
|
40
|
+
}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
bindings = self.map do |solution|
|
46
|
+
variable_names.inject({}) do |memo, n|
|
47
|
+
rep = format.call(solution[n])
|
48
|
+
rep ? memo.merge(n => rep) : memo
|
39
49
|
end
|
40
50
|
end
|
41
51
|
|
@@ -48,12 +58,36 @@ module SPARQL
|
|
48
58
|
##
|
49
59
|
# Generate Solutions as XML
|
50
60
|
# @return [String]
|
51
|
-
# @see
|
61
|
+
# @see https://www.w3.org/TR/rdf-sparql-XMLres/
|
52
62
|
def to_xml
|
53
63
|
require 'builder' unless defined?(::Builder)
|
54
64
|
|
55
65
|
xml = ::Builder::XmlMarkup.new(indent: 2)
|
56
66
|
xml.instruct!
|
67
|
+
|
68
|
+
format = ->(s) do
|
69
|
+
case s
|
70
|
+
when RDF::URI
|
71
|
+
xml.uri(s.to_s)
|
72
|
+
when RDF::Node
|
73
|
+
xml.bnode(s.id)
|
74
|
+
when RDF::Literal
|
75
|
+
if s.datatype?
|
76
|
+
xml.literal(s.to_s, "datatype" => s.datatype.to_s)
|
77
|
+
elsif s.language
|
78
|
+
xml.literal(s.to_s, "xml:lang" => s.language.to_s)
|
79
|
+
else
|
80
|
+
xml.literal(s.to_s)
|
81
|
+
end
|
82
|
+
when RDF::Statement
|
83
|
+
xml.triple do
|
84
|
+
xml.s {format.call(s.subject)}
|
85
|
+
xml.p {format.call(s.predicate)}
|
86
|
+
xml.o {format.call(s.object)}
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
57
91
|
xml.sparql(xmlns: "http://www.w3.org/2005/sparql-results#") do
|
58
92
|
xml.head do
|
59
93
|
variable_names.each do |n|
|
@@ -67,20 +101,7 @@ module SPARQL
|
|
67
101
|
s = solution[n]
|
68
102
|
next unless s
|
69
103
|
xml.binding(name: n) do
|
70
|
-
|
71
|
-
when RDF::URI
|
72
|
-
xml.uri(s.to_s)
|
73
|
-
when RDF::Node
|
74
|
-
xml.bnode(s.id)
|
75
|
-
when RDF::Literal
|
76
|
-
if s.datatype?
|
77
|
-
xml.literal(s.to_s, "datatype" => s.datatype.to_s)
|
78
|
-
elsif s.language
|
79
|
-
xml.literal(s.to_s, "xml:lang" => s.language.to_s)
|
80
|
-
else
|
81
|
-
xml.literal(s.to_s)
|
82
|
-
end
|
83
|
-
end
|
104
|
+
format.call(s)
|
84
105
|
end
|
85
106
|
end
|
86
107
|
end
|
@@ -118,7 +139,7 @@ module SPARQL
|
|
118
139
|
##
|
119
140
|
# Generate Solutions as CSV
|
120
141
|
# @return [String]
|
121
|
-
# @see
|
142
|
+
# @see https://www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/
|
122
143
|
def to_csv
|
123
144
|
require 'csv' unless defined?(::CSV)
|
124
145
|
bnode_map = {}
|
@@ -135,7 +156,7 @@ module SPARQL
|
|
135
156
|
this
|
136
157
|
end
|
137
158
|
else
|
138
|
-
solution[n].to_s
|
159
|
+
solution[n].to_s.strip
|
139
160
|
end
|
140
161
|
end
|
141
162
|
end
|
@@ -144,11 +165,9 @@ module SPARQL
|
|
144
165
|
##
|
145
166
|
# Generate Solutions as TSV
|
146
167
|
# @return [String]
|
147
|
-
# @see
|
168
|
+
# @see https://www.w3.org/TR/2013/REC-sparql11-results-csv-tsv-20130321/
|
148
169
|
def to_tsv
|
149
170
|
require 'csv' unless defined?(::CSV)
|
150
|
-
bnode_map = {}
|
151
|
-
bnode_gen = "_:a"
|
152
171
|
results = [
|
153
172
|
variable_names.map {|v| "?#{v}"}.join("\t")
|
154
173
|
] + self.map do |solution|
|
@@ -159,7 +178,7 @@ module SPARQL
|
|
159
178
|
when nil
|
160
179
|
""
|
161
180
|
else
|
162
|
-
RDF::NTriples.serialize(term)
|
181
|
+
RDF::NTriples.serialize(term).strip
|
163
182
|
end
|
164
183
|
end.join("\t")
|
165
184
|
end
|
@@ -185,7 +204,7 @@ module SPARQL
|
|
185
204
|
# @return [String]
|
186
205
|
# String with serialized results and `#content_type`
|
187
206
|
# @raise [RDF::WriterError] when inappropriate formatting options are used
|
188
|
-
def serialize_results(solutions, options
|
207
|
+
def serialize_results(solutions, **options)
|
189
208
|
format = options[:format].to_sym if options[:format]
|
190
209
|
content_type = options[:content_type].to_s.split(';').first
|
191
210
|
content_types = Array(options[:content_types] || '*/*')
|
@@ -226,7 +245,7 @@ module SPARQL
|
|
226
245
|
when RDF::Queryable
|
227
246
|
begin
|
228
247
|
require 'linkeddata'
|
229
|
-
rescue LoadError
|
248
|
+
rescue LoadError
|
230
249
|
require 'rdf/ntriples'
|
231
250
|
end
|
232
251
|
fmt = RDF::Format.for(format ? format.to_sym : {content_type: content_type})
|
@@ -236,7 +255,7 @@ module SPARQL
|
|
236
255
|
end
|
237
256
|
format ||= fmt.to_sym
|
238
257
|
content_type ||= fmt.content_type.first
|
239
|
-
results = solutions.dump(format, options)
|
258
|
+
results = solutions.dump(format, **options)
|
240
259
|
raise RDF::WriterError, "Unknown format #{fmt.inspect} for #{solutions.class}" unless results
|
241
260
|
results
|
242
261
|
when RDF::Query::Solutions
|
@@ -280,7 +299,7 @@ module SPARQL
|
|
280
299
|
# @param [Array<String>] available
|
281
300
|
# @return [String]
|
282
301
|
#
|
283
|
-
# @see
|
302
|
+
# @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
284
303
|
def first_content_type(acceptable, available)
|
285
304
|
return acceptable.first if available.empty?
|
286
305
|
available.flatten!
|
@@ -306,7 +325,7 @@ module SPARQL
|
|
306
325
|
# May also be an RDF::Writer content_type to serialize DESCRIBE or CONSTRUCT results
|
307
326
|
# @return [String]
|
308
327
|
# String with serialized results and #content_type
|
309
|
-
def serialize_exception(exception, options
|
328
|
+
def serialize_exception(exception, **options)
|
310
329
|
format = options[:format]
|
311
330
|
content_type = options[:content_type]
|
312
331
|
content_type ||= SPARQL::Results::MIME_TYPES[format]
|
data/lib/sparql/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module SPARQL
|
2
2
|
module VERSION
|
3
|
-
VERSION_FILE = File.
|
3
|
+
VERSION_FILE = File.expand_path("../../../VERSION", __FILE__)
|
4
4
|
MAJOR, MINOR, TINY, EXTRA = File.read(VERSION_FILE).chomp.split(".")
|
5
5
|
|
6
6
|
STRING = [MAJOR, MINOR, TINY, EXTRA].compact.join('.')
|