redlander 0.4.0 → 0.5.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/ChangeLog CHANGED
@@ -1,3 +1,11 @@
1
+ redlander (0.5.0)
2
+
3
+ * Model#query for queries in SPARQL (and other supported languages)
4
+ * model.statements.size is obsolete, use model.size or model.statements.count
5
+ * model.statements.delete_all accepts a pattern to delete only matching statements
6
+ * added "model.statements.exist?" checker, with a pattern
7
+ * bugfixes
8
+
1
9
  redlander (0.4.0)
2
10
 
3
11
  * deprecated Parser, Serializer, Storage, Stream and related classes and modules
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redlander (0.4.0)
4
+ redlander (0.5.0)
5
5
  ffi (~> 1.1)
6
6
  xml_schema (~> 0.1.0)
7
7
 
data/README.rdoc CHANGED
@@ -59,6 +59,20 @@ You can access the subject, predicate or object of a statement:
59
59
 
60
60
  Please refer to Redlander::Node API doc for details.
61
61
 
62
+ You can also use different query languages supported by librdf ("SPARQL 1.0" being a default):
63
+
64
+ $ m.query("SELECT ?s ?p ?o WHERE {}") # => [{"s" => ..., "p" => ..., "o" => ...}, ...]
65
+
66
+ "ASK" queries return true/false, "SELECT" queries return arrays of binding hashes,
67
+ "CONSTRUCT" queries return an instance of a new memory-based model comprised from
68
+ the statements constructed by the query.
69
+ You can also supply a block to Model#query, which is ignored by ASK queries, but
70
+ yields the statements constructed by CONSTRUCT queries and yields the binding
71
+ hash for SELECT queries. Binding hash values are instances of Redlander::Node.
72
+
73
+ For query options and available query languages refer to Model#query documentation.
74
+
75
+
62
76
  == Parsing Input
63
77
 
64
78
  You can fill your model with statements by parsing some external sources like plain or streamed data.
@@ -72,7 +86,7 @@ If the input is too large, you may prefer streaming it:
72
86
  $ m.from(source, :format => "ntriples")
73
87
 
74
88
  If you want to get the data from a local file, you can use "file://" schema for your URI
75
- (or Redlander::Uri) or use "from_file" method with a local file name (without schema):
89
+ or use "from_file" method with a local file name (without schema):
76
90
 
77
91
  $ m.from_file("../data.ttl", :format => "turtle")
78
92
 
data/lib/redland.rb CHANGED
@@ -27,10 +27,12 @@ module Redland
27
27
  attach_function :librdf_model_size, [:pointer], :int
28
28
  attach_function :librdf_model_find_statements, [:pointer, :pointer], :pointer
29
29
  attach_function :librdf_model_add_statement, [:pointer, :pointer], :int
30
+ attach_function :librdf_model_add_statements, [:pointer, :pointer], :int
30
31
  attach_function :librdf_model_remove_statement, [:pointer, :pointer], :int
31
32
  attach_function :librdf_model_transaction_start, [:pointer], :int
32
33
  attach_function :librdf_model_transaction_commit, [:pointer], :int
33
34
  attach_function :librdf_model_transaction_rollback, [:pointer], :int
35
+ attach_function :librdf_model_query_execute, [:pointer, :pointer], :pointer
34
36
 
35
37
  # Statement
36
38
  attach_function :librdf_free_statement, [:pointer], :void
@@ -85,4 +87,25 @@ module Redland
85
87
  attach_function :librdf_free_uri, [:pointer], :void
86
88
  attach_function :librdf_uri_to_string, [:pointer], :string
87
89
  attach_function :librdf_uri_equals, [:pointer, :pointer], :int
90
+
91
+ # Query
92
+ attach_function :librdf_new_query, [:pointer, :string, :pointer, :string, :pointer], :pointer
93
+ attach_function :librdf_free_query, [:pointer], :void
94
+ attach_function :librdf_query_get_limit, [:pointer], :int
95
+ attach_function :librdf_query_set_limit, [:pointer, :int], :int
96
+ attach_function :librdf_query_get_offset, [:pointer], :int
97
+ attach_function :librdf_query_set_limit, [:pointer, :int], :int
98
+ attach_function :librdf_query_results_is_bindings, [:pointer], :int
99
+ attach_function :librdf_query_results_is_boolean, [:pointer], :int
100
+ attach_function :librdf_query_results_is_graph, [:pointer], :int
101
+ attach_function :librdf_query_results_is_syntax, [:pointer], :int
102
+ attach_function :librdf_query_results_get_binding_name, [:pointer, :int], :string
103
+ attach_function :librdf_query_results_get_binding_value, [:pointer, :int], :pointer
104
+ attach_function :librdf_query_results_get_binding_value_by_name, [:pointer, :string], :pointer
105
+ attach_function :librdf_query_results_get_bindings_count, [:pointer], :int
106
+ attach_function :librdf_query_results_get_boolean, [:pointer], :int
107
+ attach_function :librdf_query_results_as_stream, [:pointer], :pointer
108
+ attach_function :librdf_query_results_next, [:pointer], :int
109
+ attach_function :librdf_query_results_finished, [:pointer], :int
110
+ attach_function :librdf_free_query_results, [:pointer], :void
88
111
  end
@@ -1,6 +1,7 @@
1
1
  require 'redlander/parsing'
2
2
  require 'redlander/serializing'
3
3
  require 'redlander/model_proxy'
4
+ require "redlander/query/results"
4
5
 
5
6
  module Redlander
6
7
  # The core object incorporating the repository of RDF statements.
@@ -66,6 +67,60 @@ module Redlander
66
67
  ModelProxy.new(self)
67
68
  end
68
69
 
70
+ # Size of the model, in statements.
71
+ #
72
+ # @return [Fixnum]
73
+ def size
74
+ s = Redland.librdf_model_size(@rdf_model)
75
+ s < 0 ? statements.count : s
76
+ end
77
+
78
+ # Query the model RDF graph using a query language
79
+ #
80
+ # @param [String] q the text of the query
81
+ # @param [Hash<Symbol => [String, URI]>] options options for the query
82
+ # @option options [String] :language language of the query, one of:
83
+ # - "sparql10" SPARQL 1.0 W3C RDF Query Language (default)
84
+ # - "sparql" SPARQL 1.1 (DRAFT) Query and Update Languages
85
+ # - "sparql11-query" SPARQL 1.1 (DRAFT) Query Language
86
+ # - "sparql11-update" SPARQL 1.1 (DRAFT) Update Language
87
+ # - "laqrs" LAQRS adds to Querying RDF in SPARQL
88
+ # - "rdql" RDF Data Query Language (RDQL)
89
+ # @option options [String] :language_uri URI of the query language, if applicable
90
+ # @option options [String] :base_uri base URI of the query, if applicable
91
+ # @return [void]
92
+ # @note
93
+ # The returned value is determined by the type of the query:
94
+ # - [Boolean] for SPARQL ASK queries (ignores block, if given)
95
+ # - [Redlander::Model] for SPARQL CONSTRUCT queries
96
+ # if given a block, yields the constructed statements to it instead
97
+ # - [Array<Hash>] for SPARQL SELECT queries
98
+ # where hash values are Redlander::Node instances;
99
+ # if given a block, yields each binding hash to it
100
+ # - nil, if query fails
101
+ # @raise [RedlandError] if fails to create a query
102
+ def query(q, options = {})
103
+ query = Query::Results.new(q, options)
104
+ query.process(self)
105
+ end
106
+
107
+ # Merge statements from another model
108
+ # (duplicates and invalid statements are skipped)
109
+ #
110
+ # @param [Redlander::Model] model
111
+ # @return [self]
112
+ def merge(model)
113
+ rdf_stream = Redland.librdf_model_as_stream(model.rdf_model)
114
+ raise RedlandError, "Failed to convert model to a stream" if rdf_stream.null?
115
+
116
+ begin
117
+ Redland.librdf_model_add_statements(@rdf_model, rdf_stream)
118
+ self
119
+ ensure
120
+ Redland.librdf_free_stream(rdf_stream)
121
+ end
122
+ end
123
+
69
124
  # Wrap changes to the given model in a transaction.
70
125
  # If an exception is raised in the block, the transaction is rolled back.
71
126
  #
@@ -44,12 +44,15 @@ module Redlander
44
44
  Redland.librdf_model_remove_statement(@model.rdf_model, statement.rdf_statement).zero?
45
45
  end
46
46
 
47
- # Delete all statements from the model.
47
+ # Delete all statements from the model,
48
+ # matching the given pattern
48
49
  #
49
- # @todo Fix this extremely ineffective (slow) implementation
50
+ # @param [Statement, Hash] pattern (see {#find})
50
51
  # @return [Boolean]
51
- def delete_all
52
- each { |st| delete(st) }
52
+ def delete_all(pattern = {})
53
+ result = true
54
+ each(pattern) { |st| result &&= delete(st) }
55
+ result
53
56
  end
54
57
 
55
58
  # Create a statement and add it to the model.
@@ -72,21 +75,13 @@ module Redlander
72
75
  size.zero?
73
76
  end
74
77
 
75
- # Size of the model in statements.
78
+ # Checks the existence of statements in the model
79
+ # matching the given criteria
76
80
  #
77
- # @note
78
- # While #count must iterate across all statements in the model,
79
- # {#size} tries to use a more efficient C implementation.
80
- # So {#size} should be preferred to #count in terms of performance.
81
- # However, for non-countable storages, {#size} falls back to
82
- # using #count. Also, {#size} is not available for enumerables
83
- # (e.g. produced from {#each} (without a block) or otherwise) and
84
- # thus cannot be used to count "filtered" results.
85
- #
86
- # @return [Fixnum]
87
- def size
88
- s = Redland.librdf_model_size(@model.rdf_model)
89
- s < 0 ? count : s
81
+ # @param [Hash, Statement] pattern (see {#find})
82
+ # @return [Boolean]
83
+ def exist?(pattern)
84
+ !first(pattern).nil?
90
85
  end
91
86
 
92
87
  # Enumerate (and filter) model statements.
@@ -94,7 +89,7 @@ module Redlander
94
89
  #
95
90
  # @param [Statement, Hash, void] args
96
91
  # if given Statement or Hash, filter the model statements
97
- # according to the specified pattern (see {#find} options).
92
+ # according to the specified pattern (see {#find} pattern).
98
93
  # @yieldparam [Statement]
99
94
  # @return [void]
100
95
  def each(*args)
@@ -103,7 +98,7 @@ module Redlander
103
98
  if args.empty?
104
99
  Redland.librdf_model_as_stream(@model.rdf_model)
105
100
  else
106
- pattern = args.first.is_a?(Statement) ? args.first.rdf_statement : Statement.new(args.first)
101
+ pattern = args.first.is_a?(Statement) ? args.first : Statement.new(args.first)
107
102
  Redland.librdf_model_find_statements(@model.rdf_model, pattern.rdf_statement)
108
103
  end
109
104
  raise RedlandError, "Failed to create a new stream" if rdf_stream.null?
@@ -125,37 +120,37 @@ module Redlander
125
120
  # Find statements satisfying the given criteria.
126
121
  #
127
122
  # @param [:first, :all] scope find just one or all matches
128
- # @param [Hash, Statement] options matching pattern made of:
123
+ # @param [Hash, Statement] pattern matching pattern made of:
129
124
  # - Hash with :subject, :predicate or :object nodes, or
130
125
  # - "patternized" Statement (nil nodes are matching anything).
131
126
  # @return [Statement, Array, nil]
132
- def find(scope, options = {})
127
+ def find(scope, pattern = {})
133
128
  case scope
134
129
  when :first
135
- each(options).first
130
+ each(pattern).first
136
131
  when :all
137
- each(options).to_a
132
+ each(pattern).to_a
138
133
  else
139
134
  raise RedlandError, "Invalid search scope '#{scope}' specified."
140
135
  end
141
136
  end
142
137
 
143
138
  # Find a first statement matching the given criteria.
144
- # (Shortcut for {#find}(:first, options)).
139
+ # (Shortcut for {#find}(:first, pattern)).
145
140
  #
146
- # @param [Hash] options (see {#find})
141
+ # @param [Statement, Hash] pattern (see {#find})
147
142
  # @return [Statement, nil]
148
- def first(options = {})
149
- find(:first, options)
143
+ def first(pattern = {})
144
+ find(:first, pattern)
150
145
  end
151
146
 
152
147
  # Find all statements matching the given criteria.
153
- # (Shortcut for {#find}(:all, options)).
148
+ # (Shortcut for {#find}(:all, pattern)).
154
149
  #
155
- # @param [Hash] options (see {#find})
150
+ # @param [Statement, Hash] pattern (see {#find})
156
151
  # @return [Array<Statement>]
157
- def all(options = {})
158
- find(:all, options)
152
+ def all(pattern = {})
153
+ find(:all, pattern)
159
154
  end
160
155
  end
161
156
  end
@@ -0,0 +1,118 @@
1
+ module Redlander
2
+ module Query
3
+ # @api private
4
+ class Results
5
+ include Enumerable
6
+
7
+ # (see Model#query)
8
+ def initialize(q, options = {})
9
+ language = options[:language] || "sparql10"
10
+ language_uri = options[:language_uri] && options[:language_uri].to_s
11
+ base_uri = options[:base_uri] && options[:base_uri].to_s
12
+
13
+ @rdf_query = Redland.librdf_new_query(Redlander.rdf_world, language, language_uri, q, base_uri)
14
+ raise RedlandError, "Failed to create a #{language.upcase} query from '#{q}'" if @rdf_query.null?
15
+
16
+ ObjectSpace.define_finalizer(self, proc { Redland.librdf_free_query(@rdf_query) })
17
+ end
18
+
19
+ def process(model)
20
+ @rdf_results = Redland.librdf_model_query_execute(model.rdf_model, @rdf_query)
21
+
22
+ if @rdf_results.null?
23
+ return nil
24
+ else
25
+ case
26
+ when bindings?
27
+ if block_given?
28
+ each { yield process_bindings }
29
+ else
30
+ map { process_bindings }
31
+ end
32
+ when boolean?
33
+ process_boolean
34
+ when graph?
35
+ if block_given?
36
+ process_graph { |statement| yield statement }
37
+ else
38
+ process_graph
39
+ end
40
+ when syntax?
41
+ process_syntax
42
+ else
43
+ raise RedlandError, "Cannot determine the type of query results"
44
+ end
45
+ end
46
+ ensure
47
+ Redland.librdf_free_query_results(@rdf_results)
48
+ end
49
+
50
+ def each
51
+ if block_given?
52
+ while Redland.librdf_query_results_finished(@rdf_results).zero?
53
+ yield self
54
+ Redland.librdf_query_results_next(@rdf_results)
55
+ end
56
+ else
57
+ enum_for(:each)
58
+ end
59
+ end
60
+
61
+ def bindings?
62
+ !Redland.librdf_query_results_is_bindings(@rdf_results).zero?
63
+ end
64
+
65
+ def boolean?
66
+ !Redland.librdf_query_results_is_boolean(@rdf_results).zero?
67
+ end
68
+
69
+ def graph?
70
+ !Redland.librdf_query_results_is_graph(@rdf_results).zero?
71
+ end
72
+
73
+ def syntax?
74
+ !Redland.librdf_query_results_is_syntax(@rdf_results).zero?
75
+ end
76
+
77
+ private
78
+
79
+ def process_bindings
80
+ {}.tap do |bindings|
81
+ n = Redland.librdf_query_results_get_bindings_count(@rdf_results)
82
+ while n > 0
83
+ name = Redland.librdf_query_results_get_binding_name(@rdf_results, n-1)
84
+ value = Redland.librdf_query_results_get_binding_value(@rdf_results, n-1)
85
+ bindings[name] = Node.new(value) unless value.null?
86
+ n -= 1
87
+ end
88
+ end
89
+ end
90
+
91
+ def process_boolean
92
+ value = Redland.librdf_query_results_get_boolean(@rdf_results)
93
+ return value >= 0 ? !value.zero? : nil
94
+ end
95
+
96
+ def process_graph
97
+ rdf_stream = Redland.librdf_query_results_as_stream(@rdf_results)
98
+ if block_given?
99
+ while Redland.librdf_stream_end(rdf_stream).zero?
100
+ statement = Statement.new(Redland.librdf_stream_get_object(rdf_stream))
101
+ yield statement
102
+ Redland.librdf_stream_next(rdf_stream)
103
+ end
104
+ else
105
+ Model.new.tap do |model|
106
+ Redland.librdf_model_add_statements(model.rdf_model, rdf_stream)
107
+ end
108
+ end
109
+ ensure
110
+ Redland.librdf_free_stream(rdf_stream)
111
+ end
112
+
113
+ def process_syntax
114
+ raise NotImplementedError, "Don't know how to handle syntax type results"
115
+ end
116
+ end
117
+ end
118
+ end
@@ -1,4 +1,4 @@
1
1
  module Redlander
2
2
  # Redlander version number
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
@@ -4,21 +4,111 @@ describe Model do
4
4
  let(:model) { described_class.new }
5
5
  subject { model }
6
6
 
7
- describe "statements" do
8
- subject { model.statements }
9
-
10
- it { should be_an_instance_of(ModelProxy) }
7
+ describe "size" do
8
+ subject { model.size }
11
9
 
12
10
  context "for a non-countable storage" do
13
11
  before do
14
- subject.create(statement_attributes)
12
+ model.statements.create(statement_attributes)
15
13
  Redland.stub(:librdf_model_size => -1)
16
14
  end
17
15
 
18
16
  it "should return size derived from count" do
19
- subject.size.should eql subject.count
17
+ subject.should eql model.statements.count
18
+ end
19
+ end
20
+ end
21
+
22
+ describe "query" do
23
+ before { model.from_file(Redlander.fixture_path("doap.ttl"), :format => "turtle") }
24
+ subject { model.query(q) }
25
+
26
+ describe "SPARQL" do
27
+ describe "SELECT" do
28
+ let(:q) { "PREFIX doap: <http://usefulinc.com/ns/doap#> SELECT ?name WHERE { <http://rubygems.org/gems/rdf> doap:name ?name }" }
29
+
30
+ it { should be_a Enumerable }
31
+
32
+ it "should return an array of binding hashes" do
33
+ expect(subject.size).to eql 1
34
+ expect(subject.first["name"]).to be_a Redlander::Node
35
+ expect(subject.first["name"].value).to eql "RDF.rb"
36
+ end
37
+
38
+ context "with a block" do
39
+ it "should yield a binding hash" do
40
+ subject do |binding|
41
+ expect(binding).to be_a Hash
42
+ expect(binding["name"]).to be_a Redlander::Node
43
+ expect(binding["name"].value).to eql "RDF.rb"
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ describe "ASK" do
50
+ let(:q) { "PREFIX doap: <http://usefulinc.com/ns/doap#> ASK { <http://rubygems.org/gems/rdf> doap:homepage <http://rdf.rubyforge.org/> }" }
51
+
52
+ it { should be_true }
53
+ end
54
+
55
+ describe "CONSTRUCT" do
56
+ let(:q) { "PREFIX doap: <http://usefulinc.com/ns/doap#> CONSTRUCT { ?project doap:framework 'RDF'^^<http://www.w3.org/2001/XMLSchema#string> } WHERE { ?project a doap:Project }" }
57
+
58
+ it { should be_a Redlander::Model }
59
+
60
+ it "should return a model made from the constructed statements" do
61
+ statement = Redlander::Statement.new(:subject => URI("http://rubygems.org/gems/rdf"),
62
+ :predicate => URI("http://usefulinc.com/ns/doap#framework"),
63
+ :object => "RDF")
64
+ expect(subject.statements.count).to eql 1
65
+ expect(subject.statements.exist?(statement)).to be_true
66
+ end
67
+ end
68
+
69
+ describe "DESCRIBE" do
70
+ let(:q) { "PREFIX doap: <http://usefulinc.com/ns/doap#> DESCRIBE ?gem WHERE { ?gem a doap:Project }" }
71
+
72
+ it { pending "Not implemented. See: http://bugs.librdf.org/mantis/view.php?id=135" }
20
73
  end
21
74
  end
75
+ end
76
+
77
+ describe "merge" do
78
+ before do
79
+ @model2 = Redlander::Model.new
80
+ @model3 = Redlander::Model.new
81
+ @statement1 = Redlander::Statement.new(:subject => URI("http://rubygems.org/gems/rdf"),
82
+ :predicate => URI("http://usefulinc.com/ns/doap#framework"),
83
+ :object => "RDF")
84
+ model.statements.add(@statement1)
85
+ @statement2 = Redlander::Statement.new(:subject => URI("http://rubygems.org/gems/rdfs"),
86
+ :predicate => URI("http://usefulinc.com/ns/doap#framework"),
87
+ :object => "RDFS")
88
+ @model2.statements.add(@statement2)
89
+ @model3.statements.add(@statement1)
90
+ end
91
+
92
+ it "should return model" do
93
+ expect(model.merge(@model2)).to eql model
94
+ end
95
+
96
+ it "should add different model statements" do
97
+ expect { model.merge(@model2) }.to change(model, :size).by(1)
98
+ expect(model.statements).to include(@statement1)
99
+ expect(model.statements).to include(@statement2)
100
+ end
101
+
102
+ it "should add same model statements" do
103
+ expect { model.merge(@model3) }.not_to change(model, :size)
104
+ expect(model.statements).to include(@statement1)
105
+ end
106
+ end
107
+
108
+ describe "statements" do
109
+ subject { model.statements }
110
+
111
+ it { should be_an_instance_of(ModelProxy) }
22
112
 
23
113
  context "when enumerated" do
24
114
  context "without a block" do
@@ -36,7 +126,7 @@ describe Model do
36
126
  it "should be iterated over" do
37
127
  expect {
38
128
  subject.each { |s| @statements << s }
39
- }.to change(@statements, :size).by(1)
129
+ }.to change(@statements, :count).by(1)
40
130
  expect(@statements).to include @statement
41
131
  end
42
132
  end
@@ -44,7 +134,6 @@ describe Model do
44
134
 
45
135
  context "when searched" do
46
136
  subject { model.statements.find(:first, @conditions) }
47
-
48
137
  before { @statement = model.statements.create(statement_attributes) }
49
138
 
50
139
  context "with empty conditions" do
@@ -66,16 +155,33 @@ describe Model do
66
155
  end
67
156
  end
68
157
 
158
+ context "when checked for existance" do
159
+ subject { model.statements.exist?(@conditions) }
160
+ before { @statement = model.statements.create(statement_attributes) }
161
+
162
+ context "with matching conditions" do
163
+ before { @conditions = {:object => @statement.object} }
164
+
165
+ it { should be_true }
166
+ end
167
+
168
+ context "with non-matching conditions" do
169
+ before { @conditions = {:object => "another object"} }
170
+
171
+ it { should be_false }
172
+ end
173
+ end
174
+
69
175
  context "when adding" do
70
176
  context "via #create" do
71
177
  it "should be created in the model" do
72
- expect { subject.create(statement_attributes) }.to change(subject, :size).by(1)
178
+ expect { subject.create(statement_attributes) }.to change(subject, :count).by(1)
73
179
  end
74
180
 
75
181
  it "should not add duplicate statements" do
76
182
  expect {
77
183
  2.times { subject.create(statement_attributes) }
78
- }.to change(subject, :size).by(1)
184
+ }.to change(subject, :count).by(1)
79
185
  end
80
186
  end
81
187
 
@@ -83,14 +189,14 @@ describe Model do
83
189
  before { @statement = Statement.new(statement_attributes) }
84
190
 
85
191
  it "should be added to the model" do
86
- expect { subject.add(@statement) }.to change(subject, :size).by(1)
192
+ expect { subject.add(@statement) }.to change(subject, :count).by(1)
87
193
  subject.should include(@statement)
88
194
  end
89
195
 
90
196
  it "should not add duplicate statements" do
91
197
  expect {
92
198
  2.times { subject.add(@statement) }
93
- }.to change(subject, :size).by(1)
199
+ }.to change(subject, :count).by(1)
94
200
  end
95
201
  end
96
202
  end
@@ -99,32 +205,22 @@ describe Model do
99
205
  before { @statement = subject.create(statement_attributes) }
100
206
 
101
207
  it "should be removed from the model" do
102
- expect { subject.delete(@statement) }.to change(subject, :size).by(-1)
208
+ expect { subject.delete(@statement) }.to change(subject, :count).by(-1)
103
209
  subject.should_not include(@statement)
104
210
  end
105
211
 
106
212
  describe "all statements" do
107
213
  before { subject.create(statement_attributes.merge(:object => "another one")) }
108
214
 
215
+ it "should selectively delete statements" do
216
+ expect { subject.delete_all(:object => "another one") }.to change(subject, :count).by(-1)
217
+ end
218
+
109
219
  it "should completely wipe the model" do
110
- expect { subject.delete_all }.to change(subject, :size).from(2).to(0)
220
+ expect { subject.delete_all }.to change(subject, :count).from(2).to(0)
111
221
  end
112
222
  end
113
223
  end
114
-
115
-
116
- private
117
-
118
- def statement_attributes
119
- s = URI.parse('http://example.com/concepts#subject')
120
- p = URI.parse('http://example.com/concepts#label')
121
- o = "subject!"
122
- {
123
- :subject => s,
124
- :predicate => p,
125
- :object => o
126
- }
127
- end
128
224
  end
129
225
 
130
226
  describe "serialization" do
@@ -200,13 +296,13 @@ describe Model do
200
296
  it "should parse from string" do
201
297
  expect {
202
298
  subject.from_rdfxml File.read(@filename), :base_uri => "http://rubygems.org/gems/rdf"
203
- }.to change(subject.statements, :size).by(62)
299
+ }.to change(subject.statements, :count).by(62)
204
300
  end
205
301
 
206
302
  it "should parse from URI/file" do
207
303
  expect {
208
304
  subject.from_rdfxml URI("file://" + @filename), :base_uri => "http://rubygems.org/gems/rdf"
209
- }.to change(subject.statements, :size).by(62)
305
+ }.to change(subject.statements, :count).by(62)
210
306
  end
211
307
 
212
308
  it "should filter statements" do
@@ -215,7 +311,7 @@ describe Model do
215
311
  subject.from_rdfxml URI("file://" + @filename), :base_uri => "http://rubygems.org/gems/rdf" do |st|
216
312
  st.object.resource? ? st.object.uri != filter_object : true
217
313
  end
218
- }.to change(subject.statements, :size).by(57)
314
+ }.to change(subject.statements, :count).by(57)
219
315
  end
220
316
  end
221
317
 
@@ -225,13 +321,13 @@ describe Model do
225
321
  it "should parse from string" do
226
322
  expect {
227
323
  subject.from_ntriples File.read(@filename)
228
- }.to change(subject.statements, :size).by(62)
324
+ }.to change(subject.statements, :count).by(62)
229
325
  end
230
326
 
231
327
  it "should parse from URI/file" do
232
328
  expect {
233
329
  subject.from_ntriples URI("file://" + @filename)
234
- }.to change(subject.statements, :size).by(62)
330
+ }.to change(subject.statements, :count).by(62)
235
331
  end
236
332
  end
237
333
 
@@ -241,13 +337,13 @@ describe Model do
241
337
  it "should parse from string" do
242
338
  expect {
243
339
  subject.from_turtle File.read(@filename), :base_uri => "http://rubygems.org/gems/rdf"
244
- }.to change(subject.statements, :size).by(62)
340
+ }.to change(subject.statements, :count).by(62)
245
341
  end
246
342
 
247
343
  it "should parse from URI/file" do
248
344
  expect {
249
345
  subject.from_turtle URI("file://" + @filename), :base_uri => "http://rubygems.org/gems/rdf"
250
- }.to change(subject.statements, :size).by(62)
346
+ }.to change(subject.statements, :count).by(62)
251
347
  end
252
348
  end
253
349
  end
@@ -301,4 +397,18 @@ describe Model do
301
397
  end
302
398
  end
303
399
  end
400
+
401
+
402
+ private
403
+
404
+ def statement_attributes
405
+ s = URI.parse('http://example.com/concepts#subject')
406
+ p = URI.parse('http://example.com/concepts#label')
407
+ o = "subject!"
408
+ {
409
+ :subject => s,
410
+ :predicate => p,
411
+ :object => o
412
+ }
413
+ end
304
414
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redlander
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
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-07-23 00:00:00.000000000 Z
12
+ date: 2012-07-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: xml_schema
@@ -87,6 +87,7 @@ files:
87
87
  - lib/redlander/model_proxy.rb
88
88
  - lib/redlander/node.rb
89
89
  - lib/redlander/parsing.rb
90
+ - lib/redlander/query/results.rb
90
91
  - lib/redlander/serializing.rb
91
92
  - lib/redlander/statement.rb
92
93
  - lib/redlander/uri.rb
@@ -116,7 +117,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
116
117
  version: '0'
117
118
  segments:
118
119
  - 0
119
- hash: 3614393653179496496
120
+ hash: -3720732623496571962
120
121
  required_rubygems_version: !ruby/object:Gem::Requirement
121
122
  none: false
122
123
  requirements:
@@ -125,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
126
  version: '0'
126
127
  segments:
127
128
  - 0
128
- hash: 3614393653179496496
129
+ hash: -3720732623496571962
129
130
  requirements: []
130
131
  rubyforge_project:
131
132
  rubygems_version: 1.8.24