redlander 0.3.6 → 0.4.0
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/.gitignore +20 -0
- data/ChangeLog +19 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +30 -0
- data/LICENSE +7 -0
- data/README.rdoc +85 -12
- data/Rakefile +5 -4
- data/lib/redland.rb +6 -2
- data/lib/redlander.rb +5 -3
- data/lib/redlander/model.rb +98 -16
- data/lib/redlander/model_proxy.rb +115 -58
- data/lib/redlander/node.rb +62 -59
- data/lib/redlander/parsing.rb +123 -0
- data/lib/redlander/serializing.rb +89 -0
- data/lib/redlander/statement.rb +61 -60
- data/lib/redlander/uri.rb +20 -13
- data/lib/redlander/version.rb +2 -1
- data/redlander.gemspec +28 -0
- data/spec/fixtures/doap.nt +62 -0
- data/spec/fixtures/doap.rdf +189 -0
- data/spec/fixtures/doap.ttl +53 -0
- data/spec/lib/redlander/model_spec.rb +304 -0
- data/spec/{redlander → lib/redlander}/node_spec.rb +26 -12
- data/spec/lib/redlander/statement_spec.rb +56 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +15 -4
- metadata +49 -37
- data/lib/redlander/error_container.rb +0 -42
- data/lib/redlander/parser.rb +0 -92
- data/lib/redlander/parser_proxy.rb +0 -22
- data/lib/redlander/serializer.rb +0 -85
- data/lib/redlander/storage.rb +0 -56
- data/lib/redlander/stream.rb +0 -57
- data/lib/redlander/stream_enumerator.rb +0 -17
- data/spec/redlander/model_spec.rb +0 -255
- data/spec/redlander/parser_spec.rb +0 -96
- data/spec/redlander/serializer_spec.rb +0 -52
- data/spec/redlander/statement_spec.rb +0 -77
@@ -1,22 +0,0 @@
|
|
1
|
-
require 'redlander/stream'
|
2
|
-
require 'redlander/stream_enumerator'
|
3
|
-
|
4
|
-
module Redlander
|
5
|
-
class ParserProxy
|
6
|
-
include StreamEnumerator
|
7
|
-
|
8
|
-
def initialize(parser, content, options = {})
|
9
|
-
# TODO: consider a streaming content, as it may be large to fit in memory
|
10
|
-
@parser = parser
|
11
|
-
@content = content
|
12
|
-
@options = options
|
13
|
-
end
|
14
|
-
|
15
|
-
|
16
|
-
private
|
17
|
-
|
18
|
-
def reset_stream
|
19
|
-
@stream = Stream.new(@parser, @content, @options)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/lib/redlander/serializer.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
module Redlander
|
2
|
-
class Serializer
|
3
|
-
# Create a new serializer.
|
4
|
-
# Name can be either of [:rdfxml, :ntriples, :turtle, :json, :dot],
|
5
|
-
# or nil, which defaults to :rdfxml.
|
6
|
-
#
|
7
|
-
# TODO: Only a small subset of parsers is implemented,
|
8
|
-
# because the rest seem to be very buggy.
|
9
|
-
def initialize(name = :rdfxml)
|
10
|
-
@rdf_serializer = Redland.librdf_new_serializer(Redlander.rdf_world, name.to_s, nil, nil)
|
11
|
-
raise RedlandError.new("Failed to create a new serializer") if @rdf_serializer.null?
|
12
|
-
ObjectSpace.define_finalizer(self, proc { Redland.librdf_free_serializer(@rdf_serializer) })
|
13
|
-
end
|
14
|
-
|
15
|
-
# Serialize a model into a string.
|
16
|
-
#
|
17
|
-
# Options are:
|
18
|
-
# :base_uri base URI (String or URI)
|
19
|
-
def to_string(model, options = {})
|
20
|
-
base_uri = if options.has_key?(:base_uri)
|
21
|
-
Uri.new(options[:base_uri]).rdf_uri
|
22
|
-
else
|
23
|
-
nil
|
24
|
-
end
|
25
|
-
Redland.librdf_serializer_serialize_model_to_string(@rdf_serializer, base_uri, model.rdf_model)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Serializes a model and stores it in a file
|
29
|
-
# filename - the name of the file to serialize to
|
30
|
-
# model - model instance
|
31
|
-
#
|
32
|
-
# Options are:
|
33
|
-
# :base_uri base URI (String or URI)
|
34
|
-
#
|
35
|
-
# Returns true on success, or false.
|
36
|
-
def to_file(model, filename, options = {})
|
37
|
-
base_uri = if options.has_key?(:base_uri)
|
38
|
-
Uri.new(options[:base_uri]).rdf_uri
|
39
|
-
else
|
40
|
-
nil
|
41
|
-
end
|
42
|
-
Redland.librdf_serializer_serialize_model_to_file(@rdf_serializer, filename, base_uri, model.rdf_model).zero?
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
# Applied to Model
|
48
|
-
module SerializingInstanceMethods
|
49
|
-
def to_rdfxml(options = {})
|
50
|
-
serializer = Serializer.new(:rdfxml)
|
51
|
-
serializer.to_string(self, options)
|
52
|
-
end
|
53
|
-
|
54
|
-
def to_ntriples(options = {})
|
55
|
-
serializer = Serializer.new(:ntriples)
|
56
|
-
serializer.to_string(self, options)
|
57
|
-
end
|
58
|
-
|
59
|
-
def to_turtle(options = {})
|
60
|
-
serializer = Serializer.new(:turtle)
|
61
|
-
serializer.to_string(self, options)
|
62
|
-
end
|
63
|
-
|
64
|
-
def to_json(options = {})
|
65
|
-
serializer = Serializer.new(:json)
|
66
|
-
serializer.to_string(self, options)
|
67
|
-
end
|
68
|
-
|
69
|
-
def to_dot(options = {})
|
70
|
-
serializer = Serializer.new(:dot)
|
71
|
-
serializer.to_string(self, options)
|
72
|
-
end
|
73
|
-
|
74
|
-
# Serialize the model into a file.
|
75
|
-
#
|
76
|
-
# Options are:
|
77
|
-
# :format - output format [:rdfxml (default), :ntriples, :turtle, :json, :dot]
|
78
|
-
# :base_uri - base URI
|
79
|
-
def to_file(filename, options = {})
|
80
|
-
serializer_options = options.dup
|
81
|
-
serializer = Serializer.new(serializer_options.delete(:format) || :rdfxml)
|
82
|
-
serializer.to_file(self, filename, serializer_options)
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
data/lib/redlander/storage.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
module Redlander
|
2
|
-
class Storage
|
3
|
-
attr_reader :rdf_storage
|
4
|
-
|
5
|
-
# Creates a store of the given type
|
6
|
-
#
|
7
|
-
# Store types (:storage option) are:
|
8
|
-
# :memory
|
9
|
-
# :hashes
|
10
|
-
# :file - memory model initialized from RDF/XML file
|
11
|
-
# :uri - read-only memory model with URI provided in 'name' arg
|
12
|
-
# :mysql
|
13
|
-
# :sqlite
|
14
|
-
# :postgresql
|
15
|
-
# :tstore
|
16
|
-
# :virtuoso
|
17
|
-
# ... anything else that Redland can handle.
|
18
|
-
#
|
19
|
-
# Options are storage-specific.
|
20
|
-
# Read the documentation for the appropriate Redland Storage module.
|
21
|
-
#
|
22
|
-
# :name - ?
|
23
|
-
# :host - database host name (for store types: :postgres, :mysql, :tstore)
|
24
|
-
# :port - database host port (for store types: :postgres, :mysql, :tstore)
|
25
|
-
# :database - database name (for store types: :postgres, :mysql, :tstore)
|
26
|
-
# :user - database user name (for store types: :postgres, :mysql, :tstore)
|
27
|
-
# :password - database user password (for store types: :postgres, :mysql, :tstore)
|
28
|
-
# :hash_type - hash type (for store types: :bdb)
|
29
|
-
# can be either 'memory' or 'bdb'
|
30
|
-
# :new - force creation of a new store
|
31
|
-
# :dir - directory path (for store types: :hashes)
|
32
|
-
# :contexts - support contexts (for store types: :hashes, :memory)
|
33
|
-
# :write - allow writing data to the store (for store types: :hashes)
|
34
|
-
#
|
35
|
-
# NOTE: When dealing with databases,
|
36
|
-
# Redland (1.0.7) just crashes when the required tables aren't available!
|
37
|
-
def initialize(options = {})
|
38
|
-
storage_type, storage_options = split_options(options.dup)
|
39
|
-
|
40
|
-
@rdf_storage = Redland.librdf_new_storage(Redlander.rdf_world,
|
41
|
-
storage_type.to_s,
|
42
|
-
storage_options.delete(:name).to_s,
|
43
|
-
Redlander.to_rdf_options(storage_options))
|
44
|
-
raise RedlandError.new("Failed to initialize '#{storage_type}' storage") if @rdf_storage.null?
|
45
|
-
ObjectSpace.define_finalizer(self, proc { Redland.librdf_free_storage(@rdf_storage) })
|
46
|
-
end
|
47
|
-
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def split_options(options)
|
52
|
-
storage_type = options.delete(:storage) || :memory
|
53
|
-
[storage_type, options]
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
data/lib/redlander/stream.rb
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
module Redlander
|
2
|
-
class Stream
|
3
|
-
attr_reader :rdf_stream
|
4
|
-
|
5
|
-
# Convert something to an RDF stream.
|
6
|
-
# Source can be:
|
7
|
-
# Parser - to parse content into a stream
|
8
|
-
# Model - to convert a model to an RDF stream, or
|
9
|
-
# if content (Statement) supplied,
|
10
|
-
# produce a stream of statements from the given model,
|
11
|
-
# matching the non-empty nodes of the given statement.
|
12
|
-
def initialize(source, content = nil, options = {})
|
13
|
-
@rdf_stream = case source
|
14
|
-
when Model
|
15
|
-
if content.is_a?(Statement)
|
16
|
-
Redland.librdf_model_find_statements(source.rdf_model, content.rdf_statement)
|
17
|
-
else
|
18
|
-
Redland.librdf_model_as_stream(source.rdf_model)
|
19
|
-
end
|
20
|
-
when Parser
|
21
|
-
base_uri = options[:base_uri] ? Uri.new(options[:base_uri]).rdf_uri : nil
|
22
|
-
Redland.librdf_parser_parse_string_as_stream(source.rdf_parser, content, base_uri)
|
23
|
-
else
|
24
|
-
# TODO
|
25
|
-
raise NotImplementedError.new
|
26
|
-
end
|
27
|
-
raise RedlandError.new("Failed to create a new stream") if @rdf_stream.null?
|
28
|
-
ObjectSpace.define_finalizer(self, proc { Redland.librdf_free_stream(@rdf_stream) })
|
29
|
-
end
|
30
|
-
|
31
|
-
# End-of-stream?
|
32
|
-
def eos?
|
33
|
-
Redland.librdf_stream_end(@rdf_stream) != 0
|
34
|
-
end
|
35
|
-
|
36
|
-
# Move stream pointer forward
|
37
|
-
def succ
|
38
|
-
Redland.librdf_stream_next(@rdf_stream).zero?
|
39
|
-
end
|
40
|
-
|
41
|
-
# Current statement in the stream, or nil
|
42
|
-
def current
|
43
|
-
Statement.new(self) unless eos?
|
44
|
-
end
|
45
|
-
|
46
|
-
# Return all the remaining statements in the stream
|
47
|
-
# from the current position.
|
48
|
-
def tail
|
49
|
-
[].tap do |all|
|
50
|
-
while !eos?
|
51
|
-
all << current
|
52
|
-
succ
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module Redlander
|
2
|
-
module StreamEnumerator
|
3
|
-
include Enumerable
|
4
|
-
|
5
|
-
def each
|
6
|
-
if block_given?
|
7
|
-
reset_stream
|
8
|
-
while !@stream.eos?
|
9
|
-
yield @stream.current
|
10
|
-
@stream.succ
|
11
|
-
end
|
12
|
-
else
|
13
|
-
raise ::LocalJumpError.new("no block given")
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,255 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Model do
|
4
|
-
|
5
|
-
before { @model = Model.new }
|
6
|
-
|
7
|
-
describe "statements" do
|
8
|
-
|
9
|
-
it { @model.statements.should be_an_instance_of(ModelProxy) }
|
10
|
-
|
11
|
-
it "should be created in the model" do
|
12
|
-
lambda {
|
13
|
-
@model.statements.create(statement_attributes)
|
14
|
-
}.should change(@model.statements, :size).by(1)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "should be iterated over" do
|
18
|
-
statement = @model.statements.create(statement_attributes)
|
19
|
-
statements = []
|
20
|
-
lambda {
|
21
|
-
@model.statements.each do |s|
|
22
|
-
statements << s
|
23
|
-
end
|
24
|
-
}.should change(statements, :size).by(1)
|
25
|
-
statements.first.should eql(statement)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should be added to the model" do
|
29
|
-
statement = Statement.new(statement_attributes)
|
30
|
-
lambda {
|
31
|
-
@model.statements.add(statement)
|
32
|
-
}.should change(@model.statements, :size).by(1)
|
33
|
-
@model.statements.should include(statement)
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should be found without a block" do
|
37
|
-
statement = @model.statements.create(statement_attributes)
|
38
|
-
@model.statements.find(:first).should eql(statement)
|
39
|
-
@model.statements.first.should eql(statement)
|
40
|
-
@model.statements.all.should eql([statement])
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should be found with a block" do
|
44
|
-
statements = []
|
45
|
-
statement = @model.statements.create(statement_attributes)
|
46
|
-
lambda {
|
47
|
-
@model.statements.each do |st|
|
48
|
-
statements << st
|
49
|
-
end
|
50
|
-
}.should change(statements, :size).by(1)
|
51
|
-
statements.first.should eql(statement)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "should be found by an attribute" do
|
55
|
-
statements = []
|
56
|
-
statement = @model.statements.create(statement_attributes)
|
57
|
-
lambda {
|
58
|
-
@model.statements.find(:all, :object => statement.object).each do |st|
|
59
|
-
statements << st
|
60
|
-
end
|
61
|
-
}.should change(statements, :size).by(1)
|
62
|
-
statements.first.should eql(statement)
|
63
|
-
end
|
64
|
-
|
65
|
-
it "should not be found with a block" do
|
66
|
-
statements = []
|
67
|
-
statement = @model.statements.create(statement_attributes)
|
68
|
-
lambda {
|
69
|
-
@model.statements.find(:all, :object => "another object").each do |st|
|
70
|
-
statements << st
|
71
|
-
end
|
72
|
-
}.should_not change(statements, :size)
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should be removed from the model" do
|
76
|
-
statement = @model.statements.create(statement_attributes)
|
77
|
-
lambda {
|
78
|
-
@model.statements.delete(statement)
|
79
|
-
}.should change(@model.statements, :size).by(-1)
|
80
|
-
@model.statements.should_not include(statement)
|
81
|
-
end
|
82
|
-
|
83
|
-
|
84
|
-
private
|
85
|
-
|
86
|
-
def statement_attributes
|
87
|
-
s = URI.parse('http://example.com/concepts#subject')
|
88
|
-
p = URI.parse('http://example.com/concepts#label')
|
89
|
-
o = "subject!"
|
90
|
-
{
|
91
|
-
:subject => s,
|
92
|
-
:predicate => p,
|
93
|
-
:object => o
|
94
|
-
}
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
describe "serialization" do
|
100
|
-
|
101
|
-
before :each do
|
102
|
-
s = URI.parse("http://example.com/concepts#two-dimensional_seismic_imaging")
|
103
|
-
p = URI.parse("http://www.w3.org/2000/01/rdf-schema#label")
|
104
|
-
o = "2-D seismic imaging@en"
|
105
|
-
@model.statements.create(:subject => s, :predicate => p, :object => o)
|
106
|
-
end
|
107
|
-
|
108
|
-
it "should produce RDF/XML content" do
|
109
|
-
content = @model.to_rdfxml
|
110
|
-
content.should be_an_instance_of(String)
|
111
|
-
content.should include('2-D seismic imaging')
|
112
|
-
end
|
113
|
-
|
114
|
-
it "should produce N-Triples content" do
|
115
|
-
content = @model.to_ntriples
|
116
|
-
content.should be_an_instance_of(String)
|
117
|
-
content.should include('2-D seismic imaging@en')
|
118
|
-
end
|
119
|
-
|
120
|
-
it "should produce Turtle content" do
|
121
|
-
content = @model.to_turtle
|
122
|
-
content.should be_an_instance_of(String)
|
123
|
-
content.should include('2-D seismic imaging@en')
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should produce JSON content" do
|
127
|
-
content = @model.to_json
|
128
|
-
content.should be_an_instance_of(String)
|
129
|
-
content.should include('2-D seismic imaging@en')
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should produce DOT content" do
|
133
|
-
content = @model.to_dot
|
134
|
-
content.should be_an_instance_of(String)
|
135
|
-
content.should include('2-D seismic imaging@en')
|
136
|
-
end
|
137
|
-
|
138
|
-
describe "file source" do
|
139
|
-
|
140
|
-
before :each do
|
141
|
-
content = '<?xml version="1.0" encoding="utf-8"?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="http://example.com/concepts#two-dimensional_seismic_imaging"><ns0:label xmlns:ns0="http://www.w3.org/2000/01/rdf-schema#" xml:lang="en">2-D seismic imaging</ns0:label></rdf:Description></rdf:RDF>'
|
142
|
-
reference_model = Model.new
|
143
|
-
reference_model.from_rdfxml(content, :base_uri => 'http://example.com/concepts')
|
144
|
-
reference_model.to_file(filename)
|
145
|
-
end
|
146
|
-
|
147
|
-
after :each do
|
148
|
-
cleanup
|
149
|
-
end
|
150
|
-
|
151
|
-
it "should be loaded from a file" do
|
152
|
-
lambda {
|
153
|
-
@model.from_file(filename, :base_uri => 'http://example.com/concepts')
|
154
|
-
}.should change(@model.statements, :size).by(1)
|
155
|
-
end
|
156
|
-
|
157
|
-
end
|
158
|
-
|
159
|
-
describe "file destination" do
|
160
|
-
|
161
|
-
before :each do
|
162
|
-
cleanup
|
163
|
-
end
|
164
|
-
|
165
|
-
after :each do
|
166
|
-
cleanup
|
167
|
-
end
|
168
|
-
|
169
|
-
it "should produce a file" do
|
170
|
-
@model.to_file(filename)
|
171
|
-
File.should be_exists(filename)
|
172
|
-
File.size(filename).should_not be_zero
|
173
|
-
end
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
private
|
178
|
-
|
179
|
-
def cleanup
|
180
|
-
File.delete(filename) if File.exists?(filename)
|
181
|
-
end
|
182
|
-
|
183
|
-
def filename
|
184
|
-
"test_model.rdf"
|
185
|
-
end
|
186
|
-
|
187
|
-
end
|
188
|
-
|
189
|
-
describe "deserialization" do
|
190
|
-
|
191
|
-
it "should be successful for RDF/XML data" do
|
192
|
-
content = '<?xml version="1.0" encoding="utf-8"?><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"><rdf:Description rdf:about="http://example.com/concepts#two-dimensional_seismic_imaging"><ns0:label xmlns:ns0="http://www.w3.org/2000/01/rdf-schema#" xml:lang="en">2-D seismic imaging</ns0:label></rdf:Description></rdf:RDF>'
|
193
|
-
lambda {
|
194
|
-
@model.from_rdfxml(content, :base_uri => 'http://example.com/concepts')
|
195
|
-
}.should change(@model.statements, :size).by(1)
|
196
|
-
end
|
197
|
-
|
198
|
-
it "should be successful for N-Triples data" do
|
199
|
-
content = '<http://example.org/ns/a2> <http://example.org/ns/b2> <http://example.org/ns/c2> .'
|
200
|
-
lambda {
|
201
|
-
@model.from_ntriples(content)
|
202
|
-
}.should change(@model.statements, :size).by(1)
|
203
|
-
end
|
204
|
-
|
205
|
-
it "should be successful for Turtle data" do
|
206
|
-
content = '# this is a complete turtle document
|
207
|
-
@prefix foo: <http://example.org/ns#> .
|
208
|
-
@prefix : <http://other.example.org/ns#> .
|
209
|
-
foo:bar foo: : .'
|
210
|
-
lambda {
|
211
|
-
@model.from_turtle(content, :base_uri => 'http://example.com/concepts')
|
212
|
-
}.should change(@model.statements, :size).by(1)
|
213
|
-
end
|
214
|
-
|
215
|
-
end
|
216
|
-
|
217
|
-
describe "transactions" do
|
218
|
-
before do
|
219
|
-
Redland.stub(:librdf_model_transaction_start => 0,
|
220
|
-
:librdf_model_transaction_commit => 0,
|
221
|
-
:librdf_model_transaction_rollback => 0)
|
222
|
-
end
|
223
|
-
|
224
|
-
context "when start fails" do
|
225
|
-
before { Redland.stub(:librdf_model_transaction_start => -1) }
|
226
|
-
|
227
|
-
it "should raise RedlandError" do
|
228
|
-
lambda {
|
229
|
-
@model.transaction { true }
|
230
|
-
}.should raise_exception RedlandError
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
context "when commit fails" do
|
235
|
-
before { Redland.stub(:librdf_model_transaction_commit => -1) }
|
236
|
-
|
237
|
-
it "should raise RedlandError" do
|
238
|
-
lambda {
|
239
|
-
@model.transaction { true }
|
240
|
-
}.should raise_exception RedlandError
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
context "when rollback fails" do
|
245
|
-
before { Redland.stub(:librdf_model_transaction_rollback => -1) }
|
246
|
-
|
247
|
-
it "should raise RedlandError" do
|
248
|
-
lambda {
|
249
|
-
@model.rollback
|
250
|
-
}.should raise_exception RedlandError
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
end
|