iq_triplestorage 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/iq_triplestorage.rb +23 -1
- data/lib/iq_triplestorage/sesame_adaptor.rb +5 -22
- data/lib/iq_triplestorage/virtuoso_adaptor.rb +58 -73
- data/test/base_test.rb +29 -0
- data/test/sesame_test.rb +3 -21
- data/test/virtuoso_test.rb +4 -5
- metadata +6 -6
- data/test/core_test.rb +0 -11
data/lib/iq_triplestorage.rb
CHANGED
@@ -1,3 +1,25 @@
|
|
1
1
|
module IqTriplestorage
|
2
|
-
VERSION = "0.2.
|
2
|
+
VERSION = "0.2.1"
|
3
|
+
|
4
|
+
class BaseAdaptor
|
5
|
+
attr_reader :host
|
6
|
+
|
7
|
+
def initialize(host, options={})
|
8
|
+
@host = URI.parse(host).normalize
|
9
|
+
@username = options[:username]
|
10
|
+
@password = options[:password]
|
11
|
+
end
|
12
|
+
|
13
|
+
def http_request(method, path, body, headers={})
|
14
|
+
uri = URI.join("#{@host}/", path)
|
15
|
+
|
16
|
+
req = Net::HTTP.const_get(method.to_s.downcase.capitalize).new(uri.to_s)
|
17
|
+
req.basic_auth(@username, @password) if (@username && @password)
|
18
|
+
headers.each { |key, value| req[key] = value }
|
19
|
+
req.body = body
|
20
|
+
|
21
|
+
return Net::HTTP.new(uri.host, uri.port).request(req)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
3
25
|
end
|
@@ -3,14 +3,12 @@ require "cgi"
|
|
3
3
|
|
4
4
|
require "iq_triplestorage"
|
5
5
|
|
6
|
-
class IqTriplestorage::SesameAdaptor
|
7
|
-
attr_reader :host
|
6
|
+
class IqTriplestorage::SesameAdaptor < IqTriplestorage::BaseAdaptor
|
8
7
|
|
9
|
-
def initialize(host,
|
10
|
-
|
11
|
-
@repo = repository
|
12
|
-
|
13
|
-
@password = options[:username]
|
8
|
+
def initialize(host, options={})
|
9
|
+
super
|
10
|
+
@repo = options[:repository]
|
11
|
+
raise(ArgumentError, "repository must not be nil") if @repo.nil?
|
14
12
|
end
|
15
13
|
|
16
14
|
# expects a hash of N-Triples by graph URI
|
@@ -25,19 +23,4 @@ class IqTriplestorage::SesameAdaptor
|
|
25
23
|
http_request("POST", path, data, { "Content-Type" => "application/x-trig" })
|
26
24
|
end
|
27
25
|
|
28
|
-
# converts N-Triples to N-Quads
|
29
|
-
def triples_to_quads(triples, context)
|
30
|
-
end
|
31
|
-
|
32
|
-
def http_request(method, path, body, headers={}) # XXX: largely duplicates VirtuosoAdaptor's
|
33
|
-
uri = URI.join("#{@host.to_s}/", path)
|
34
|
-
|
35
|
-
req = Net::HTTP.const_get(method.to_s.downcase.capitalize).new(uri.to_s)
|
36
|
-
req.basic_auth(@username, @password) if (@username && @password)
|
37
|
-
headers.each { |key, value| req[key] = value }
|
38
|
-
req.body = body
|
39
|
-
|
40
|
-
return Net::HTTP.new(uri.host, uri.port).request(req)
|
41
|
-
end
|
42
|
-
|
43
26
|
end
|
@@ -1,97 +1,82 @@
|
|
1
1
|
require "net/http"
|
2
2
|
|
3
|
-
|
4
|
-
class VirtuosoAdaptor
|
3
|
+
require "iq_triplestorage"
|
5
4
|
|
6
|
-
|
7
|
-
# validate to avoid nasty errors
|
8
|
-
raise(ArgumentError, "username must not be nil") if username.nil?
|
5
|
+
class IqTriplestorage::VirtuosoAdaptor < IqTriplestorage::BaseAdaptor
|
9
6
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def reset(uri)
|
17
|
-
return sparql_pull("CLEAR GRAPH <#{uri}>") # XXX: s/CLEAR/DROP/ was rejected (405)
|
18
|
-
end
|
19
|
-
|
20
|
-
# expects a hash of N-Triples by graph URI
|
21
|
-
def batch_update(triples_by_graph)
|
22
|
-
# apparently Virtuoso gets confused when mixing CLEAR and INSERT queries,
|
23
|
-
# so we have to do use separate requests
|
7
|
+
def initialize(host, options={})
|
8
|
+
super
|
9
|
+
# validate to avoid nasty errors
|
10
|
+
raise(ArgumentError, "username must not be nil") if @username.nil?
|
11
|
+
end
|
24
12
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
success = sparql_query(reset_queries)
|
29
|
-
return false unless success
|
13
|
+
def reset(uri)
|
14
|
+
return sparql_pull("CLEAR GRAPH <#{uri}>") # XXX: s/CLEAR/DROP/ was rejected (405)
|
15
|
+
end
|
30
16
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
17
|
+
# expects a hash of N-Triples by graph URI
|
18
|
+
def batch_update(triples_by_graph)
|
19
|
+
# apparently Virtuoso gets confused when mixing CLEAR and INSERT queries,
|
20
|
+
# so we have to do use separate requests
|
35
21
|
|
36
|
-
|
22
|
+
reset_queries = triples_by_graph.keys.map do |graph_uri|
|
23
|
+
"CLEAR GRAPH <#{graph_uri}>" # XXX: duplicates `reset`
|
37
24
|
end
|
25
|
+
success = sparql_query(reset_queries)
|
26
|
+
return false unless success
|
38
27
|
|
39
|
-
|
40
|
-
|
41
|
-
reset(uri)
|
42
|
-
|
43
|
-
if rdf_data
|
44
|
-
res = sparql_push(uri, rdf_data.strip, content_type)
|
45
|
-
else
|
46
|
-
res = sparql_pull(%{LOAD "#{uri}" INTO GRAPH <#{uri}>})
|
47
|
-
end
|
48
|
-
|
49
|
-
return res
|
28
|
+
insert_queries = triples_by_graph.map do |graph_uri, ntriples|
|
29
|
+
"INSERT IN GRAPH <#{graph_uri}> {\n#{ntriples}\n}"
|
50
30
|
end
|
31
|
+
success = sparql_query(insert_queries)
|
51
32
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
filename = uri.gsub(/[^0-9A-Za-z]/, "_") # XXX: too simplistic?
|
56
|
-
path = "/DAV/home/#{@username}/rdf_sink/#{filename}"
|
33
|
+
return success
|
34
|
+
end
|
57
35
|
|
58
|
-
|
59
|
-
|
60
|
-
|
36
|
+
# uses push method if `rdf_data` is provided, pull otherwise
|
37
|
+
def update(uri, rdf_data=nil, content_type=nil)
|
38
|
+
reset(uri)
|
61
39
|
|
62
|
-
|
40
|
+
if rdf_data
|
41
|
+
res = sparql_push(uri, rdf_data.strip, content_type)
|
42
|
+
else
|
43
|
+
res = sparql_pull(%{LOAD "#{uri}" INTO GRAPH <#{uri}>})
|
63
44
|
end
|
64
45
|
|
65
|
-
|
66
|
-
|
67
|
-
res = http_request("POST", path, query, {
|
68
|
-
"Content-Type" => "application/sparql-query"
|
69
|
-
})
|
70
|
-
return res.code == "200" # XXX: always returns 409
|
71
|
-
end
|
46
|
+
return res
|
47
|
+
end
|
72
48
|
|
73
|
-
|
74
|
-
|
75
|
-
query = query.join("\n\n") + "\n" rescue query
|
76
|
-
path = "/DAV/home/#{@username}/query"
|
49
|
+
def sparql_push(uri, rdf_data, content_type)
|
50
|
+
raise TypeError, "missing content type" unless content_type
|
77
51
|
|
78
|
-
|
79
|
-
|
80
|
-
})
|
52
|
+
filename = uri.gsub(/[^0-9A-Za-z]/, "_") # XXX: too simplistic?
|
53
|
+
path = "/DAV/home/#{@username}/rdf_sink/#{filename}"
|
81
54
|
|
82
|
-
|
83
|
-
|
55
|
+
res = http_request("PUT", path, rdf_data, { # XXX: is PUT correct here?
|
56
|
+
"Content-Type" => content_type
|
57
|
+
})
|
84
58
|
|
85
|
-
|
86
|
-
|
59
|
+
return res.code == "201"
|
60
|
+
end
|
87
61
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
62
|
+
def sparql_pull(query)
|
63
|
+
path = "/DAV/home/#{@username}/rdf_sink" # XXX: shouldn't this be /sparql?
|
64
|
+
res = http_request("POST", path, query, {
|
65
|
+
"Content-Type" => "application/sparql-query"
|
66
|
+
})
|
67
|
+
return res.code == "200" # XXX: always returns 409
|
68
|
+
end
|
92
69
|
|
93
|
-
|
94
|
-
|
70
|
+
# query is a string or an array of strings
|
71
|
+
def sparql_query(query)
|
72
|
+
query = query.join("\n\n") + "\n" rescue query
|
73
|
+
path = "/DAV/home/#{@username}/query"
|
95
74
|
|
75
|
+
res = http_request("POST", path, query, {
|
76
|
+
"Content-Type" => "application/sparql-query"
|
77
|
+
})
|
78
|
+
|
79
|
+
return res.code == "201"
|
96
80
|
end
|
81
|
+
|
97
82
|
end
|
data/test/base_test.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "test_helper")
|
2
|
+
|
3
|
+
require "iq_triplestorage"
|
4
|
+
|
5
|
+
class BaseTest < MiniTest::Unit::TestCase
|
6
|
+
|
7
|
+
def test_version
|
8
|
+
assert IqTriplestorage::VERSION.is_a?(String)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_host_normalization
|
12
|
+
host = "http://example.org"
|
13
|
+
adaptor = IqTriplestorage::BaseAdaptor.new(host)
|
14
|
+
assert_equal "/", adaptor.host.path
|
15
|
+
|
16
|
+
host = "http://example.org/"
|
17
|
+
adaptor = IqTriplestorage::BaseAdaptor.new(host)
|
18
|
+
assert_equal "/", adaptor.host.path
|
19
|
+
|
20
|
+
host = "http://example.org/foo"
|
21
|
+
adaptor = IqTriplestorage::BaseAdaptor.new(host)
|
22
|
+
assert_equal "/foo", adaptor.host.path
|
23
|
+
|
24
|
+
host = "http://example.org/foo/"
|
25
|
+
adaptor = IqTriplestorage::BaseAdaptor.new(host)
|
26
|
+
assert_equal "/foo/", adaptor.host.path
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/test/sesame_test.rb
CHANGED
@@ -13,33 +13,15 @@ class SesameTest < WebTestCase
|
|
13
13
|
{ :status => req.uri.to_s.end_with?("/rdf_sink") ? 200 : 201 }
|
14
14
|
end
|
15
15
|
|
16
|
-
@username = "foo"
|
17
|
-
@password = "bar"
|
18
16
|
@host = "http://example.org/sesame"
|
19
17
|
@repo = "test"
|
18
|
+
@username = "foo"
|
19
|
+
@password = "bar"
|
20
20
|
|
21
|
-
@adaptor = IqTriplestorage::SesameAdaptor.new(@host, @repo,
|
21
|
+
@adaptor = IqTriplestorage::SesameAdaptor.new(@host, :repository => @repo,
|
22
22
|
:username => @username, :password => @password)
|
23
23
|
end
|
24
24
|
|
25
|
-
def test_host_normalization
|
26
|
-
host = "http://example.org"
|
27
|
-
adaptor = IqTriplestorage::SesameAdaptor.new(host, "dummy")
|
28
|
-
assert_equal "/", adaptor.host.path
|
29
|
-
|
30
|
-
host = "http://example.org/"
|
31
|
-
adaptor = IqTriplestorage::SesameAdaptor.new(host, "dummy")
|
32
|
-
assert_equal "/", adaptor.host.path
|
33
|
-
|
34
|
-
host = "http://example.org/foo"
|
35
|
-
adaptor = IqTriplestorage::SesameAdaptor.new(host, "dummy")
|
36
|
-
assert_equal "/foo", adaptor.host.path
|
37
|
-
|
38
|
-
host = "http://example.org/foo/"
|
39
|
-
adaptor = IqTriplestorage::SesameAdaptor.new(host, "dummy")
|
40
|
-
assert_equal "/foo/", adaptor.host.path
|
41
|
-
end
|
42
|
-
|
43
25
|
def test_batch
|
44
26
|
data = {
|
45
27
|
"http://example.com/foo" => "<aaa> <bbb> <ccc> .\n<ddd> <eee> <fff> .",
|
data/test/virtuoso_test.rb
CHANGED
@@ -13,12 +13,11 @@ class VirtuosoTest < WebTestCase
|
|
13
13
|
{ :status => req.uri.to_s.end_with?("/rdf_sink") ? 200 : 201 }
|
14
14
|
end
|
15
15
|
|
16
|
+
@host = "http://example.org:8080"
|
16
17
|
@username = "foo"
|
17
18
|
@password = "bar"
|
18
|
-
@
|
19
|
-
|
20
|
-
@adaptor = IqTriplestorage::VirtuosoAdaptor.new("http://#{@host}", @port,
|
21
|
-
@username, @password)
|
19
|
+
@adaptor = IqTriplestorage::VirtuosoAdaptor.new(@host,
|
20
|
+
:username => @username, :password => @password)
|
22
21
|
end
|
23
22
|
|
24
23
|
def test_reset
|
@@ -121,7 +120,7 @@ INSERT IN GRAPH <#{graph_uri}> {
|
|
121
120
|
end
|
122
121
|
|
123
122
|
def ensure_basics(req) # TODO: rename
|
124
|
-
assert_equal
|
123
|
+
assert_equal @host, "#{req.uri.scheme}://#{req.uri.hostname}:#{req.uri.port}"
|
125
124
|
|
126
125
|
if auth_header = req.headers["Authorization"]
|
127
126
|
auth = Base64.encode64([@username, @password].join(":")).strip
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iq_triplestorage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-11-
|
12
|
+
date: 2012-11-21 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|
@@ -26,7 +26,7 @@ files:
|
|
26
26
|
- lib/iq_triplestorage.rb
|
27
27
|
- lib/iq_triplestorage/sesame_adaptor.rb
|
28
28
|
- lib/iq_triplestorage/virtuoso_adaptor.rb
|
29
|
-
- test/
|
29
|
+
- test/base_test.rb
|
30
30
|
- test/sesame_test.rb
|
31
31
|
- test/test_helper.rb
|
32
32
|
- test/virtuoso_test.rb
|
@@ -44,7 +44,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
44
44
|
version: '0'
|
45
45
|
segments:
|
46
46
|
- 0
|
47
|
-
hash: -
|
47
|
+
hash: -3716524453347900390
|
48
48
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
@@ -53,7 +53,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
53
53
|
version: '0'
|
54
54
|
segments:
|
55
55
|
- 0
|
56
|
-
hash: -
|
56
|
+
hash: -3716524453347900390
|
57
57
|
requirements: []
|
58
58
|
rubyforge_project: iq_triplestorage
|
59
59
|
rubygems_version: 1.8.23
|
@@ -61,7 +61,7 @@ signing_key:
|
|
61
61
|
specification_version: 3
|
62
62
|
summary: IqTriplestorage - library for interacting with RDF triplestores / quadstores
|
63
63
|
test_files:
|
64
|
-
- test/
|
64
|
+
- test/base_test.rb
|
65
65
|
- test/sesame_test.rb
|
66
66
|
- test/test_helper.rb
|
67
67
|
- test/virtuoso_test.rb
|
data/test/core_test.rb
DELETED