iq_triplestorage 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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