sedna 0.3.0 → 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.
Files changed (7) hide show
  1. data/CHANGES +18 -0
  2. data/README +35 -13
  3. data/Rakefile +3 -3
  4. data/ext/extconf.rb +4 -9
  5. data/ext/sedna.c +429 -118
  6. data/test/sedna_test.rb +447 -317
  7. metadata +2 -2
data/test/sedna_test.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # encoding: utf-8
3
3
 
4
- # Copyright 2008 Voormedia B.V.
4
+ # Copyright 2008, 2009 Voormedia B.V.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -30,53 +30,42 @@ require 'socket'
30
30
  class SednaTest < Test::Unit::TestCase
31
31
  # Support declarative specification of test methods.
32
32
  def self.test name, &block
33
- test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
34
- defined = instance_method(test_name) rescue false
35
- raise "#{test_name} is already defined in #{self}" if defined
36
- if block_given?
37
- define_method test_name, &block
38
- else
39
- define_method test_name do
40
- flunk "No implementation provided for #{test_name}"
41
- end
42
- end
33
+ define_method "test_#{name.gsub(/\s+/,'_')}".to_sym, &block
43
34
  end
44
35
 
36
+ # Backward compatibility if __method__ is not available.
45
37
  alias :__method__ :method_name if method_defined? :method_name
46
38
 
47
- # Setup.
48
- def setup
49
- @connection = {
50
- :database => "test",
51
- :host => "localhost",
52
- :username => "SYSTEM",
53
- :password => "MANAGER",
54
- }
55
- end
39
+ @@spec = {
40
+ :database => "test",
41
+ :host => "localhost",
42
+ :username => "SYSTEM",
43
+ :password => "MANAGER",
44
+ }
45
+
46
+ # Test the remote socket before continuing.
47
+ port = 5050
48
+ begin
49
+ socket = TCPSocket.new @@spec[:host], port
50
+ rescue Errno::ECONNREFUSED, SocketError
51
+ # No DB appears to be running; fail fatally. Do not run the other tests and just exit.
52
+ puts "\nConnection to port #{port} on #{@@spec[:host]} could not be established.\nCheck if the Sedna XML database is running before running this test suite.\n\n"
53
+ exit 1
54
+ end
55
+ socket.close
56
+
57
+ # Create re-usable connection. Word of warning: because we re-use the connection,
58
+ # if one particular test screws it up, subsequent tests may fail.
59
+ @@sedna = Sedna.connect @@spec
56
60
 
57
- # Faux test that just checks if we can connect, otherwise the test
58
- # suite is aborted.
59
- test "aaa connection" do
60
- port = 5050
61
- begin
62
- s = TCPSocket.new @connection[:host], port
63
- rescue Errno::ECONNREFUSED, SocketError
64
- # No DB appears to be running; fail fatally. Do not run the other tests and just exit.
65
- puts "Connection to port #{port} on #{@connection[:host]} could not be established. Check if the Sedna XML database is running before running this test suite."
66
- exit 1
67
- end
68
- assert s
69
- s.close
70
- end
71
-
72
61
  # Test Sedna.version.
73
- test "version should return 3 0" do
62
+ test "version should return 3.0" do
74
63
  assert_equal "3.0", Sedna.version
75
64
  end
76
65
 
77
66
  # Test Sedna.blocking?
78
67
  test "blocking should return true if ruby 18 and false if ruby 19" do
79
- if RUBY_VERSION < "1.9"
68
+ if RUBY_VERSION < "1.9.1"
80
69
  assert Sedna.blocking?
81
70
  else
82
71
  assert !Sedna.blocking?
@@ -85,7 +74,7 @@ class SednaTest < Test::Unit::TestCase
85
74
 
86
75
  # Test Sedna.connect.
87
76
  test "connect should return Sedna object" do
88
- sedna = Sedna.connect @connection
77
+ sedna = Sedna.connect @@spec
89
78
  assert_kind_of Sedna, sedna
90
79
  sedna.close
91
80
  end
@@ -98,32 +87,40 @@ class SednaTest < Test::Unit::TestCase
98
87
 
99
88
  test "connect should raise exception when host not found" do
100
89
  assert_raises Sedna::ConnectionError do
101
- Sedna.connect @connection.merge(:host => "non-existent-host")
90
+ Sedna.connect @@spec.merge(:host => "non-existent-host")
102
91
  end
103
92
  end
104
93
 
105
94
  test "connect should raise exception when credentials are incorrect" do
106
95
  assert_raises Sedna::AuthenticationError do
107
- Sedna.connect @connection.merge(:username => "non-existent-user")
96
+ Sedna.connect @@spec.merge(:username => "non-existent-user")
108
97
  end
109
98
  end
110
99
 
111
100
  test "connect should return nil on error" do
112
101
  begin
113
- sedna = Sedna.connect @connection.merge(:username => "non-existent-user")
102
+ sedna = Sedna.connect @@spec.merge(:username => "non-existent-user")
114
103
  rescue
115
104
  end
116
105
  assert_nil sedna
117
106
  end
118
107
 
108
+ test "connect should not execute block if connection fails" do
109
+ assert_nothing_raised do
110
+ sedna = Sedna.connect @@spec.merge(:username => "non-existent-user") do
111
+ raise "block should not be run"
112
+ end rescue nil
113
+ end
114
+ end
115
+
119
116
  test "connect should return nil if block given" do
120
- sedna = Sedna.connect @connection do |s| end
117
+ sedna = Sedna.connect @@spec do |s| end
121
118
  assert_nil sedna
122
119
  end
123
120
 
124
121
  test "connect should close connection after block" do
125
122
  sedna = nil
126
- Sedna.connect @connection do |s|
123
+ Sedna.connect @@spec do |s|
127
124
  sedna = s
128
125
  end
129
126
  assert_raises Sedna::ConnectionError do
@@ -134,7 +131,7 @@ class SednaTest < Test::Unit::TestCase
134
131
  test "connect should close connection if exception is raised inside block" do
135
132
  sedna = nil
136
133
  begin
137
- Sedna.connect @connection do |s|
134
+ Sedna.connect @@spec do |s|
138
135
  sedna = s
139
136
  raise Exception
140
137
  end
@@ -148,7 +145,7 @@ class SednaTest < Test::Unit::TestCase
148
145
  test "connect should close connection if something is thrown inside block" do
149
146
  sedna = nil
150
147
  catch :ball do
151
- Sedna.connect @connection do |s|
148
+ Sedna.connect @@spec do |s|
152
149
  sedna = s
153
150
  throw :ball
154
151
  end
@@ -160,69 +157,142 @@ class SednaTest < Test::Unit::TestCase
160
157
 
161
158
  test "connect should re-raise exceptions from inside block" do
162
159
  assert_raises Exception do
163
- Sedna.connect @connection do
160
+ Sedna.connect @@spec do
164
161
  raise Exception
165
162
  end
166
163
  end
167
164
  end
168
165
 
166
+ test "connect should set instance variables for keys in connection specification" do
167
+ assert_equal @@spec.values, @@spec.keys.collect { |k| @@sedna.instance_variable_get "@#{k.to_s}".to_sym }
168
+ end
169
+
169
170
  # Test sedna.close.
170
171
  test "close should return nil" do
171
- sedna = Sedna.connect @connection
172
+ sedna = Sedna.connect @@spec
172
173
  assert_nil sedna.close
173
174
  end
174
175
 
175
176
  test "close should fail silently if connection is already closed" do
176
- sedna = Sedna.connect @connection
177
+ sedna = Sedna.connect @@spec
177
178
  assert_nothing_raised do
178
179
  sedna.close
179
180
  sedna.close
180
181
  end
181
182
  end
182
183
 
183
- # Test sedna.execute / sedna.query.
184
- test "execute should raise TypeError if argument cannot be converted to String" do
185
- Sedna.connect @connection do |sedna|
186
- assert_raises TypeError do
187
- sedna.execute Object.new
184
+ # Test sedna.connected?.
185
+ test "connected? should return true if connected" do
186
+ assert_equal true, @@sedna.connected?
187
+ end
188
+
189
+ test "connected? should return false if closed" do
190
+ sedna = Sedna.connect @@spec
191
+ sedna.close
192
+ assert_equal false, sedna.connected?
193
+ end
194
+
195
+ # Test sedna.reset.
196
+ test "reset should return nil" do
197
+ assert_nil @@sedna.reset
198
+ end
199
+
200
+ test "reset should break current transaction" do
201
+ assert_raises Sedna::TransactionError do
202
+ @@sedna.transaction do
203
+ @@sedna.reset
188
204
  end
189
205
  end
190
206
  end
191
207
 
192
- test "execute should return nil for data structure query" do
193
- Sedna.connect @connection do |sedna|
194
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
195
- assert_nil sedna.execute("create document '#{__method__}'")
196
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
208
+ test "reset should implicitly roll back current transaction" do
209
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
210
+ @@sedna.execute "create document '#{__method__}'"
211
+ @@sedna.transaction do
212
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
213
+ @@sedna.reset
214
+ end rescue nil
215
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
216
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
217
+ end
218
+
219
+ test "reset should close and reconnect if the connection is open" do
220
+ @@sedna.reset
221
+ assert_nothing_raised do
222
+ @@sedna.execute "<test/>"
197
223
  end
198
224
  end
199
225
 
200
- test "execute should return array for select query" do
201
- Sedna.connect @connection do |sedna|
202
- assert_kind_of Array, sedna.execute("<test/>")
226
+ test "reset should reconnect if the connection is closed" do
227
+ @@sedna.close
228
+ @@sedna.reset
229
+ assert_nothing_raised do
230
+ @@sedna.execute "<test/>"
231
+ end
232
+ end
233
+
234
+ test "reset should raise exception when host not found" do
235
+ sedna = Sedna.connect @@spec
236
+ sedna.instance_variable_set :@host, "non-existent-host"
237
+ assert_raises Sedna::ConnectionError do
238
+ sedna.reset
239
+ end
240
+ end
241
+
242
+ test "reset should raise exception when credentials are incorrect" do
243
+ sedna = Sedna.connect @@spec
244
+ sedna.instance_variable_set :@username, "non-existent-user"
245
+ assert_raises Sedna::AuthenticationError do
246
+ sedna.reset
247
+ end
248
+ end
249
+
250
+ test "reset should preserve disabled autocommit status" do
251
+ Sedna.connect @@spec do |sedna|
252
+ sedna.autocommit = false
253
+ sedna.reset
254
+ assert_raises Sedna::Exception do
255
+ sedna.execute "<test/>"
256
+ end
203
257
  end
204
258
  end
205
259
 
206
- test "execute should return array with single string for single select query" do
207
- Sedna.connect @connection do |sedna|
208
- assert_equal ["<test/>"], sedna.execute("<test/>")
260
+ # Test sedna.execute / sedna.query.
261
+ test "execute should raise TypeError if argument cannot be converted to String" do
262
+ assert_raises TypeError do
263
+ @@sedna.execute Object.new
209
264
  end
210
265
  end
211
266
 
267
+ test "execute should return nil for data structure query" do
268
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
269
+ assert_nil @@sedna.execute("create document '#{__method__}'")
270
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
271
+ end
272
+
273
+ test "execute should return subclass of array for select query" do
274
+ assert_kind_of Array, @@sedna.execute("<test/>")
275
+ end
276
+
277
+ test "execute should return array with single string for single select query" do
278
+ assert_equal ["<test/>"], @@sedna.execute("<test/>")
279
+ end
280
+
212
281
  test "execute should return array with strings for select query" do
213
- Sedna.connect @connection do |sedna|
214
- assert_equal ["<test/>", "<test/>", "<test/>"], sedna.execute("<test/>, <test/>, <test/>")
215
- end
282
+ assert_equal ["<test/>", "<test/>", "<test/>"], @@sedna.execute("<test/>, <test/>, <test/>")
216
283
  end
217
284
 
218
285
  test "execute should return tainted strings" do
219
- Sedna.connect @connection do |sedna|
220
- assert sedna.execute("<test/>").first.tainted?
221
- end
286
+ assert @@sedna.execute("<test/>").first.tainted?
287
+ end
288
+
289
+ test "execute should return utf-8 strings" do
290
+ str = "<utf8> Ѩ 乗 </utf8>"
291
+ assert_equal [str], @@sedna.execute(str)
222
292
  end
223
293
 
224
294
  test "execute should fail if autocommit is false" do
225
- Sedna.connect @connection do |sedna|
295
+ Sedna.connect @@spec do |sedna|
226
296
  sedna.autocommit = false
227
297
  assert_raises Sedna::Exception do
228
298
  sedna.execute "<test/>"
@@ -231,15 +301,13 @@ class SednaTest < Test::Unit::TestCase
231
301
  end
232
302
 
233
303
  test "execute should fail with Sedna::Exception for invalid statements" do
234
- Sedna.connect @connection do |sedna|
235
- assert_raises Sedna::Exception do
236
- sedna.execute "INVALID"
237
- end
304
+ assert_raises Sedna::Exception do
305
+ @@sedna.execute "INVALID"
238
306
  end
239
307
  end
240
308
 
241
309
  test "execute should fail with Sedna::ConnectionError if connection is closed" do
242
- Sedna.connect @connection do |sedna|
310
+ Sedna.connect @@spec do |sedna|
243
311
  sedna.close
244
312
  assert_raises Sedna::ConnectionError do
245
313
  sedna.execute "<test/>"
@@ -248,165 +316,107 @@ class SednaTest < Test::Unit::TestCase
248
316
  end
249
317
 
250
318
  test "execute should strip first newline of all but first results" do
251
- Sedna.connect @connection do |sedna|
252
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
253
- sedna.execute("create document '#{__method__}'")
254
- sedna.execute("update insert <test><a>\n\nt</a><a>\n\nt</a><a>\n\nt</a></test> into doc('#{__method__}')")
255
- assert_equal ["\n\nt", "\n\nt", "\n\nt"], sedna.execute("doc('#{__method__}')/test/a/text()")
256
- sedna.execute("drop document '#{__method__}'") rescue Sedna::Exception
257
- end
319
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
320
+ @@sedna.execute("create document '#{__method__}'")
321
+ @@sedna.execute("update insert <test><a>\n\nt</a><a>\n\nt</a><a>\n\nt</a></test> into doc('#{__method__}')")
322
+ assert_equal ["\n\nt", "\n\nt", "\n\nt"], @@sedna.execute("doc('#{__method__}')/test/a/text()")
323
+ @@sedna.execute("drop document '#{__method__}'") rescue nil
258
324
  end
259
325
 
260
- test "execute should block other threads for ruby 18 and not block for ruby 19" do
261
- n = 5 # Amount of threads to be run. Increase for more accuracy.
262
- i = 10000 # Times to loop in query. Increase for more accuracy.
326
+ test "execute should be run serially if called from different threads on same connection" do
327
+ i = 1000
263
328
  threads = []
264
- start_times = {}
265
- end_times = {}
266
- n.times do |number|
329
+ exceptions = []
330
+ Thread.abort_on_exception = true
331
+ 5.times do
267
332
  threads << Thread.new do
268
- Sedna.connect @connection do |sedna|
269
- start_times[number] = Time.now
270
- sedna.execute "for $x in 1 to #{i} where $x = 1 return <node/>"
271
- end_times[number] = Time.now
333
+ begin
334
+ @@sedna.execute "for $x in #{i} where $x = 1 return <node/>"
335
+ rescue StandardError => e
336
+ exceptions << e
272
337
  end
273
338
  end
274
339
  end
275
340
  threads.each do |thread| thread.join end
276
- # Count the amount of time that is overlapped between threads. If the execute
277
- # method blocks, there should be hardly any overlap.
278
- time_diff = 0
279
- (n - 1).times do |number|
280
- time_diff += start_times[number + 1] - end_times[number]
281
- end
282
- if RUBY_VERSION < "1.9"
283
- # Blocking behaviour. The start/end times of two threads should not overlap.
284
- assert time_diff > 0
285
- else
286
- # We have concurrency, the execute method in the threads should have been
287
- # run in parallel and there should be considerable overlap in the start/end
288
- # times of the executed threads.
289
- assert time_diff < 0
290
- end
291
- end
292
-
293
- test "execute should be run in serially if called from different threads on same connection" do
294
- Sedna.connect @connection do |sedna|
295
- i = 1000
296
- threads = []
297
- exceptions = []
298
- Thread.abort_on_exception = true
299
- 5.times do
300
- threads << Thread.new do
301
- begin
302
- sedna.execute "for $x in #{i} where $x = 1 return <node/>"
303
- rescue StandardError => e
304
- exceptions << e
305
- end
306
- end
307
- end
308
- threads.each do |thread| thread.join end
309
- assert_equal [], exceptions
310
- end
341
+ assert_equal [], exceptions
311
342
  end
312
343
 
313
344
  test "execute should quit if exception is raised in it by another thread in ruby 19" do
314
- Sedna.connect @connection do |sedna|
315
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
316
- begin
317
- thread = Thread.new do
318
- sedna.execute "create document '#{__method__}'"
319
- end
320
- thread.raise
321
- thread.join
322
- rescue
323
- end
324
- count = sedna.execute("count(doc('$documents')//*[@name='#{__method__}'])").first.to_i
325
- if RUBY_VERSION < "1.9"
326
- assert_equal 1, count
327
- else
328
- assert_equal 0, count
345
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
346
+ begin
347
+ thread = Thread.new do
348
+ @@sedna.execute "create document '#{__method__}'"
329
349
  end
350
+ thread.raise
351
+ thread.join
352
+ rescue
353
+ end
354
+ count = @@sedna.execute("count(doc('$documents')//*[@name='#{__method__}'])").first.to_i
355
+ if RUBY_VERSION < "1.9"
356
+ assert_equal 1, count
357
+ else
358
+ assert_equal 0, count
330
359
  end
331
360
  end
332
361
 
333
362
  test "query should be alias of execute" do
334
- Sedna.connect @connection do |sedna|
335
- assert_equal ["<test/>"], sedna.query("<test/>")
336
- end
363
+ assert_equal ["<test/>"], @@sedna.query("<test/>")
337
364
  end
338
365
 
339
366
  # Test sedna.load_document.
340
367
  test "load_document should raise TypeError if document argument cannot be converted to String" do
341
- Sedna.connect @connection do |sedna|
342
- assert_raises TypeError do
343
- sedna.load_document Object.new, __method__.to_s
344
- end
368
+ assert_raises TypeError do
369
+ @@sedna.load_document Object.new, __method__.to_s
345
370
  end
346
371
  end
347
372
 
348
373
  test "load_document should raise TypeError if doc_name argument cannot be converted to String" do
349
- Sedna.connect @connection do |sedna|
350
- assert_raises TypeError do
351
- sedna.load_document "<doc/>", Object.new
352
- end
374
+ assert_raises TypeError do
375
+ @@sedna.load_document "<doc/>", Object.new
353
376
  end
354
377
  end
355
378
 
356
379
  test "load_document should raise TypeError if col_name argument cannot be converted to String" do
357
- Sedna.connect @connection do |sedna|
358
- assert_raises TypeError do
359
- sedna.load_document "<doc/>", __method__.to_s, Object.new
360
- end
380
+ assert_raises TypeError do
381
+ @@sedna.load_document "<doc/>", __method__.to_s, Object.new
361
382
  end
362
383
  end
363
384
 
364
385
  test "load_document should create document in given collection" do
365
- Sedna.connect @connection do |sedna|
366
- col = "test_collection"
367
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
368
-
369
- sedna.execute "create collection '#{col}'" rescue Sedna::Exception
370
- sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue Sedna::Exception
371
- sedna.load_document doc, __method__.to_s, col
372
- assert_equal doc, sedna.execute("doc('#{__method__}', '#{col}')").first
373
- sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue Sedna::Exception
374
- sedna.execute "drop collection '#{col}'" rescue Sedna::Exception
375
- end
386
+ col = "test_collection"
387
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
388
+ @@sedna.execute "create collection '#{col}'" rescue nil
389
+ @@sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue nil
390
+ @@sedna.load_document doc, __method__.to_s, col
391
+ assert_equal doc, @@sedna.execute("doc('#{__method__}', '#{col}')").first
392
+ @@sedna.execute "drop document '#{__method__}' in collection '#{col}'" rescue nil
393
+ @@sedna.execute "drop collection '#{col}'" rescue nil
376
394
  end
377
395
 
378
396
  test "load_document should create standalone document if collection is unspecified" do
379
- Sedna.connect @connection do |sedna|
380
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
381
-
382
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
383
- sedna.load_document doc, __method__.to_s
384
- assert_equal doc, sedna.execute("doc('#{__method__}')").first
385
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
386
- end
397
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
398
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
399
+ @@sedna.load_document doc, __method__.to_s
400
+ assert_equal doc, @@sedna.execute("doc('#{__method__}')").first
401
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
387
402
  end
388
403
 
389
404
  test "load_document should create standalone document if collection is nil" do
390
- Sedna.connect @connection do |sedna|
391
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
392
-
393
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
394
- sedna.load_document doc, __method__.to_s, nil
395
- assert_equal doc, sedna.execute("doc('#{__method__}')").first
396
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
397
- end
405
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>\n <node/>\n</document>"
406
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
407
+ @@sedna.load_document doc, __method__.to_s, nil
408
+ assert_equal doc, @@sedna.execute("doc('#{__method__}')").first
409
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
398
410
  end
399
411
 
400
412
  test "load_document should return nil if standalone document loaded successfully" do
401
- Sedna.connect @connection do |sedna|
402
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
403
- assert_nil sedna.load_document("<document><node/></document>", __method__.to_s)
404
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
405
- end
413
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
414
+ assert_nil @@sedna.load_document("<document><node/></document>", __method__.to_s)
415
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
406
416
  end
407
417
 
408
418
  test "load_document should fail if autocommit is false" do
409
- Sedna.connect @connection do |sedna|
419
+ Sedna.connect @@spec do |sedna|
410
420
  sedna.autocommit = false
411
421
  assert_raises Sedna::Exception do
412
422
  sedna.load_document "<test/>", "some_doc"
@@ -415,26 +425,22 @@ class SednaTest < Test::Unit::TestCase
415
425
  end
416
426
 
417
427
  test "load_document should fail with Sedna::Exception for invalid documents" do
418
- Sedna.connect @connection do |sedna|
419
- assert_raises Sedna::Exception do
420
- sedna.load_document "<doc/> this is an invalid document", "some_doc"
421
- end
428
+ assert_raises Sedna::Exception do
429
+ @@sedna.load_document "<doc/> this is an invalid document", "some_doc"
422
430
  end
423
431
  end
424
432
 
425
433
  test "load_document should raise exception with complete details for invalid documents" do
426
- Sedna.connect @connection do |sedna|
427
- e = nil
428
- begin
429
- sedna.load_document "<doc/> junk here", "some_doc"
430
- rescue Sedna::Exception => e
431
- end
432
- assert_match /junk after document element/, e.message
434
+ e = nil
435
+ begin
436
+ @@sedna.load_document "<doc/> junk here", "some_doc"
437
+ rescue Sedna::Exception => e
433
438
  end
439
+ assert_match /junk after document element/, e.message
434
440
  end
435
441
 
436
442
  test "load_document should fail with Sedna::ConnectionError if connection is closed" do
437
- Sedna.connect @connection do |sedna|
443
+ Sedna.connect @@spec do |sedna|
438
444
  sedna.close
439
445
  assert_raises Sedna::ConnectionError do
440
446
  sedna.load_document "<doc/>", "some_doc"
@@ -443,71 +449,63 @@ class SednaTest < Test::Unit::TestCase
443
449
  end
444
450
 
445
451
  test "load_document should create document if given document is IO object" do
446
- Sedna.connect @connection do |sedna|
447
- doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>" << ("\n <some_very_often_repeated_node/>" * 800) << "\n</document>"
448
- p_out, p_in = IO.pipe
449
- p_in.write doc
450
- p_in.close
452
+ doc = "<?xml version=\"1.0\" standalone=\"yes\"?><document>" << ("\n <some_very_often_repeated_node/>" * 800) << "\n</document>"
453
+ p_out, p_in = IO.pipe
454
+ p_in.write doc
455
+ p_in.close
451
456
 
452
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
453
- sedna.load_document p_out, __method__.to_s, nil
454
- assert_equal doc.length, sedna.execute("doc('#{__method__}')").first.length
455
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
456
- end
457
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
458
+ @@sedna.load_document p_out, __method__.to_s, nil
459
+ assert_equal doc.length, @@sedna.execute("doc('#{__method__}')").first.length
460
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
457
461
  end
458
462
 
459
463
  test "load_document should raise Sedna::Exception if given document is empty IO object" do
460
- Sedna.connect @connection do |sedna|
461
- p_out, p_in = IO.pipe
462
- p_in.close
463
-
464
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
465
- e = nil
466
- begin
467
- sedna.load_document p_out, __method__.to_s, nil
468
- rescue Sedna::Exception => e
469
- end
470
- assert_equal "Document is empty.", e.message
471
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
464
+ p_out, p_in = IO.pipe
465
+ p_in.close
466
+
467
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
468
+ e = nil
469
+ begin
470
+ @@sedna.load_document p_out, __method__.to_s, nil
471
+ rescue Sedna::Exception => e
472
472
  end
473
+ assert_equal "Document is empty.", e.message
474
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
473
475
  end
474
476
 
475
477
  test "load_document should raise Sedna::Exception if given document is empty string" do
476
- Sedna.connect @connection do |sedna|
477
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
478
- e = nil
479
- begin
480
- sedna.load_document "", __method__.to_s, nil
481
- rescue Sedna::Exception => e
482
- end
483
- assert_equal "Document is empty.", e.message
484
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
478
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
479
+ e = nil
480
+ begin
481
+ @@sedna.load_document "", __method__.to_s, nil
482
+ rescue Sedna::Exception => e
485
483
  end
484
+ assert_equal "Document is empty.", e.message
485
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
486
486
  end
487
-
487
+
488
488
  # Test sedna.autocommit= / sedna.autocommit.
489
489
  test "autocommit should return true by default" do
490
- Sedna.connect @connection do |sedna|
491
- assert_equal true, sedna.autocommit
492
- end
490
+ assert_equal true, @@sedna.autocommit
493
491
  end
494
492
 
495
493
  test "autocommit should return true if set to true" do
496
- Sedna.connect @connection do |sedna|
494
+ Sedna.connect @@spec do |sedna|
497
495
  sedna.autocommit = true
498
496
  assert_equal true, sedna.autocommit
499
497
  end
500
498
  end
501
499
 
502
500
  test "autocommit should return false if set to false" do
503
- Sedna.connect @connection do |sedna|
501
+ Sedna.connect @@spec do |sedna|
504
502
  sedna.autocommit = false
505
503
  assert_equal false, sedna.autocommit
506
504
  end
507
505
  end
508
506
 
509
507
  test "autocommit should return true if set to true after being set to false" do
510
- Sedna.connect @connection do |sedna|
508
+ Sedna.connect @@spec do |sedna|
511
509
  sedna.autocommit = false
512
510
  sedna.autocommit = true
513
511
  assert_equal true, sedna.autocommit
@@ -515,21 +513,21 @@ class SednaTest < Test::Unit::TestCase
515
513
  end
516
514
 
517
515
  test "autocommit should return true if argument evaluates to true" do
518
- Sedna.connect @connection do |sedna|
516
+ Sedna.connect @@spec do |sedna|
519
517
  sedna.autocommit = "string evaluates to true"
520
518
  assert_equal true, sedna.autocommit
521
519
  end
522
520
  end
523
521
 
524
522
  test "autocommit should return false if argument evaluates to false" do
525
- Sedna.connect @connection do |sedna|
523
+ Sedna.connect @@spec do |sedna|
526
524
  sedna.autocommit = nil
527
525
  assert_equal false, sedna.autocommit
528
526
  end
529
527
  end
530
528
 
531
- test "autocommit should be re-enabled after transactions" do
532
- Sedna.connect @connection do |sedna|
529
+ test "autocommit should be re-enabled after a transaction" do
530
+ Sedna.connect @@spec do |sedna|
533
531
  sedna.autocommit = true
534
532
  sedna.transaction do end
535
533
  assert_nothing_raised do
@@ -538,23 +536,66 @@ class SednaTest < Test::Unit::TestCase
538
536
  end
539
537
  end
540
538
 
541
- # Test sedna.transaction.
542
- test "transaction should return nil if committed" do
543
- Sedna.connect @connection do |sedna|
544
- assert_nil sedna.transaction(){}
539
+ test "autocommit should be re-enabled after an explicit commit" do
540
+ Sedna.connect @@spec do |sedna|
541
+ sedna.autocommit = true
542
+ sedna.transaction
543
+ sedna.commit
544
+ assert_nothing_raised do
545
+ sedna.execute "<test/>"
546
+ end
547
+ end
548
+ end
549
+
550
+ test "autocommit should be re-enabled after an explicit rollback" do
551
+ Sedna.connect @@spec do |sedna|
552
+ sedna.autocommit = true
553
+ sedna.transaction
554
+ sedna.rollback
555
+ assert_nothing_raised do
556
+ sedna.execute "<test/>"
557
+ end
545
558
  end
546
559
  end
547
560
 
548
- test "transaction should raise LocalJumpError if no block is given" do
549
- assert_raises LocalJumpError do
550
- Sedna.connect @connection do |sedna|
551
- sedna.transaction
561
+ test "autocommit should be re-enabled after a transaction was rolled back" do
562
+ Sedna.connect @@spec do |sedna|
563
+ sedna.autocommit = true
564
+ catch :rollback do
565
+ sedna.transaction do
566
+ throw :rollback
567
+ end
568
+ end
569
+ assert_nothing_raised do
570
+ sedna.execute "<test/>"
552
571
  end
553
572
  end
554
573
  end
555
574
 
575
+ test "autocommit should be re-enabled after a transaction raised an error" do
576
+ Sedna.connect @@spec do |sedna|
577
+ sedna.autocommit = true
578
+ sedna.transaction do
579
+ sedna.execute "INVALID" rescue nil
580
+ end rescue nil
581
+ assert_nothing_raised do
582
+ sedna.execute "<test/>"
583
+ end
584
+ end
585
+ end
586
+
587
+ # Test sedna.transaction.
588
+ test "transaction should return nil if called without block" do
589
+ assert_nil @@sedna.transaction
590
+ @@sedna.rollback
591
+ end
592
+
593
+ test "transaction should return nil if committed" do
594
+ assert_nil @@sedna.transaction(){}
595
+ end
596
+
556
597
  test "transaction should be possible with autocommit" do
557
- Sedna.connect @connection do |sedna|
598
+ Sedna.connect @@spec do |sedna|
558
599
  sedna.autocommit = true
559
600
  assert_nothing_raised do
560
601
  sedna.transaction do end
@@ -563,74 +604,86 @@ class SednaTest < Test::Unit::TestCase
563
604
  end
564
605
 
565
606
  test "transaction should fail with Sedna::TransactionError if another transaction is started inside it" do
566
- Sedna.connect @connection do |sedna|
567
- assert_raises Sedna::TransactionError do
568
- sedna.transaction do
569
- sedna.transaction do end
570
- end
607
+ assert_raises Sedna::TransactionError do
608
+ @@sedna.transaction do
609
+ @@sedna.transaction do end
571
610
  end
572
611
  end
573
612
  end
574
613
 
614
+ test "transaction should fail with Sedna::TransactionError if another transaction is started before it is committed" do
615
+ @@sedna.transaction
616
+ assert_raises Sedna::TransactionError do
617
+ @@sedna.transaction
618
+ end
619
+ @@sedna.rollback
620
+ end
621
+
575
622
  test "transaction should commit if block given" do
576
- Sedna.connect @connection do |sedna|
577
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
578
- sedna.execute "create document '#{__method__}'"
579
- sedna.transaction do
580
- sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
581
- end
582
- assert_equal 1, sedna.execute("count(doc('#{__method__}')/test)").first.to_i
583
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
623
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
624
+ @@sedna.execute "create document '#{__method__}'"
625
+ @@sedna.transaction do
626
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
584
627
  end
628
+ assert_equal 1, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
629
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
585
630
  end
586
631
 
587
632
  test "transaction should rollback if exception is raised inside block" do
588
- Sedna.connect @connection do |sedna|
589
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
590
- sedna.execute "create document '#{__method__}'"
591
- begin
592
- sedna.transaction do
593
- sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
594
- raise Exception
595
- end
596
- rescue Exception
633
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
634
+ @@sedna.execute "create document '#{__method__}'"
635
+ begin
636
+ @@sedna.transaction do
637
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
638
+ raise Exception
597
639
  end
598
- assert_equal 0, sedna.execute("count(doc('#{__method__}')/test)").first.to_i
599
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
640
+ rescue Exception
600
641
  end
642
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
643
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
601
644
  end
602
645
 
603
646
  test "transaction should rollback if something is thrown inside block" do
604
- Sedna.connect @connection do |sedna|
605
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
606
- sedna.execute "create document '#{__method__}'"
607
- catch :ball do
608
- sedna.transaction do
609
- sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
610
- throw :ball
611
- end
647
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
648
+ @@sedna.execute "create document '#{__method__}'"
649
+ catch :ball do
650
+ @@sedna.transaction do
651
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
652
+ throw :ball
612
653
  end
613
- assert_equal 0, sedna.execute("count(doc('#{__method__}')/test)").first.to_i
614
- sedna.execute "drop document '#{__method__}'" rescue Sedna::Exception
615
654
  end
655
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
656
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
616
657
  end
617
658
 
618
659
  test "transaction should raise Sedna::TransactionError if invalid statement caused exception but it was rescued" do
619
- Sedna.connect @connection do |sedna|
620
- assert_raises Sedna::TransactionError do
621
- sedna.transaction do
622
- sedna.execute "FAILS" rescue Sedna::Exception
623
- end
660
+ assert_raises Sedna::TransactionError do
661
+ @@sedna.transaction do
662
+ @@sedna.execute "FAILS" rescue nil
624
663
  end
625
664
  end
626
665
  end
627
-
666
+
667
+ test "transaction should raise Sedna::TransactionError if it was committed inside the block" do
668
+ assert_raises Sedna::TransactionError do
669
+ @@sedna.transaction do
670
+ @@sedna.commit
671
+ end
672
+ end
673
+ end
674
+
675
+ test "transaction should raise Sedna::TransactionError if it was rolled back inside the block" do
676
+ assert_raises Sedna::TransactionError do
677
+ @@sedna.transaction do
678
+ @@sedna.rollback
679
+ end
680
+ end
681
+ end
682
+
628
683
  test "transaction should re-raise exceptions from inside block" do
629
- Sedna.connect @connection do |sedna|
630
- assert_raises Exception do
631
- sedna.transaction do
632
- raise Exception
633
- end
684
+ assert_raises Exception do
685
+ @@sedna.transaction do
686
+ raise Exception
634
687
  end
635
688
  end
636
689
  end
@@ -638,10 +691,8 @@ class SednaTest < Test::Unit::TestCase
638
691
  test "transaction with invalid statements should cause transaction to roll back once" do
639
692
  exc = nil
640
693
  begin
641
- Sedna.connect @connection do |sedna|
642
- sedna.transaction do
643
- sedna.execute "FAILS"
644
- end
694
+ @@sedna.transaction do
695
+ @@sedna.execute "FAILS"
645
696
  end
646
697
  rescue Sedna::Exception => exc
647
698
  end
@@ -649,23 +700,102 @@ class SednaTest < Test::Unit::TestCase
649
700
  end
650
701
 
651
702
  test "transaction should raise Sedna::TransactionError if called from different threads on same connection" do
652
- Sedna.connect @connection do |sedna|
653
- threads = []
654
- exceptions = []
655
- Thread.abort_on_exception = true
656
- 5.times do
657
- threads << Thread.new do
658
- begin
659
- sedna.transaction do
660
- sleep 0.1
661
- end
662
- rescue StandardError => e
663
- exceptions << e.class
703
+ threads = []
704
+ exceptions = []
705
+ Thread.abort_on_exception = true
706
+ 5.times do
707
+ threads << Thread.new do
708
+ begin
709
+ @@sedna.transaction do
710
+ sleep 0.1
664
711
  end
712
+ rescue StandardError => e
713
+ exceptions << e.class
665
714
  end
666
715
  end
667
- threads.each do |thread| thread.join end
668
- assert_equal [Sedna::TransactionError] * 4, exceptions
669
716
  end
717
+ threads.each do |thread| thread.join end
718
+ assert_equal [Sedna::TransactionError] * 4, exceptions
719
+ end
720
+
721
+ test "transaction should raise Sedna::Exception if connection is closed before it could be committed" do
722
+ sedna = Sedna.connect @@spec
723
+ assert_raises Sedna::Exception do
724
+ sedna.transaction do
725
+ sedna.execute "<test/>"
726
+ sedna.close
727
+ end
728
+ end
729
+ end
730
+
731
+ # Test sedna.commit.
732
+ test "commit should commit transaction" do
733
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
734
+ @@sedna.execute "create document '#{__method__}'"
735
+
736
+ @@sedna.transaction
737
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
738
+ @@sedna.commit
739
+
740
+ assert_equal 1, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
741
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
742
+ end
743
+
744
+ test "commit should raise Sedna::Exception if connection is closed before transaction could be committed" do
745
+ sedna = Sedna.connect @@spec
746
+ sedna.transaction
747
+ sedna.execute "<test/>"
748
+ sedna.close
749
+ assert_raises Sedna::Exception do
750
+ sedna.commit
751
+ end
752
+ end
753
+
754
+ test "commit should raise Sedna::TransactionError if no transaction is in progress" do
755
+ assert_raises Sedna::TransactionError do
756
+ @@sedna.commit
757
+ end
758
+ end
759
+
760
+ test "commit should return nil" do
761
+ @@sedna.transaction
762
+ assert_nil @@sedna.commit
763
+ end
764
+
765
+ # Test sedna.rollback.
766
+ test "rollback should roll back transaction" do
767
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
768
+ @@sedna.execute "create document '#{__method__}'"
769
+
770
+ @@sedna.transaction
771
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
772
+ @@sedna.rollback
773
+
774
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
775
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
776
+ end
777
+
778
+ test "rollback should roll back transaction if called inside transaction block" do
779
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
780
+ @@sedna.execute "create document '#{__method__}'"
781
+
782
+ @@sedna.transaction do
783
+ @@sedna.execute "update insert <test>test</test> into doc('#{__method__}')"
784
+ @@sedna.rollback
785
+ end rescue nil
786
+
787
+ assert_equal 0, @@sedna.execute("count(doc('#{__method__}')/test)").first.to_i
788
+ @@sedna.execute "drop document '#{__method__}'" rescue nil
789
+ end
790
+
791
+ test "rollback should fail silently if no transaction is in progress" do
792
+ assert_nothing_raised do
793
+ @@sedna.rollback
794
+ end
795
+ end
796
+
797
+ test "rollback should return nil" do
798
+ @@sedna.transaction
799
+ assert_nil @@sedna.rollback
670
800
  end
671
801
  end