rdf-blazegraph 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8e2e77f00c85d5d33fa1138638238040525b0311
4
- data.tar.gz: d3cc73a2b6bd389a3206999ff1a8105d8764f065
3
+ metadata.gz: c0c6c5c91cbcc317617576f87509b86b8ffd55c4
4
+ data.tar.gz: 0ce51a89e9f46712dae6274cc92da5650f962a90
5
5
  SHA512:
6
- metadata.gz: 34f1525cf7ded366446347c4b6721649943f6674d2e0f8bd03b494386cd8876c7671e891a664db3b6a3e282aebbf88eb851bc20a9d4a953aeee817fce236f014
7
- data.tar.gz: 612f391cff097c9631f03f08b14d4350690a3c7db1bc10703043e3d72f8975d888eb4d5c60bca8df26e7362d15bde483846c19d908be48906e072d51f6a8f102
6
+ metadata.gz: 140fd3ac3b4dc9dd63c3640d78653290eda10648fe6a8c3c302cca9ee5b03dacd2f1ecdee372879e8b21a09a39f3c48495bee79ceafef1221a426d624cfc31d2
7
+ data.tar.gz: 71435e52775795d154b5c5a8d1b7ce9b80038bba3adb73a3c3a457e637fa1183efd3c8d65bbfe011f08e52a6436ae181e4ccd372ee041c29c51044c385ba06f4
data/README.md CHANGED
@@ -1,6 +1,26 @@
1
1
  RDF::Blazegraph
2
2
  ================
3
3
 
4
+ An RDF::Repository implementation for [Blazegraph](http://blazegraph.com); a REST client for [NanoSparqlServer](https://wiki.blazegraph.com/wiki/index.php/NanoSparqlServer).
5
+
6
+ ## Usage
7
+
8
+ Run `gem install rdf-blazegraph` or add `gem 'rdf-blazegraph'` to your Gemspec.
9
+
10
+ ```ruby
11
+ require 'rdf/blazegraph'
12
+
13
+ # as an RDF::Repository
14
+ repo = RDF::Blazegraph::Repository.new('http://localhost:9999/bigdata/sparql')
15
+ repo << RDF::Statement(RDF::URI('http://example.org/#moomin'), RDF::FOAF.name, 'Moomin')
16
+ repo.count # => 1
17
+
18
+ # with REST interface
19
+ nano = RDF::Blazegraph::RestClient.new('http://localhost:9999/bigdata/sparql')
20
+ nano.get_statements.each { |s| puts s.inspect }
21
+ # #<RDF::Statement:0x3ff0d450e5ec(<http://example.org/#moomin> <http://xmlns.com/foaf/0.1/name> "Moomin" .)>
22
+ ```
23
+
4
24
  ## Running the Tests
5
25
 
6
26
  ```bash
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -1,5 +1,4 @@
1
1
  require 'rdf'
2
- require 'sparql/client'
3
2
  require 'rexml/document'
4
3
  require 'net/http/persistent'
5
4
 
@@ -12,8 +11,14 @@ module RDF
12
11
  module Blazegraph
13
12
  VOCAB_BD = RDF::Vocabulary.new('http://www.bigdata.com/rdf#')
14
13
  NULL_GRAPH_URI = Blazegraph::VOCAB_BD.nullGraph
15
-
14
+
16
15
  autoload :Repository, 'rdf/blazegraph/repository'
17
16
  autoload :RestClient, 'rdf/blazegraph/rest_client'
18
17
  end
18
+
19
+ module NQuads
20
+ class Format
21
+ content_type 'application/n-quads', :extension => :nq, :alias => ['text/x-nquads']
22
+ end
23
+ end
19
24
  end
@@ -1,3 +1,5 @@
1
+ require 'sparql/client'
2
+
1
3
  module RDF::Blazegraph
2
4
  ##
3
5
  # An RDF::Repository implementaton for Blazegraph (formerly BigData).
@@ -16,8 +18,15 @@ module RDF::Blazegraph
16
18
  rest_client.fast_range_count
17
19
  end
18
20
 
21
+ ##
22
+ # @see RDF::Mutable#delete_insert
23
+ def delete_insert(deletes, inserts)
24
+ rest_client.delete_insert(deletes, inserts)
25
+ end
26
+
19
27
  ##
20
28
  # @see RDF::Repository#each
29
+ # @todo this won't scale
21
30
  def each(&block)
22
31
  rest_client.get_statements.each_statement(&block)
23
32
  end
@@ -29,9 +38,9 @@ module RDF::Blazegraph
29
38
  end
30
39
 
31
40
  ##
32
- # @see RDF::Repository#has_predicate?
33
- def has_context?(context)
34
- rest_client.has_statement?(context: context)
41
+ # @see RDF::Repository#has_graph_name?
42
+ def has_graph?(graph_name)
43
+ rest_client.has_statement?(context: graph_name)
35
44
  end
36
45
 
37
46
  ##
@@ -78,40 +87,51 @@ module RDF::Blazegraph
78
87
  rest_client.has_statement?(subject: statement.subject,
79
88
  predicate: statement.predicate,
80
89
  object: statement.object,
81
- context: statement.context)
90
+ context: statement.graph_name)
82
91
  end
83
92
 
84
93
  ##
85
94
  # @see SPARQL::Client::Repository#supports?
86
95
  def supports?(feature)
87
96
  return true if feature.to_sym == :context
97
+ return true if feature.to_sym == :graph_name
88
98
  super
89
99
  end
90
100
 
91
101
  protected
92
102
 
103
+ ##
104
+ # @private
105
+ # @see RDF::Mutable#clear
106
+ def clear_statements
107
+ rest_client.clear_statements
108
+ end
109
+
93
110
  ##
94
111
  # Deletes the given RDF statements from the underlying storage.
95
112
  #
96
- # Overridden here to use SPARQL/UPDATE
113
+ # Overridden here to use the Blazegraph REST client
97
114
  #
98
115
  # @param [RDF::Enumerable] statements
99
116
  # @return [void]
100
117
  def delete_statements(statements)
101
- @rest_client.delete(statements)
118
+ rest_client.delete(statements)
102
119
  end
103
120
 
104
121
  ##
105
122
  # Queries `self` for RDF statements matching the given `pattern`.
106
123
  #
107
124
  # @see SPARQL::Client::Repository#query_pattern
108
- def query_pattern(pattern, &block)
125
+ def query_pattern(pattern, options = {}, &block)
109
126
  pattern = pattern.dup
110
127
  pattern.subject ||= RDF::Query::Variable.new
111
128
  pattern.predicate ||= RDF::Query::Variable.new
112
129
  pattern.object ||= RDF::Query::Variable.new
113
130
  pattern.initialize!
114
131
 
132
+ return fast_pattern(pattern, &block) unless
133
+ pattern.subject.node? || pattern.predicate.node? || pattern.object.node?
134
+
115
135
  # Blazegraph objects to bnodes shared across the CONSTRUCT & WHERE scopes
116
136
  # so we dup the pattern with fresh bnodes
117
137
  where_pattern = pattern.dup
@@ -122,11 +142,11 @@ module RDF::Blazegraph
122
142
 
123
143
  query = client.construct(pattern).where(where_pattern)
124
144
 
125
- unless where_pattern.context.nil?
126
- where_pattern.context ||= NULL_GRAPH_URI
127
- query.graph(where_pattern.context)
128
- query.filter("#{where_pattern.context} != #{NULL_GRAPH_URI.to_base}") if
129
- where_pattern.context.variable?
145
+ unless where_pattern.graph_name.nil?
146
+ where_pattern.graph_name ||= NULL_GRAPH_URI
147
+ query.graph(where_pattern.graph_name)
148
+ query.filter("#{where_pattern.graph_name} != #{NULL_GRAPH_URI.to_base}") if
149
+ where_pattern.graph_name.variable?
130
150
  end
131
151
 
132
152
  if block_given?
@@ -136,6 +156,20 @@ module RDF::Blazegraph
136
156
  end
137
157
  end
138
158
 
159
+ def fast_pattern(pattern, &block)
160
+ pattern = pattern.dup
161
+ pattern.graph_name = NULL_GRAPH_URI if pattern.graph_name == false
162
+
163
+ reader =
164
+ rest_client.get_statements(subject: variable_to_nil(pattern.subject),
165
+ predicate: variable_to_nil(pattern.predicate),
166
+ object: variable_to_nil(pattern.object),
167
+ context: variable_to_nil(pattern.graph_name))
168
+
169
+ return reader.each_statement(&block) if block_given?
170
+ reader.each_statement
171
+ end
172
+
139
173
  def insert_statements(statements)
140
174
  rest_client.insert(statements)
141
175
  end
@@ -143,5 +177,10 @@ module RDF::Blazegraph
143
177
  def insert_statement(statement)
144
178
  rest_client.insert([statement])
145
179
  end
180
+
181
+ def variable_to_nil(term)
182
+ return nil unless term
183
+ term.variable? ? nil : term
184
+ end
146
185
  end
147
186
  end
@@ -18,6 +18,12 @@ module RDF::Blazegraph
18
18
  @sparql_client = SPARQL::Client.new(@url)
19
19
  end
20
20
 
21
+ ##
22
+ # Deletes all statements from the server
23
+ def clear_statements
24
+ send_delete_request('')
25
+ end
26
+
21
27
  ##
22
28
  # Send a request to the server
23
29
  #
@@ -104,9 +110,16 @@ module RDF::Blazegraph
104
110
  ##
105
111
  # @param [RDF::Enumerable] statements
106
112
  #
113
+ # @raise [ArugmentError] when a statement is invalid
107
114
  # @todo handle blank nodes
108
115
  def insert(statements)
109
- send_post_request(url, statements)
116
+ sts = statements.lazy.map do |st|
117
+ raise ArgumentError, "Invalid statement #{st}" if
118
+ st.respond_to?(:invalid?) && st.invalid?
119
+ st
120
+ end
121
+
122
+ send_post_request(url, sts)
110
123
  return self
111
124
  end
112
125
 
@@ -118,13 +131,19 @@ module RDF::Blazegraph
118
131
  return self if statements.empty?
119
132
 
120
133
  statements.map! do |s|
121
- statement = RDF::Statement.from(s)
122
- statement.context ||= NULL_GRAPH_URI
134
+ statement = RDF::Statement.from(s).dup
135
+ statement.graph_name ||= NULL_GRAPH_URI
123
136
  statement
124
137
  end
125
138
 
139
+ if statements.count == 1 && !statements.first.has_blank_nodes?
140
+ st = statements.first
141
+ query = access_path_query(st.subject, st.predicate, st.object, st.graph_name)
142
+ send_delete_request(query)
143
+ end
144
+
126
145
  constant = statements.all? do |statement|
127
- !statement.respond_to?(:each_statement) && statement.constant? &&
146
+ !statement.respond_to?(:each_statement) && statement.constant? &&
128
147
  !statement.has_blank_nodes?
129
148
  end
130
149
 
@@ -137,6 +156,16 @@ module RDF::Blazegraph
137
156
  return self
138
157
  end
139
158
 
159
+ ##
160
+ # @param [RDF::Enumerable<RDF::Statement>, Array<RDF::Statement>] dels
161
+ # @param [RDF::Enumerable<RDF::Statement>, Array<RDF::Statement>] ins
162
+ #
163
+ # @return [RDF::Blazegraph::RestClient] self
164
+ def delete_insert(deletes, ins)
165
+ delete(deletes)
166
+ insert(ins)
167
+ end
168
+
140
169
  private
141
170
 
142
171
  def sparql_ask_statement(triple, context)
@@ -156,24 +185,27 @@ module RDF::Blazegraph
156
185
  end
157
186
 
158
187
  def send_post_request(request_url, statements)
159
- io = StringIO.new
160
188
  writer = RDF::Writer.for(:nquads)
161
189
 
162
- io.rewind
163
-
164
190
  request = Net::HTTP::Post.new(request_url)
165
- request['Content-Type'] =
166
- RDF::Writer.for(:nquads).format.content_type.last # use text/x-nquads
191
+ request['Content-Type'] = 'text/x-nquads'
167
192
  request.body = writer.dump(statements)
168
193
 
169
194
  @http.request(url, request)
170
195
  end
171
-
196
+
197
+ def send_delete_request(query)
198
+ query = "#{query[1..-1]}" if query.start_with? '&'
199
+ request = Net::HTTP::Delete.new(url + "?#{::URI::encode(query)}")
200
+
201
+ @http.request(url, request)
202
+ end
203
+
172
204
  ##
173
205
  # @param [Net::HTTPResponse] response
174
206
  # @return [RDF::Enumerable]
175
207
  def read_rdf_response(response)
176
- RDF::Reader.for(content_type: response.content_type).new(response.body)
208
+ RDF::Reader.for(content_type: 'application/n-quads').new(response.body)
177
209
  end
178
210
 
179
211
  ##
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf-blazegraph
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom Johnson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-13 00:00:00.000000000 Z
11
+ date: 2016-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdf
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.1'
19
+ version: '1.99'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.1'
26
+ version: '1.99'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: sparql-client
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -134,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
134
134
  version: '0'
135
135
  requirements: []
136
136
  rubyforge_project:
137
- rubygems_version: 2.2.1
137
+ rubygems_version: 2.2.0
138
138
  signing_key:
139
139
  specification_version: 4
140
140
  summary: A Blazegraph Repository adapter for RDF.rb