sqlite3-full 1.3.9.1

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/API_CHANGES.rdoc +50 -0
  4. data/CHANGELOG.rdoc +278 -0
  5. data/ChangeLog.cvs +88 -0
  6. data/Gemfile +15 -0
  7. data/LICENSE +34 -0
  8. data/Manifest.txt +52 -0
  9. data/README.rdoc +90 -0
  10. data/Rakefile +10 -0
  11. data/ext/sqlite3/backup.c +168 -0
  12. data/ext/sqlite3/backup.h +15 -0
  13. data/ext/sqlite3/database.c +825 -0
  14. data/ext/sqlite3/database.h +15 -0
  15. data/ext/sqlite3/exception.c +94 -0
  16. data/ext/sqlite3/exception.h +8 -0
  17. data/ext/sqlite3/extconf.rb +86 -0
  18. data/ext/sqlite3/sqlite3.c +97 -0
  19. data/ext/sqlite3/sqlite3_ruby.h +52 -0
  20. data/ext/sqlite3/sqlite3amalgamation.c +153367 -0
  21. data/ext/sqlite3/statement.c +447 -0
  22. data/ext/sqlite3/statement.h +16 -0
  23. data/faq/faq.rb +145 -0
  24. data/faq/faq.yml +426 -0
  25. data/lib/sqlite3/constants.rb +49 -0
  26. data/lib/sqlite3/database.rb +590 -0
  27. data/lib/sqlite3/errors.rb +44 -0
  28. data/lib/sqlite3/pragmas.rb +280 -0
  29. data/lib/sqlite3/resultset.rb +195 -0
  30. data/lib/sqlite3/statement.rb +144 -0
  31. data/lib/sqlite3/translator.rb +118 -0
  32. data/lib/sqlite3/value.rb +57 -0
  33. data/lib/sqlite3/version.rb +25 -0
  34. data/lib/sqlite3.rb +10 -0
  35. data/setup.rb +1333 -0
  36. data/tasks/faq.rake +9 -0
  37. data/tasks/gem.rake +38 -0
  38. data/tasks/native.rake +52 -0
  39. data/tasks/vendor_sqlite3.rake +91 -0
  40. data/test/helper.rb +18 -0
  41. data/test/test_backup.rb +33 -0
  42. data/test/test_collation.rb +82 -0
  43. data/test/test_database.rb +367 -0
  44. data/test/test_database_readonly.rb +29 -0
  45. data/test/test_deprecated.rb +44 -0
  46. data/test/test_encoding.rb +153 -0
  47. data/test/test_integration.rb +572 -0
  48. data/test/test_integration_open_close.rb +30 -0
  49. data/test/test_integration_pending.rb +115 -0
  50. data/test/test_integration_resultset.rb +159 -0
  51. data/test/test_integration_statement.rb +194 -0
  52. data/test/test_result_set.rb +37 -0
  53. data/test/test_sqlite3.rb +9 -0
  54. data/test/test_statement.rb +260 -0
  55. data/test/test_statement_execute.rb +35 -0
  56. metadata +205 -0
@@ -0,0 +1,572 @@
1
+ require 'helper'
2
+
3
+ class TC_Database_Integration < SQLite3::TestCase
4
+ def setup
5
+ @db = SQLite3::Database.new(":memory:")
6
+ @db.transaction do
7
+ @db.execute "create table foo ( a integer primary key, b text )"
8
+ @db.execute "insert into foo ( b ) values ( 'foo' )"
9
+ @db.execute "insert into foo ( b ) values ( 'bar' )"
10
+ @db.execute "insert into foo ( b ) values ( 'baz' )"
11
+ end
12
+ end
13
+
14
+ def teardown
15
+ @db.close
16
+ end
17
+
18
+ def test_table_info_with_type_translation_active
19
+ assert_nothing_raised { @db.table_info("foo") }
20
+ end
21
+
22
+ def test_table_info_with_defaults_for_version_3_3_8_and_higher
23
+ @db.transaction do
24
+ @db.execute "create table defaults_test ( a string default NULL, b string default 'Hello', c string default '--- []\n' )"
25
+ data = @db.table_info( "defaults_test" )
26
+ assert_equal({"name" => "a", "type" => "string", "dflt_value" => nil, "notnull" => 0, "cid" => 0, "pk" => 0},
27
+ data[0])
28
+ assert_equal({"name" => "b", "type" => "string", "dflt_value" => "Hello", "notnull" => 0, "cid" => 1, "pk" => 0},
29
+ data[1])
30
+ assert_equal({"name" => "c", "type" => "string", "dflt_value" => "--- []\n", "notnull" => 0, "cid" => 2, "pk" => 0},
31
+ data[2])
32
+ end
33
+ end
34
+
35
+ def test_table_info_without_defaults_for_version_3_3_8_and_higher
36
+ @db.transaction do
37
+ @db.execute "create table no_defaults_test ( a integer default 1, b integer )"
38
+ data = @db.table_info( "no_defaults_test" )
39
+ assert_equal({"name" => "a", "type" => "integer", "dflt_value" => "1", "notnull" => 0, "cid" => 0, "pk" => 0},
40
+ data[0])
41
+ assert_equal({"name" => "b", "type" => "integer", "dflt_value" => nil, "notnull" => 0, "cid" => 1, "pk" => 0},
42
+ data[1])
43
+ end
44
+ end
45
+
46
+ def test_complete_fail
47
+ assert !@db.complete?( "select * from foo" )
48
+ end
49
+ def test_complete_success
50
+ assert @db.complete?( "select * from foo;" )
51
+ end
52
+
53
+ # FIXME: do people really need UTF16 sql statements?
54
+ #def test_complete_fail_utf16
55
+ # assert !@db.complete?( "select * from foo".to_utf16(false), true )
56
+ #end
57
+
58
+ # FIXME: do people really need UTF16 sql statements?
59
+ #def test_complete_success_utf16
60
+ # assert @db.complete?( "select * from foo;".to_utf16(true), true )
61
+ #end
62
+
63
+ def test_errmsg
64
+ assert_equal "not an error", @db.errmsg
65
+ end
66
+
67
+ # FIXME: do people really need UTF16 error messages?
68
+ #def test_errmsg_utf16
69
+ # msg = Iconv.conv('UTF-16', 'UTF-8', 'not an error')
70
+ # assert_equal msg, @db.errmsg(true)
71
+ #end
72
+
73
+ def test_errcode
74
+ assert_equal 0, @db.errcode
75
+ end
76
+
77
+ def test_trace
78
+ result = nil
79
+ @db.trace { |sql| result = sql }
80
+ @db.execute "select * from foo"
81
+ assert_equal "select * from foo", result
82
+ end
83
+
84
+ def test_authorizer_okay
85
+ @db.authorizer { |type,a,b,c,d| 0 }
86
+ rows = @db.execute "select * from foo"
87
+ assert_equal 3, rows.length
88
+ end
89
+
90
+ def test_authorizer_error
91
+ @db.authorizer { |type,a,b,c,d| 1 }
92
+ assert_raise( SQLite3::AuthorizationException ) do
93
+ @db.execute "select * from foo"
94
+ end
95
+ end
96
+
97
+ def test_authorizer_silent
98
+ @db.authorizer { |type,a,b,c,d| 2 }
99
+ rows = @db.execute "select * from foo"
100
+ assert rows.empty?
101
+ end
102
+
103
+ def test_prepare_invalid_syntax
104
+ assert_raise( SQLite3::SQLException ) do
105
+ @db.prepare "select from foo"
106
+ end
107
+ end
108
+
109
+ def test_prepare_invalid_column
110
+ assert_raise( SQLite3::SQLException ) do
111
+ @db.prepare "select k from foo"
112
+ end
113
+ end
114
+
115
+ def test_prepare_invalid_table
116
+ assert_raise( SQLite3::SQLException ) do
117
+ @db.prepare "select * from barf"
118
+ end
119
+ end
120
+
121
+ def test_prepare_no_block
122
+ stmt = @db.prepare "select * from foo"
123
+ assert stmt.respond_to?(:execute)
124
+ stmt.close
125
+ end
126
+
127
+ def test_prepare_with_block
128
+ called = false
129
+ @db.prepare "select * from foo" do |stmt|
130
+ called = true
131
+ assert stmt.respond_to?(:execute)
132
+ end
133
+ assert called
134
+ end
135
+
136
+ def test_execute_no_block_no_bind_no_match
137
+ rows = @db.execute( "select * from foo where a > 100" )
138
+ assert rows.empty?
139
+ end
140
+
141
+ def test_execute_with_block_no_bind_no_match
142
+ called = false
143
+ @db.execute( "select * from foo where a > 100" ) do |row|
144
+ called = true
145
+ end
146
+ assert !called
147
+ end
148
+
149
+ def test_execute_no_block_with_bind_no_match
150
+ rows = @db.execute( "select * from foo where a > ?", 100 )
151
+ assert rows.empty?
152
+ end
153
+
154
+ def test_execute_with_block_with_bind_no_match
155
+ called = false
156
+ @db.execute( "select * from foo where a > ?", 100 ) do |row|
157
+ called = true
158
+ end
159
+ assert !called
160
+ end
161
+
162
+ def test_execute_no_block_no_bind_with_match
163
+ rows = @db.execute( "select * from foo where a = 1" )
164
+ assert_equal 1, rows.length
165
+ end
166
+
167
+ def test_execute_with_block_no_bind_with_match
168
+ called = 0
169
+ @db.execute( "select * from foo where a = 1" ) do |row|
170
+ called += 1
171
+ end
172
+ assert_equal 1, called
173
+ end
174
+
175
+ def test_execute_no_block_with_bind_with_match
176
+ rows = @db.execute( "select * from foo where a = ?", 1 )
177
+ assert_equal 1, rows.length
178
+ end
179
+
180
+ def test_execute_with_block_with_bind_with_match
181
+ called = 0
182
+ @db.execute( "select * from foo where a = ?", 1 ) do |row|
183
+ called += 1
184
+ end
185
+ assert_equal 1, called
186
+ end
187
+
188
+ def test_execute2_no_block_no_bind_no_match
189
+ columns, *rows = @db.execute2( "select * from foo where a > 100" )
190
+ assert rows.empty?
191
+ assert_equal [ "a", "b" ], columns
192
+ end
193
+
194
+ def test_execute2_with_block_no_bind_no_match
195
+ called = 0
196
+ @db.execute2( "select * from foo where a > 100" ) do |row|
197
+ assert [ "a", "b" ], row unless called == 0
198
+ called += 1
199
+ end
200
+ assert_equal 1, called
201
+ end
202
+
203
+ def test_execute2_no_block_with_bind_no_match
204
+ columns, *rows = @db.execute2( "select * from foo where a > ?", 100 )
205
+ assert rows.empty?
206
+ assert_equal [ "a", "b" ], columns
207
+ end
208
+
209
+ def test_execute2_with_block_with_bind_no_match
210
+ called = 0
211
+ @db.execute2( "select * from foo where a > ?", 100 ) do |row|
212
+ assert_equal [ "a", "b" ], row unless called == 0
213
+ called += 1
214
+ end
215
+ assert_equal 1, called
216
+ end
217
+
218
+ def test_execute2_no_block_no_bind_with_match
219
+ columns, *rows = @db.execute2( "select * from foo where a = 1" )
220
+ assert_equal 1, rows.length
221
+ assert_equal [ "a", "b" ], columns
222
+ end
223
+
224
+ def test_execute2_with_block_no_bind_with_match
225
+ called = 0
226
+ @db.execute2( "select * from foo where a = 1" ) do |row|
227
+ assert_equal [ 1, "foo" ], row unless called == 0
228
+ called += 1
229
+ end
230
+ assert_equal 2, called
231
+ end
232
+
233
+ def test_execute2_no_block_with_bind_with_match
234
+ columns, *rows = @db.execute2( "select * from foo where a = ?", 1 )
235
+ assert_equal 1, rows.length
236
+ assert_equal [ "a", "b" ], columns
237
+ end
238
+
239
+ def test_execute2_with_block_with_bind_with_match
240
+ called = 0
241
+ @db.execute2( "select * from foo where a = ?", 1 ) do
242
+ called += 1
243
+ end
244
+ assert_equal 2, called
245
+ end
246
+
247
+ def test_execute_batch_empty
248
+ assert_nothing_raised { @db.execute_batch "" }
249
+ end
250
+
251
+ def test_execute_batch_no_bind
252
+ @db.transaction do
253
+ @db.execute_batch <<-SQL
254
+ create table bar ( a, b, c );
255
+ insert into bar values ( 'one', 2, 'three' );
256
+ insert into bar values ( 'four', 5, 'six' );
257
+ insert into bar values ( 'seven', 8, 'nine' );
258
+ SQL
259
+ end
260
+ rows = @db.execute( "select * from bar" )
261
+ assert_equal 3, rows.length
262
+ end
263
+
264
+ def test_execute_batch_with_bind
265
+ @db.execute_batch( <<-SQL, [1] )
266
+ create table bar ( a, b, c );
267
+ insert into bar values ( 'one', 2, ? );
268
+ insert into bar values ( 'four', 5, ? );
269
+ insert into bar values ( 'seven', 8, ? );
270
+ SQL
271
+ rows = @db.execute( "select * from bar" ).map { |a,b,c| c }
272
+ assert_equal [1, 1, 1], rows
273
+ end
274
+
275
+ def test_query_no_block_no_bind_no_match
276
+ result = @db.query( "select * from foo where a > 100" )
277
+ assert_nil result.next
278
+ result.close
279
+ end
280
+
281
+ def test_query_with_block_no_bind_no_match
282
+ r = nil
283
+ @db.query( "select * from foo where a > 100" ) do |result|
284
+ assert_nil result.next
285
+ r = result
286
+ end
287
+ assert r.closed?
288
+ end
289
+
290
+ def test_query_no_block_with_bind_no_match
291
+ result = @db.query( "select * from foo where a > ?", 100 )
292
+ assert_nil result.next
293
+ result.close
294
+ end
295
+
296
+ def test_query_with_block_with_bind_no_match
297
+ r = nil
298
+ @db.query( "select * from foo where a > ?", 100 ) do |result|
299
+ assert_nil result.next
300
+ r = result
301
+ end
302
+ assert r.closed?
303
+ end
304
+
305
+ def test_query_no_block_no_bind_with_match
306
+ result = @db.query( "select * from foo where a = 1" )
307
+ assert_not_nil result.next
308
+ assert_nil result.next
309
+ result.close
310
+ end
311
+
312
+ def test_query_with_block_no_bind_with_match
313
+ r = nil
314
+ @db.query( "select * from foo where a = 1" ) do |result|
315
+ assert_not_nil result.next
316
+ assert_nil result.next
317
+ r = result
318
+ end
319
+ assert r.closed?
320
+ end
321
+
322
+ def test_query_no_block_with_bind_with_match
323
+ result = @db.query( "select * from foo where a = ?", 1 )
324
+ assert_not_nil result.next
325
+ assert_nil result.next
326
+ result.close
327
+ end
328
+
329
+ def test_query_with_block_with_bind_with_match
330
+ r = nil
331
+ @db.query( "select * from foo where a = ?", 1 ) do |result|
332
+ assert_not_nil result.next
333
+ assert_nil result.next
334
+ r = result
335
+ end
336
+ assert r.closed?
337
+ end
338
+
339
+ def test_get_first_row_no_bind_no_match
340
+ result = @db.get_first_row( "select * from foo where a=100" )
341
+ assert_nil result
342
+ end
343
+
344
+ def test_get_first_row_no_bind_with_match
345
+ result = @db.get_first_row( "select * from foo where a=1" )
346
+ assert_equal [ 1, "foo" ], result
347
+ end
348
+
349
+ def test_get_first_row_with_bind_no_match
350
+ result = @db.get_first_row( "select * from foo where a=?", 100 )
351
+ assert_nil result
352
+ end
353
+
354
+ def test_get_first_row_with_bind_with_match
355
+ result = @db.get_first_row( "select * from foo where a=?", 1 )
356
+ assert_equal [ 1, "foo" ], result
357
+ end
358
+
359
+ def test_get_first_value_no_bind_no_match
360
+ result = @db.get_first_value( "select b, a from foo where a=100" )
361
+ assert_nil result
362
+ end
363
+
364
+ def test_get_first_value_no_bind_with_match
365
+ result = @db.get_first_value( "select b, a from foo where a=1" )
366
+ assert_equal "foo", result
367
+ end
368
+
369
+ def test_get_first_value_with_bind_no_match
370
+ result = @db.get_first_value( "select b, a from foo where a=?", 100 )
371
+ assert_nil result
372
+ end
373
+
374
+ def test_get_first_value_with_bind_with_match
375
+ result = @db.get_first_value( "select b, a from foo where a=?", 1 )
376
+ assert_equal "foo", result
377
+ end
378
+
379
+ def test_last_insert_row_id
380
+ @db.execute "insert into foo ( b ) values ( 'test' )"
381
+ assert_equal 4, @db.last_insert_row_id
382
+ @db.execute "insert into foo ( b ) values ( 'again' )"
383
+ assert_equal 5, @db.last_insert_row_id
384
+ end
385
+
386
+ def test_changes
387
+ @db.execute "insert into foo ( b ) values ( 'test' )"
388
+ assert_equal 1, @db.changes
389
+ @db.execute "delete from foo where 1=1"
390
+ assert_equal 4, @db.changes
391
+ end
392
+
393
+ def test_total_changes
394
+ assert_equal 3, @db.total_changes
395
+ @db.execute "insert into foo ( b ) values ( 'test' )"
396
+ @db.execute "delete from foo where 1=1"
397
+ assert_equal 8, @db.total_changes
398
+ end
399
+
400
+ def test_transaction_nest
401
+ assert_raise( SQLite3::SQLException ) do
402
+ @db.transaction do
403
+ @db.transaction do
404
+ end
405
+ end
406
+ end
407
+ end
408
+
409
+ def test_transaction_rollback
410
+ @db.transaction
411
+ @db.execute_batch <<-SQL
412
+ insert into foo (b) values ( 'test1' );
413
+ insert into foo (b) values ( 'test2' );
414
+ insert into foo (b) values ( 'test3' );
415
+ insert into foo (b) values ( 'test4' );
416
+ SQL
417
+ assert_equal 7, @db.get_first_value("select count(*) from foo").to_i
418
+ @db.rollback
419
+ assert_equal 3, @db.get_first_value("select count(*) from foo").to_i
420
+ end
421
+
422
+ def test_transaction_commit
423
+ @db.transaction
424
+ @db.execute_batch <<-SQL
425
+ insert into foo (b) values ( 'test1' );
426
+ insert into foo (b) values ( 'test2' );
427
+ insert into foo (b) values ( 'test3' );
428
+ insert into foo (b) values ( 'test4' );
429
+ SQL
430
+ assert_equal 7, @db.get_first_value("select count(*) from foo").to_i
431
+ @db.commit
432
+ assert_equal 7, @db.get_first_value("select count(*) from foo").to_i
433
+ end
434
+
435
+ def test_transaction_rollback_in_block
436
+ assert_raise( SQLite3::SQLException ) do
437
+ @db.transaction do
438
+ @db.rollback
439
+ end
440
+ end
441
+ end
442
+
443
+ def test_transaction_commit_in_block
444
+ assert_raise( SQLite3::SQLException ) do
445
+ @db.transaction do
446
+ @db.commit
447
+ end
448
+ end
449
+ end
450
+
451
+ def test_transaction_active
452
+ assert !@db.transaction_active?
453
+ @db.transaction
454
+ assert @db.transaction_active?
455
+ @db.commit
456
+ assert !@db.transaction_active?
457
+ end
458
+
459
+ def test_transaction_implicit_rollback
460
+ assert !@db.transaction_active?
461
+ @db.transaction
462
+ @db.execute('create table bar (x CHECK(1 = 0))')
463
+ assert @db.transaction_active?
464
+ assert_raises( SQLite3::ConstraintException ) do
465
+ @db.execute("insert or rollback into bar (x) VALUES ('x')")
466
+ end
467
+ assert !@db.transaction_active?
468
+ end
469
+
470
+ def test_interrupt
471
+ @db.create_function( "abort", 1 ) do |func,x|
472
+ @db.interrupt
473
+ func.result = x
474
+ end
475
+
476
+ assert_raise( SQLite3::InterruptException ) do
477
+ @db.execute "select abort(a) from foo"
478
+ end
479
+ end
480
+
481
+ def test_create_function
482
+ @db.create_function( "munge", 1 ) do |func,x|
483
+ func.result = ">>>#{x}<<<"
484
+ end
485
+
486
+ value = @db.get_first_value( "select munge(b) from foo where a=1" )
487
+ assert_match( />>>.*<<</, value )
488
+ end
489
+
490
+ def test_create_aggregate_without_block
491
+ step = proc do |ctx,a|
492
+ ctx[:sum] ||= 0
493
+ ctx[:sum] += a.to_i
494
+ end
495
+
496
+ final = proc { |ctx| ctx.result = ctx[:sum] }
497
+
498
+ @db.create_aggregate( "accumulate", 1, step, final )
499
+
500
+ value = @db.get_first_value( "select accumulate(a) from foo" )
501
+ assert_equal 6, value
502
+ end
503
+
504
+ def test_create_aggregate_with_block
505
+ @db.create_aggregate( "accumulate", 1 ) do
506
+ step do |ctx,a|
507
+ ctx[:sum] ||= 0
508
+ ctx[:sum] += a.to_i
509
+ end
510
+
511
+ finalize { |ctx| ctx.result = ctx[:sum] }
512
+ end
513
+
514
+ value = @db.get_first_value( "select accumulate(a) from foo" )
515
+ assert_equal 6, value
516
+ end
517
+
518
+ def test_create_aggregate_with_no_data
519
+ @db.create_aggregate( "accumulate", 1 ) do
520
+ step do |ctx,a|
521
+ ctx[:sum] ||= 0
522
+ ctx[:sum] += a.to_i
523
+ end
524
+
525
+ finalize { |ctx| ctx.result = ctx[:sum] || 0 }
526
+ end
527
+
528
+ value = @db.get_first_value(
529
+ "select accumulate(a) from foo where a = 100" )
530
+ assert_equal 0, value
531
+ end
532
+
533
+ class AggregateHandler
534
+ class << self
535
+ def arity; 1; end
536
+ def text_rep; SQLite3::Constants::TextRep::ANY; end
537
+ def name; "multiply"; end
538
+ end
539
+ def step(ctx, a)
540
+ ctx[:buffer] ||= 1
541
+ ctx[:buffer] *= a.to_i
542
+ end
543
+ def finalize(ctx); ctx.result = ctx[:buffer]; end
544
+ end
545
+
546
+ def test_aggregate_initialized_twice
547
+ initialized = 0
548
+ handler = Class.new(AggregateHandler) do
549
+ define_method(:initialize) do
550
+ initialized += 1
551
+ super()
552
+ end
553
+ end
554
+
555
+ @db.create_aggregate_handler handler
556
+ @db.get_first_value( "select multiply(a) from foo" )
557
+ @db.get_first_value( "select multiply(a) from foo" )
558
+ assert_equal 2, initialized
559
+ end
560
+
561
+ def test_create_aggregate_handler
562
+ @db.create_aggregate_handler AggregateHandler
563
+ value = @db.get_first_value( "select multiply(a) from foo" )
564
+ assert_equal 6, value
565
+ end
566
+
567
+ def test_bind_array_parameter
568
+ result = @db.get_first_value( "select b from foo where a=? and b=?",
569
+ [ 1, "foo" ] )
570
+ assert_equal "foo", result
571
+ end
572
+ end
@@ -0,0 +1,30 @@
1
+ require 'helper'
2
+
3
+ class TC_OpenClose < SQLite3::TestCase
4
+ def test_create_close
5
+ begin
6
+ db = SQLite3::Database.new( "test-create.db" )
7
+ assert File.exist?( "test-create.db" )
8
+ assert_nothing_raised { db.close }
9
+ ensure
10
+ File.delete( "test-create.db" ) rescue nil
11
+ end
12
+ end
13
+
14
+ def test_open_close
15
+ begin
16
+ File.open( "test-open.db", "w" ) { |f| }
17
+ assert File.exist?( "test-open.db" )
18
+ db = SQLite3::Database.new( "test-open.db" )
19
+ assert_nothing_raised { db.close }
20
+ ensure
21
+ File.delete( "test-open.db" ) rescue nil
22
+ end
23
+ end
24
+
25
+ def test_bad_open
26
+ assert_raise( SQLite3::CantOpenException ) do
27
+ SQLite3::Database.new( "." )
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,115 @@
1
+ require 'helper'
2
+
3
+ require 'thread'
4
+ require 'benchmark'
5
+
6
+ class TC_Integration_Pending < SQLite3::TestCase
7
+ def setup
8
+ @db = SQLite3::Database.new("test.db")
9
+ @db.transaction do
10
+ @db.execute "create table foo ( a integer primary key, b text )"
11
+ @db.execute "insert into foo ( b ) values ( 'foo' )"
12
+ @db.execute "insert into foo ( b ) values ( 'bar' )"
13
+ @db.execute "insert into foo ( b ) values ( 'baz' )"
14
+ end
15
+ end
16
+
17
+ def teardown
18
+ @db.close
19
+ File.delete( "test.db" )
20
+ end
21
+
22
+ def test_busy_handler_outwait
23
+ skip("not working in 1.9") if RUBY_VERSION >= '1.9'
24
+
25
+ busy = Mutex.new
26
+ busy.lock
27
+ handler_call_count = 0
28
+
29
+ t = Thread.new(busy) do |locker|
30
+ begin
31
+ db2 = SQLite3::Database.open( "test.db" )
32
+ db2.transaction( :exclusive ) do
33
+ locker.lock
34
+ end
35
+ ensure
36
+ db2.close if db2
37
+ end
38
+ end
39
+
40
+ @db.busy_handler do |data,count|
41
+ handler_call_count += 1
42
+ busy.unlock
43
+ true
44
+ end
45
+
46
+ assert_nothing_raised do
47
+ @db.execute "insert into foo (b) values ( 'from 2' )"
48
+ end
49
+
50
+ t.join
51
+
52
+ assert_equal 1, handler_call_count
53
+ end
54
+
55
+ def test_busy_handler_impatient
56
+ busy = Mutex.new
57
+ busy.lock
58
+ handler_call_count = 0
59
+
60
+ t = Thread.new do
61
+ begin
62
+ db2 = SQLite3::Database.open( "test.db" )
63
+ db2.transaction( :exclusive ) do
64
+ busy.lock
65
+ end
66
+ ensure
67
+ db2.close if db2
68
+ end
69
+ end
70
+ sleep 1
71
+
72
+ @db.busy_handler do
73
+ handler_call_count += 1
74
+ false
75
+ end
76
+
77
+ assert_raise( SQLite3::BusyException ) do
78
+ @db.execute "insert into foo (b) values ( 'from 2' )"
79
+ end
80
+
81
+ busy.unlock
82
+ t.join
83
+
84
+ assert_equal 1, handler_call_count
85
+ end
86
+
87
+ def test_busy_timeout
88
+ @db.busy_timeout 1000
89
+ busy = Mutex.new
90
+ busy.lock
91
+
92
+ t = Thread.new do
93
+ begin
94
+ db2 = SQLite3::Database.open( "test.db" )
95
+ db2.transaction( :exclusive ) do
96
+ busy.lock
97
+ end
98
+ ensure
99
+ db2.close if db2
100
+ end
101
+ end
102
+
103
+ sleep 1
104
+ time = Benchmark.measure do
105
+ assert_raise( SQLite3::BusyException ) do
106
+ @db.execute "insert into foo (b) values ( 'from 2' )"
107
+ end
108
+ end
109
+
110
+ busy.unlock
111
+ t.join
112
+
113
+ assert time.real*1000 >= 1000
114
+ end
115
+ end