sparql 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. data/AUTHORS +3 -0
  2. data/CREDITS +0 -0
  3. data/README.markdown +103 -53
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/bin/sparql +87 -0
  7. data/lib/sparql.rb +105 -22
  8. data/lib/sparql/algebra.rb +369 -0
  9. data/lib/sparql/algebra/evaluatable.rb +37 -0
  10. data/lib/sparql/algebra/expression.rb +284 -0
  11. data/lib/sparql/algebra/extensions.rb +159 -0
  12. data/lib/sparql/algebra/operator.rb +492 -0
  13. data/lib/sparql/algebra/operator/add.rb +34 -0
  14. data/lib/sparql/algebra/operator/and.rb +65 -0
  15. data/lib/sparql/algebra/operator/asc.rb +29 -0
  16. data/lib/sparql/algebra/operator/ask.rb +46 -0
  17. data/lib/sparql/algebra/operator/base.rb +46 -0
  18. data/lib/sparql/algebra/operator/bgp.rb +26 -0
  19. data/lib/sparql/algebra/operator/bound.rb +48 -0
  20. data/lib/sparql/algebra/operator/compare.rb +84 -0
  21. data/lib/sparql/algebra/operator/construct.rb +85 -0
  22. data/lib/sparql/algebra/operator/dataset.rb +77 -0
  23. data/lib/sparql/algebra/operator/datatype.rb +42 -0
  24. data/lib/sparql/algebra/operator/desc.rb +17 -0
  25. data/lib/sparql/algebra/operator/describe.rb +71 -0
  26. data/lib/sparql/algebra/operator/distinct.rb +50 -0
  27. data/lib/sparql/algebra/operator/divide.rb +43 -0
  28. data/lib/sparql/algebra/operator/equal.rb +32 -0
  29. data/lib/sparql/algebra/operator/exprlist.rb +52 -0
  30. data/lib/sparql/algebra/operator/filter.rb +71 -0
  31. data/lib/sparql/algebra/operator/graph.rb +28 -0
  32. data/lib/sparql/algebra/operator/greater_than.rb +32 -0
  33. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +33 -0
  34. data/lib/sparql/algebra/operator/is_blank.rb +35 -0
  35. data/lib/sparql/algebra/operator/is_iri.rb +37 -0
  36. data/lib/sparql/algebra/operator/is_literal.rb +36 -0
  37. data/lib/sparql/algebra/operator/join.rb +67 -0
  38. data/lib/sparql/algebra/operator/lang.rb +29 -0
  39. data/lib/sparql/algebra/operator/lang_matches.rb +53 -0
  40. data/lib/sparql/algebra/operator/left_join.rb +95 -0
  41. data/lib/sparql/algebra/operator/less_than.rb +32 -0
  42. data/lib/sparql/algebra/operator/less_than_or_equal.rb +32 -0
  43. data/lib/sparql/algebra/operator/minus.rb +31 -0
  44. data/lib/sparql/algebra/operator/multiply.rb +34 -0
  45. data/lib/sparql/algebra/operator/not.rb +35 -0
  46. data/lib/sparql/algebra/operator/not_equal.rb +26 -0
  47. data/lib/sparql/algebra/operator/or.rb +65 -0
  48. data/lib/sparql/algebra/operator/order.rb +69 -0
  49. data/lib/sparql/algebra/operator/plus.rb +31 -0
  50. data/lib/sparql/algebra/operator/prefix.rb +45 -0
  51. data/lib/sparql/algebra/operator/project.rb +46 -0
  52. data/lib/sparql/algebra/operator/reduced.rb +47 -0
  53. data/lib/sparql/algebra/operator/regex.rb +70 -0
  54. data/lib/sparql/algebra/operator/same_term.rb +46 -0
  55. data/lib/sparql/algebra/operator/slice.rb +60 -0
  56. data/lib/sparql/algebra/operator/str.rb +35 -0
  57. data/lib/sparql/algebra/operator/subtract.rb +32 -0
  58. data/lib/sparql/algebra/operator/union.rb +55 -0
  59. data/lib/sparql/algebra/query.rb +99 -0
  60. data/lib/sparql/algebra/sxp_extensions.rb +35 -0
  61. data/lib/sparql/algebra/version.rb +20 -0
  62. data/lib/sparql/extensions.rb +102 -0
  63. data/lib/sparql/grammar.rb +298 -0
  64. data/lib/sparql/grammar/lexer.rb +609 -0
  65. data/lib/sparql/grammar/parser.rb +1383 -0
  66. data/lib/sparql/grammar/parser/meta.rb +1801 -0
  67. data/lib/sparql/results.rb +220 -0
  68. data/lib/sparql/version.rb +20 -0
  69. metadata +232 -62
  70. data/Rakefile +0 -22
  71. data/coverage/index.html +0 -252
  72. data/coverage/lib-sparql-execute_sparql_rb.html +0 -621
  73. data/coverage/lib-sparql_rb.html +0 -622
  74. data/lib/sparql/execute_sparql.rb +0 -27
  75. data/lib/sparql/sparql.treetop +0 -159
  76. data/sparql.gemspec +0 -16
  77. data/spec/spec.opts +0 -2
  78. data/spec/spec_helper.rb +0 -24
  79. data/spec/unit/graph_parsing_spec.rb +0 -76
  80. data/spec/unit/iri_parsing_spec.rb +0 -46
  81. data/spec/unit/prefixed_names_parsing_spec.rb +0 -40
  82. data/spec/unit/primitives_parsing_spec.rb +0 -26
  83. data/spec/unit/sparql_parsing_spec.rb +0 -72
  84. data/spec/unit/variables_parsing_spec.rb +0 -36
data/AUTHORS ADDED
@@ -0,0 +1,3 @@
1
+ * Gregg Kellogg <gregg@kellogg-assoc.com>
2
+ * Arto Bendiken <arto.bendiken@gmail.com>
3
+ * Pius Uzamere <pius@alum.mit.edu>
data/CREDITS ADDED
File without changes
data/README.markdown CHANGED
@@ -1,88 +1,138 @@
1
- sparql Release 0.0.1 (July 17th 2008)
2
- ===================================
1
+ # SPARQL for RDF.rb
3
2
 
4
- **Git**: [http://github.com/pius/sparql](http://github.com/pius/sparql)
5
- **Author**: Pius Uzamere, [The Uyiosa Corporation](http://www.uyiosa.com)
3
+ This is a [Ruby][] implementation of the [SPARQL][] algebra for [RDF.rb][].
6
4
 
7
- **Copyright**: Pius Uzamere © 2008
8
- **License**: The Lesser GNU Public License
5
+ ## Features
9
6
 
7
+ * 100% free and unencumbered [public domain](http://unlicense.org/) software.
8
+ * [SPARQL 1.0][] query parsing and execution
9
+ * SPARQL results as [XML][SPARQL XML] or [JSON][SPARQL JSON].
10
+ * SPARQL CONSTRUCT or DESCRIBE serialized based on Format, Extension of Mime Type
11
+ using available RDF Writers (see [Linked Data](http://rubygems.org/gems/linkeddata))
12
+ * SPARQL Client for accessing remote SPARQL endpoints.
13
+ * Helper method for describing [SPARQL Service Description][]
14
+ * Compatible with Ruby Ruby 1.9.x.
15
+ * Compatible with older Ruby versions with the help of the [Backports][] gem.
16
+ * Supports Unicode query strings both on Ruby 1.8.x and 1.9.x.
10
17
 
11
- SYNOPSIS
12
- --------
18
+ ## Examples
13
19
 
14
- sparql is a library for Ruby that formally implements the [SPARQL grammar](http://www.w3.org/TR/rdf-sparql-query/#grammar) as a parsing expression grammar (PEG). The grammar is implemented in a fantastic syntax language called [Treetop](http://treetop.rubyforge.org).
20
+ require 'rubygems'
21
+ require 'sparql'
15
22
 
23
+ ### Executing a SPARQL query against a repository
16
24
 
17
- FEATURE LIST
18
- ------------
19
-
20
- 1. **As of right now (00:10 EST, July 17, 2008) can parse basic SPARQL statements, check the test cases for precisely what it can support**: When finished, this library will be able to parse arbitrary SPARQL queries and can serve as a maintainable reference implementation in Ruby.
25
+ queryable = RDF::Repository.load("etc/doap.ttl")
26
+ sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
27
+ sse.execute(queryable)
21
28
 
22
- 2. **Starting point for providing SPARQL endpoints for arbitrary datastores**: When completed, this library will provide hooks that allow a Ruby developer to easily define a translation from SPARQL to another query language or API of their choosing. Ideally, this will be done using a simple YAML configuration file.
29
+ ### Rendering solutions as JSON, XML or HTML
30
+ queryable = RDF::Repository.load("etc/doap.ttl")
31
+ solutions = SPARQL.execute("SELECT * WHERE { ?s ?p ?o }", queryable)
32
+ solutions.to_json #to_xml #to_html
23
33
 
24
- 3. **Fully Composable**: Because parsing expression grammars are closed under composition, you can compose this grammar with other Treetop grammars with relative ease.
34
+ ### Parsing a SPARQL query string to SSE
25
35
 
36
+ sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
37
+ sse.to_sxp
26
38
 
27
- USAGE
28
- -----
39
+ ### Command line processing
29
40
 
30
- Though this library only parses a small subset of SPARQL and I've not added all of the API methods yet, it **is** ready to start playing with.
41
+ sparql --default-graph etc/doap.ttl etc/from_default.rq
42
+ sparql -e "SELECT * FROM <etc/doap.ttl> WHERE { ?s ?p ?o }"
31
43
 
32
- 1. **Install the Gem**
44
+ # Generate SPARQL Algebra Expression (SSE) format
45
+ sparql --to-sse etc/input.rq
46
+ sparql --to-sse -e "SELECT * WHERE { ?s ?p ?o }"
33
47
 
34
- Make sure you've upgraded to RubyGems 1.2. Then, if you've never installed a gem from GitHub before then do this:
48
+ # Run query using SSE input
49
+ sparql --default-graph etc/doap.ttl --sse etc/input.sse
50
+ sparql --sse -e "(dataset (<etc/doap.ttl>) (bgp (triple ?s ?p ?o))))"
35
51
 
36
- > gem sources -a http://gems.github.com (you only have to do this once)
52
+ ## Documentation
37
53
 
38
- Then:
54
+ Full documentation available on [Rubydoc.info][SPARQL doc]
39
55
 
40
- > sudo gem install pius-sparql
56
+ ### Principle Classes
41
57
 
42
- 2. **Make Sure You've Got the Dependencies installed**
58
+ * {SPARQL}
59
+ * {SPARQL::Algebra}
60
+ * {SPARQL::Algebra::Expression}
61
+ * {SPARQL::Algebra::Query}
62
+ * {SPARQL::Algebra::Operator}
63
+ * {SPARQL::Grammar}
64
+ * {SPARQL::Grammar::Parser}
65
+ * {SPARQL::Grammar::Lexer}
43
66
 
44
- sparql depends on Treetop (http://github.com/nathansobo/treetop).
67
+ ## Dependencies
45
68
 
46
- > sudo gem install treetop
69
+ * [Ruby](http://ruby-lang.org/) (>= 1.9) or (>= 1.8.1 with [Backports][])
70
+ * [RDF.rb](http://rubygems.org/gems/rdf) (>= 0.3.4)
71
+ * [SPARQL::Client](https://rubygems.org/gems/sparql-client) (>= 0.0.11)
72
+ * [SXP](https://rubygems.org/gems/sxp) (>= 0.0.15)
73
+ * [Builder](https://rubygems.org/gems/builder) (>= 3.0.0)
74
+ * [JSON](https://rubygems.org/gems/json) (>= 1.5.1)
47
75
 
48
- 3. **Require the gem in your code, play with it**
76
+ ## Installation
49
77
 
50
- As of this minute, the code won't be that useful to you, as it can only parse a small subset of SPARQL and the translation hooks have not been added yet. That being said, stay tuned. I think development on this is going to move fairly quickly because Treetop is such a joy to write the PEG in.
78
+ The recommended installation method is via [RubyGems](http://rubygems.org/).
79
+ To install the latest official release of the `SPARQL` gem, do:
51
80
 
52
- Anyway, you can get started by doing the following in IRB.
81
+ % [sudo] gem install sparql
53
82
 
54
- > irb(main):001:0> require 'rubygems'
83
+ ## Download
55
84
 
56
- > => true
85
+ To get a local working copy of the development repository, do:
57
86
 
58
- > irb(main):002:0> gem 'pius-sparql'
87
+ % git clone git://github.com/gkellogg/sparql.git
59
88
 
60
- > => true
89
+ ## Mailing List
61
90
 
62
- > irb(main):003:0> require 'sparql'
91
+ * <http://lists.w3.org/Archives/Public/public-rdf-ruby/>
63
92
 
64
- > => true
93
+ ## Authors
65
94
 
66
- > irb(main):004:0> parser = SparqlParser.new
95
+ * [Gregg Kellogg](http://github.com/gkellogg) - <http://kellogg-assoc.com/>
96
+ * [Arto Bendiken](http://github.com/bendiken) - <http://ar.to/>
97
+ * [Pius Uzamere](http://github.com/pius) - <http://pius.me/>
67
98
 
68
- > => #SparqlParser:0x1270bcc @consume_all_input=true
99
+ ## Contributing
69
100
 
70
- > irb(main):005:0> syntaxtree = parser.parse('SELECT ?foo ?bar WHERE { ?x foaf:knows ?y . ?z foaf:name ?y . }')
101
+ * Do your best to adhere to the existing coding conventions and idioms.
102
+ * Don't use hard tabs, and don't leave trailing whitespace on any line.
103
+ * Do document every method you add using [YARD][] annotations. Read the
104
+ [tutorial][YARD-GS] or just look at the existing code for examples.
105
+ * Don't touch the `.gemspec`, `VERSION` or `AUTHORS` files. If you need to
106
+ change them, do so on your private branch only.
107
+ * Do feel free to add yourself to the `CREDITS` file and the corresponding
108
+ list in the the `README`. Alphabetical order applies.
109
+ * Do note that in order for us to merge any non-trivial changes (as a rule
110
+ of thumb, additions larger than about 15 lines of code), we need an
111
+ explicit [public domain dedication][PDD] on record from you.
71
112
 
113
+ ## License
72
114
 
73
- 4. **Read the documentation**
115
+ This is free and unencumbered public domain software. For more information,
116
+ see <http://unlicense.org/> or the accompanying {file:UNLICENSE} file.
74
117
 
75
- Actually, read the tests -- they will show you the forms that are supported. Take a look at lib/sparql/sparql.treetop and get a sense of the grammar. In addition, check out the [formal specification of the SPARQL grammar](http://www.w3.org/TR/rdf-sparql-query/#grammar) so you can see how the Treetop grammar relates to it.
76
-
77
- 5. **Contribute!**
78
-
79
- Fork my repository (http://github.com/pius/sparql), make some changes, and send along a pull request!
80
-
81
- The best way to contribute is to add a test case for a specific SPARQL query that does not parse and then tweak the grammar such that your new test case plus all the others pass.
82
-
83
-
84
- COPYRIGHT
85
- ---------
86
-
87
- sparql was created in 2008 by Pius Uzamere (pius -AT- alum -DOT- mit -DOT- edu) and is
88
- licensed under the LGPL.
118
+ [Ruby]: http://ruby-lang.org/
119
+ [RDF]: http://www.w3.org/RDF/
120
+ [YARD]: http://yardoc.org/
121
+ [YARD-GS]: http://rubydoc.info/docs/yard/file/docs/GettingStarted.md
122
+ [PDD]: http://lists.w3.org/Archives/Public/public-rdf-ruby/2010May/0013.html
123
+ [SPARQL]: http://en.wikipedia.org/wiki/SPARQL
124
+ [SPARQL 1.0]: http://www.w3.org/TR/rdf-sparql-query/
125
+ [SPARQL 1.1]: http://www.w3.org/TR/sparql11-query/
126
+ [SSE]: http://openjena.org/wiki/SSE
127
+ [SXP]: http://sxp.rubyforge.org/
128
+ [grammar]: http://www.w3.org/TR/rdf-sparql-query/#grammar
129
+ [RDF.rb]: http://rdf.rubyforge.org/
130
+ [YARD]: http://yardoc.org/
131
+ [YARD-GS]: http://rubydoc.info/docs/yard/file/docs/GettingStarted.md
132
+ [PDD]: http://unlicense.org/#unlicensing-contributions
133
+ [Backports]: http://rubygems.org/gems/backports
134
+ [SPARQL doc]: http://rubydoc.info/github/gkellogg/sparql/frames
135
+ [SPARQL XML]: http://www.w3.org/TR/rdf-sparql-XMLres/
136
+ [SPARQL JSON]: http://www.w3.org/TR/rdf-sparql-json-res/
137
+ [SPARQL Protocol]: http://www.w3.org/TR/rdf-sparql-protocol/
138
+ [SPARQL Service]: http://www.w3.org/TR/sparql11-service-description/
data/UNLICENSE ADDED
@@ -0,0 +1,24 @@
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, please refer to <http://unlicense.org/>
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.2
data/bin/sparql ADDED
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ $:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "..", 'lib')))
4
+ require 'sparql'
5
+ require 'linkeddata'
6
+ require 'getoptlong'
7
+
8
+ def run(input, options = {})
9
+ if options[:debug]
10
+ puts "input graph:\n#{options[:graph].dump(:n3)}\n" if options[:graph]
11
+ puts "query:\n#{input}\n"
12
+ end
13
+
14
+ if options[:verbose]
15
+ puts ("\nSPARQL:\n" + input)
16
+ end
17
+
18
+ query = if options[:sse]
19
+ SPARQL::Algebra.parse(input, {:debug => options[:debug]})
20
+ else
21
+ SPARQL::Grammar.parse(input, options)
22
+ end
23
+
24
+ if options[:to_sse]
25
+ puts ("\nSSE:\n" + query.to_sxp)
26
+ else
27
+ res = query.execute(options[:graph])
28
+ puts res.inspect if options[:verbose]
29
+ puts case res
30
+ when RDF::Graph then res.dump(:ttl, :base_uri => query.base_uri, :prefixes => query.prefixes)
31
+ else res.map {|s| s.bindings.map {|k,v| "#{k}: #{v}"}}.join("\n")
32
+ end
33
+ end
34
+ end
35
+
36
+ opts = GetoptLong.new(
37
+ ["--debug", GetoptLong::NO_ARGUMENT],
38
+ ["--dump", GetoptLong::NO_ARGUMENT],
39
+ ["--verbose", GetoptLong::NO_ARGUMENT],
40
+ ["--sse", GetoptLong::NO_ARGUMENT],
41
+ ["--to-sse", GetoptLong::NO_ARGUMENT],
42
+ ["--execute", "-e", GetoptLong::REQUIRED_ARGUMENT],
43
+ ["--default-graph", "-g", GetoptLong::REQUIRED_ARGUMENT],
44
+ ["--help", "-?", GetoptLong::NO_ARGUMENT]
45
+ )
46
+
47
+ options = {
48
+ :graph => RDF::Repository.new,
49
+ }
50
+
51
+ input = nil
52
+
53
+ opts.each do |opt, arg|
54
+ case opt
55
+ when '--execute' then input = arg
56
+ when "--default-graph" then options[:graph] = RDF::Graph.load(arg)
57
+ when '--dump' then $dump = true
58
+ when '--sse' then options[:sse] = true
59
+ when '--to-sse' then options[:to_sse] = true
60
+ when '--debug' then options[:debug] = true
61
+ when '--verbose' then options[:verbose] = true
62
+ when "--help"
63
+ puts "Usage: #{$0} [options] file-or-uri ..."
64
+ puts "Options:"
65
+ puts " --execute,-e: Use option argument as the SPARQL input if no files are given"
66
+ puts " --default-graph: Load default graph"
67
+ puts " --dump: Dump raw output, otherwise serialize to SSE"
68
+ puts " --debug: Display detailed debug output"
69
+ puts " --sse: Input is in SSE format"
70
+ puts " --to-sse: Generate SSE instead of running query"
71
+ puts " --debug: Display detailed debug output"
72
+ puts " --verbose: Display details of processing"
73
+ puts " --help,-?: This message"
74
+ exit(0)
75
+ end
76
+ end
77
+
78
+ if ARGV.empty?
79
+ s = input ? input : $stdin.read
80
+ run(s, options)
81
+ else
82
+ ARGV.each do |test_file|
83
+ puts "parse #{test_file}"
84
+ run(RDF::Util::File.open_file(test_file).read, options.merge(:base_uri => RDF::URI(test_file)))
85
+ end
86
+ end
87
+ puts
data/lib/sparql.rb CHANGED
@@ -1,28 +1,111 @@
1
- # This file is part of Sparql.rb.
2
- #
3
- # Sparql.rb is free software: you can redistribute it and/or modify
4
- # it under the terms of the GNU Lesser General Public License as published by
5
- # the Free Software Foundation, either version 3 of the License, or
6
- # (at your option) any later version.
7
- #
8
- # Sparql.rb is distributed in the hope that it will be useful,
9
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- # GNU Lesser General Public License for more details.
12
- #
13
- # You should have received a copy of the GNU Lesser General Public License
14
- # along with Sparql.rb. If not, see <http://www.gnu.org/licenses/>.
1
+ require 'sparql/extensions'
15
2
 
3
+ ##
4
+ # A SPARQL for RDF.rb.
5
+ #
6
+ # @see http://www.w3.org/TR/rdf-sparql-query
7
+ module SPARQL
8
+ autoload :Algebra, 'sparql/algebra'
9
+ autoload :Grammar, 'sparql/grammar'
10
+ autoload :Results, 'sparql/results'
11
+ autoload :VERSION, 'sparql/version'
16
12
 
17
- require 'rubygems'
18
- require 'pathname'
13
+ # @see http://rubygems.org/gems/sparql-client
14
+ autoload :Client, 'sparql/client'
19
15
 
20
- class Pathname
21
- def /(path)
22
- (self + path).expand_path
16
+ ##
17
+ # Parse the given SPARQL `query` string.
18
+ #
19
+ # @example
20
+ # parser = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
21
+ # result = parser.parse
22
+ #
23
+ # @param [IO, StringIO, String, #to_s] query
24
+ # @param [Hash{Symbol => Object}] options
25
+ # @return [SPARQL::Query]
26
+ # The resulting query may be executed against
27
+ # a `queryable` object such as an RDF::Graph
28
+ # or RDF::Repository.
29
+ # @raise [Parser::Error] on invalid input
30
+ def self.parse(query, options = {})
31
+ query = Grammar::Parser.new(query, options).parse
23
32
  end
24
- end # class Pathname
25
33
 
26
- dir = Pathname(__FILE__).dirname.expand_path / 'sparql'
34
+ ##
35
+ # Parse and execute the given SPARQL `query` string against `queriable`.
36
+ #
37
+ # Requires a queryable object (such as an RDF::Repository), into which the dataset will be loaded.
38
+ #
39
+ # Optionally takes a list of URIs to load as default or named graphs
40
+ # into `queryable`.
41
+ #
42
+ # Note, if default or named graphs are specified as options (protocol elements),
43
+ # or the query references specific default or named graphs the graphs are either
44
+ # presumed to be existant in `queryable` or are loaded into `queryable` depending
45
+ # on the presense and value of the :load_datasets option.
46
+ #
47
+ # Attempting to load into an immutable `queryable` will result in a RDF::TypeError.
48
+ #
49
+ # @example
50
+ # repository = RDF::Repository.new
51
+ # results = SPARQL.execute("SELECT * WHERE { ?s ?p ?o }", repository)
52
+ # result = parser.parse
53
+ #
54
+ # @param [IO, StringIO, String, #to_s] query
55
+ # @param [Hash{Symbol => Object}] options
56
+ # @option options [RDF::Queryable] :queryable
57
+ # @option options [RDF::URI, String, Array<RDF::URI, String>] :load_datasets
58
+ # One or more URIs used to initialize a new instance of `queryable` in the default context.
59
+ # @option options [RDF::URI, String, Array<RDF::URI, String>] :default_graph_uri
60
+ # One or more URIs used to initialize a new instance of `queryable` in the default context.
61
+ # @option options [RDF::URI, String, Array<RDF::URI, String>] :named_graph_uri
62
+ # One or more URIs used to initialize the `queryable` as a named context.
63
+ # @return [RDF::Graph, RDF::Query::Solutions, Boolean]
64
+ # Note, results may be used with SPARQL.serialize_results to obtain appropriate
65
+ # output encoding.
66
+ # @raise [SPARQL::MalformedQuery] on invalid input
67
+ def self.execute(query, queryable, options = {})
68
+ query = self.parse(query, options)
69
+ queryable = queryable || RDF::Repository.new
70
+
71
+ if options.has_key?(:load_datasets)
72
+ queryable = queryable.class.new
73
+ [options[:default_graph_uri]].flatten.each do |uri|
74
+ queryable.load(uri)
75
+ end
76
+ [options[:named_graph_uri]].flatten.each do |uri|
77
+ queryable.load(uri, :context => uri)
78
+ end
79
+ end
80
+ solutions = query.execute(queryable)
81
+ rescue SPARQL::Grammar::Parser::Error => e
82
+ raise MalformedQuery, e.message
83
+ rescue RDF::TypeError => e
84
+ raise QueryRequestRefused, e.message
85
+ end
86
+
87
+ ##
88
+ # MalformedQuery
89
+ #
90
+ # When the value of the query type is not a legal sequence of characters in the language defined by the
91
+ # SPARQL grammar, the MalformedQuery or QueryRequestRefused fault message must be returned. According to the
92
+ # Fault Replaces Message Rule, if a WSDL fault is returned, including MalformedQuery, an Out Message must not
93
+ # be returned.
94
+ class MalformedQuery < Exception
95
+ def title
96
+ "Malformed Query".freeze
97
+ end
98
+ end
99
+
100
+ ##
101
+ # QueryRequestRefused
102
+ #
103
+ # returned when a client submits a request that the service refuses to process.
104
+ class QueryRequestRefused < Exception
105
+ def title
106
+ "Query Request Refused".freeze
107
+ end
108
+ end
109
+ end
27
110
 
28
- require dir / 'execute_sparql'
111
+ require 'sparql/extensions'