redlander 0.3.6 → 0.4.0

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