sqlite3 1.7.3 → 2.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.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +292 -0
  3. data/CONTRIBUTING.md +33 -7
  4. data/FAQ.md +43 -77
  5. data/INSTALLATION.md +14 -6
  6. data/LICENSE +18 -22
  7. data/README.md +97 -9
  8. data/dependencies.yml +10 -11
  9. data/ext/sqlite3/aggregator.c +142 -145
  10. data/ext/sqlite3/aggregator.h +2 -4
  11. data/ext/sqlite3/backup.c +74 -65
  12. data/ext/sqlite3/backup.h +2 -2
  13. data/ext/sqlite3/database.c +621 -493
  14. data/ext/sqlite3/database.h +13 -4
  15. data/ext/sqlite3/exception.c +116 -92
  16. data/ext/sqlite3/exception.h +5 -1
  17. data/ext/sqlite3/extconf.rb +33 -24
  18. data/ext/sqlite3/sqlite3.c +176 -115
  19. data/ext/sqlite3/sqlite3_ruby.h +2 -2
  20. data/ext/sqlite3/statement.c +553 -300
  21. data/ext/sqlite3/statement.h +4 -3
  22. data/ext/sqlite3/timespec.h +20 -0
  23. data/lib/sqlite3/constants.rb +195 -47
  24. data/lib/sqlite3/database.rb +223 -187
  25. data/lib/sqlite3/errors.rb +54 -1
  26. data/lib/sqlite3/fork_safety.rb +66 -0
  27. data/lib/sqlite3/pragmas.rb +140 -136
  28. data/lib/sqlite3/resultset.rb +14 -97
  29. data/lib/sqlite3/statement.rb +58 -13
  30. data/lib/sqlite3/value.rb +17 -20
  31. data/lib/sqlite3/version.rb +2 -21
  32. data/lib/sqlite3/version_info.rb +17 -0
  33. data/lib/sqlite3.rb +8 -4
  34. data/ports/archives/sqlite-autoconf-3470200.tar.gz +0 -0
  35. metadata +9 -37
  36. data/API_CHANGES.md +0 -49
  37. data/ChangeLog.cvs +0 -88
  38. data/Gemfile +0 -10
  39. data/LICENSE-DEPENDENCIES +0 -20
  40. data/lib/sqlite3/translator.rb +0 -117
  41. data/ports/archives/sqlite-autoconf-3450200.tar.gz +0 -0
  42. data/test/helper.rb +0 -27
  43. data/test/test_backup.rb +0 -33
  44. data/test/test_collation.rb +0 -82
  45. data/test/test_database.rb +0 -668
  46. data/test/test_database_flags.rb +0 -95
  47. data/test/test_database_readonly.rb +0 -36
  48. data/test/test_database_readwrite.rb +0 -41
  49. data/test/test_deprecated.rb +0 -49
  50. data/test/test_encoding.rb +0 -165
  51. data/test/test_integration.rb +0 -507
  52. data/test/test_integration_aggregate.rb +0 -336
  53. data/test/test_integration_open_close.rb +0 -30
  54. data/test/test_integration_pending.rb +0 -115
  55. data/test/test_integration_resultset.rb +0 -142
  56. data/test/test_integration_statement.rb +0 -194
  57. data/test/test_pragmas.rb +0 -22
  58. data/test/test_result_set.rb +0 -47
  59. data/test/test_sqlite3.rb +0 -30
  60. data/test/test_statement.rb +0 -290
  61. data/test/test_statement_execute.rb +0 -39
@@ -1,668 +0,0 @@
1
- require 'helper'
2
- require 'tempfile'
3
- require 'pathname'
4
-
5
- module SQLite3
6
- class TestDatabase < SQLite3::TestCase
7
- attr_reader :db
8
-
9
- def setup
10
- @db = SQLite3::Database.new(':memory:')
11
- super
12
- end
13
-
14
- def teardown
15
- @db.close unless @db.closed?
16
- end
17
-
18
- def test_segv
19
- assert_raises { SQLite3::Database.new 1 }
20
- end
21
-
22
- def test_db_filename
23
- tf = nil
24
- assert_equal '', @db.filename('main')
25
- tf = Tempfile.new 'thing'
26
- @db = SQLite3::Database.new tf.path
27
- assert_equal File.realdirpath(tf.path), File.realdirpath(@db.filename('main'))
28
- ensure
29
- tf.unlink if tf
30
- end
31
-
32
- def test_filename
33
- tf = nil
34
- assert_equal '', @db.filename
35
- tf = Tempfile.new 'thing'
36
- @db = SQLite3::Database.new tf.path
37
- assert_equal File.realdirpath(tf.path), File.realdirpath(@db.filename)
38
- ensure
39
- tf.unlink if tf
40
- end
41
-
42
- def test_filename_with_attachment
43
- tf = nil
44
- assert_equal '', @db.filename
45
- tf = Tempfile.new 'thing'
46
- @db.execute "ATTACH DATABASE '#{tf.path}' AS 'testing'"
47
-
48
- assert_equal File.realdirpath(tf.path), File.realdirpath(@db.filename('testing'))
49
- ensure
50
- tf.unlink if tf
51
- end
52
-
53
-
54
- def test_filename_to_path
55
- tf = Tempfile.new 'thing'
56
- pn = Pathname tf.path
57
- db = SQLite3::Database.new pn
58
- assert_equal pn.realdirpath.to_s, File.realdirpath(db.filename)
59
- ensure
60
- tf.close! if tf
61
- db.close if db
62
- end
63
-
64
-
65
- def test_error_code
66
- begin
67
- db.execute 'SELECT'
68
- rescue SQLite3::SQLException => e
69
- end
70
- assert_equal 1, e.code
71
- end
72
-
73
- def test_extended_error_code
74
- db.extended_result_codes = true
75
- db.execute 'CREATE TABLE "employees" ("token" integer NOT NULL)'
76
- begin
77
- db.execute 'INSERT INTO employees (token) VALUES (NULL)'
78
- rescue SQLite3::ConstraintException => e
79
- end
80
- assert_equal 1299, e.code
81
- end
82
-
83
- def test_bignum
84
- num = 4907021672125087844
85
- db.execute 'CREATE TABLE "employees" ("token" integer(8), "name" varchar(20) NOT NULL)'
86
- db.execute "INSERT INTO employees(name, token) VALUES('employee-1', ?)", [num]
87
- rows = db.execute 'select token from employees'
88
- assert_equal num, rows.first.first
89
- end
90
-
91
- def test_blob
92
- @db.execute("CREATE TABLE blobs ( id INTEGER, hash BLOB(10) )")
93
- blob = Blob.new("foo\0bar")
94
- @db.execute("INSERT INTO blobs VALUES (0, ?)", [blob])
95
- assert_equal [[0, blob, blob.length, blob.length*2]], @db.execute("SELECT id, hash, length(hash), length(hex(hash)) FROM blobs")
96
- end
97
-
98
- def test_get_first_row
99
- assert_equal [1], @db.get_first_row('SELECT 1')
100
- end
101
-
102
- def test_get_first_row_with_type_translation_and_hash_results
103
- @db.results_as_hash = true
104
- capture_io do # hush translation deprecation warnings
105
- @db.type_translation = true
106
- assert_equal({"1"=>1}, @db.get_first_row('SELECT 1'))
107
- end
108
- end
109
-
110
- def test_execute_with_type_translation_and_hash
111
- rows = []
112
- @db.results_as_hash = true
113
-
114
- capture_io do # hush translation deprecation warnings
115
- @db.type_translation = true
116
- @db.execute('SELECT 1') { |row| rows << row }
117
- end
118
-
119
- assert_equal({"1"=>1}, rows.first)
120
- end
121
-
122
- def test_encoding
123
- assert @db.encoding, 'database has encoding'
124
- end
125
-
126
- def test_changes
127
- @db.execute("CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, number integer)")
128
- assert_equal 0, @db.changes
129
- @db.execute("INSERT INTO items (number) VALUES (10)")
130
- assert_equal 1, @db.changes
131
- @db.execute_batch(
132
- "UPDATE items SET number = (number + :nn) WHERE (number = :n)",
133
- {"nn" => 20, "n" => 10})
134
- assert_equal 1, @db.changes
135
- assert_equal [[30]], @db.execute("select number from items")
136
- end
137
-
138
- def test_batch_last_comment_is_processed
139
- # FIXME: nil as a successful return value is kinda dumb
140
- assert_nil @db.execute_batch <<-eosql
141
- CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT);
142
- -- omg
143
- eosql
144
- end
145
-
146
- def test_execute_batch2
147
- @db.results_as_hash = true
148
- return_value = @db.execute_batch2 <<-eosql
149
- CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, name string);
150
- INSERT INTO items (name) VALUES ("foo");
151
- INSERT INTO items (name) VALUES ("bar");
152
- SELECT * FROM items;
153
- eosql
154
- assert_equal return_value, [{"id"=>"1","name"=>"foo"}, {"id"=>"2", "name"=>"bar"}]
155
-
156
- return_value = @db.execute_batch2('SELECT * FROM items;') do |result|
157
- result["id"] = result["id"].to_i
158
- result
159
- end
160
- assert_equal return_value, [{"id"=>1,"name"=>"foo"}, {"id"=>2, "name"=>"bar"}]
161
-
162
- return_value = @db.execute_batch2('INSERT INTO items (name) VALUES ("oof")')
163
- assert_equal return_value, []
164
-
165
- return_value = @db.execute_batch2(
166
- 'CREATE TABLE employees (id integer PRIMARY KEY AUTOINCREMENT, name string, age integer(3));
167
- INSERT INTO employees (age) VALUES (30);
168
- INSERT INTO employees (age) VALUES (40);
169
- INSERT INTO employees (age) VALUES (20);
170
- SELECT age FROM employees;') do |result|
171
- result["age"] = result["age"].to_i
172
- result
173
- end
174
- assert_equal return_value, [{"age"=>30}, {"age"=>40}, {"age"=>20}]
175
-
176
- return_value = @db.execute_batch2('SELECT name FROM employees');
177
- assert_equal return_value, [{"name"=>nil}, {"name"=>nil}, {"name"=>nil}]
178
-
179
- @db.results_as_hash = false
180
- return_value = @db.execute_batch2(
181
- 'CREATE TABLE managers (id integer PRIMARY KEY AUTOINCREMENT, age integer(3));
182
- INSERT INTO managers (age) VALUES (50);
183
- INSERT INTO managers (age) VALUES (60);
184
- SELECT id, age from managers;') do |result|
185
- result = result.map do |res|
186
- res.to_i
187
- end
188
- result
189
- end
190
- assert_equal return_value, [[1, 50], [2, 60]]
191
-
192
- assert_raises (RuntimeError) do
193
- # "names" is not a valid column
194
- @db.execute_batch2 'INSERT INTO items (names) VALUES ("bazz")'
195
- end
196
-
197
- end
198
-
199
- def test_new
200
- db = SQLite3::Database.new(':memory:')
201
- assert_instance_of(SQLite3::Database, db)
202
- ensure
203
- db.close if db
204
- end
205
-
206
- def test_open
207
- db = SQLite3::Database.open(':memory:')
208
- assert_instance_of(SQLite3::Database, db)
209
- ensure
210
- db.close if db
211
- end
212
-
213
- def test_open_returns_block_result
214
- result = SQLite3::Database.open(':memory:') do |db|
215
- :foo
216
- end
217
- assert_equal :foo, result
218
- end
219
-
220
- def test_new_yields_self
221
- thing = nil
222
- SQLite3::Database.new(':memory:') do |db|
223
- thing = db
224
- end
225
- assert_instance_of(SQLite3::Database, thing)
226
- end
227
-
228
- def test_open_yields_self
229
- thing = nil
230
- SQLite3::Database.open(':memory:') do |db|
231
- thing = db
232
- end
233
- assert_instance_of(SQLite3::Database, thing)
234
- end
235
-
236
- def test_new_with_options
237
- # determine if Ruby is running on Big Endian platform
238
- utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
239
-
240
- if RUBY_VERSION >= "1.9"
241
- db = SQLite3::Database.new(':memory:'.encode(utf16), :utf16 => true)
242
- else
243
- db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
244
- :utf16 => true)
245
- end
246
- assert_instance_of(SQLite3::Database, db)
247
- ensure
248
- db.close if db
249
- end
250
-
251
- def test_close
252
- db = SQLite3::Database.new(':memory:')
253
- db.close
254
- assert db.closed?
255
- end
256
-
257
- def test_block_closes_self
258
- thing = nil
259
- SQLite3::Database.new(':memory:') do |db|
260
- thing = db
261
- assert !thing.closed?
262
- end
263
- assert thing.closed?
264
- end
265
-
266
- def test_open_with_block_closes_self
267
- thing = nil
268
- SQLite3::Database.open(':memory:') do |db|
269
- thing = db
270
- assert !thing.closed?
271
- end
272
- assert thing.closed?
273
- end
274
-
275
- def test_block_closes_self_even_raised
276
- thing = nil
277
- begin
278
- SQLite3::Database.new(':memory:') do |db|
279
- thing = db
280
- raise
281
- end
282
- rescue
283
- end
284
- assert thing.closed?
285
- end
286
-
287
- def test_open_with_block_closes_self_even_raised
288
- thing = nil
289
- begin
290
- SQLite3::Database.open(':memory:') do |db|
291
- thing = db
292
- raise
293
- end
294
- rescue
295
- end
296
- assert thing.closed?
297
- end
298
-
299
- def test_prepare
300
- db = SQLite3::Database.new(':memory:')
301
- stmt = db.prepare('select "hello world"')
302
- assert_instance_of(SQLite3::Statement, stmt)
303
- ensure
304
- stmt.close if stmt
305
- end
306
-
307
- def test_block_prepare_does_not_double_close
308
- db = SQLite3::Database.new(':memory:')
309
- r = db.prepare('select "hello world"') do |stmt|
310
- stmt.close
311
- :foo
312
- end
313
- assert_equal :foo, r
314
- end
315
-
316
- def test_total_changes
317
- db = SQLite3::Database.new(':memory:')
318
- db.execute("create table foo ( a integer primary key, b text )")
319
- db.execute("insert into foo (b) values ('hello')")
320
- assert_equal 1, db.total_changes
321
- end
322
-
323
- def test_execute_returns_list_of_hash
324
- db = SQLite3::Database.new(':memory:', :results_as_hash => true)
325
- db.execute("create table foo ( a integer primary key, b text )")
326
- db.execute("insert into foo (b) values ('hello')")
327
- rows = db.execute("select * from foo")
328
- assert_equal [{"a"=>1, "b"=>"hello"}], rows
329
- end
330
-
331
- def test_execute_yields_hash
332
- db = SQLite3::Database.new(':memory:', :results_as_hash => true)
333
- db.execute("create table foo ( a integer primary key, b text )")
334
- db.execute("insert into foo (b) values ('hello')")
335
- db.execute("select * from foo") do |row|
336
- assert_equal({"a"=>1, "b"=>"hello"}, row)
337
- end
338
- end
339
-
340
- def test_table_info
341
- db = SQLite3::Database.new(':memory:', :results_as_hash => true)
342
- db.execute("create table foo ( a integer primary key, b text )")
343
- info = [{
344
- "name" => "a",
345
- "pk" => 1,
346
- "notnull" => 0,
347
- "type" => "integer",
348
- "dflt_value" => nil,
349
- "cid" => 0
350
- },
351
- {
352
- "name" => "b",
353
- "pk" => 0,
354
- "notnull" => 0,
355
- "type" => "text",
356
- "dflt_value" => nil,
357
- "cid" => 1
358
- }]
359
- assert_equal info, db.table_info('foo')
360
- end
361
-
362
- def test_total_changes_closed
363
- db = SQLite3::Database.new(':memory:')
364
- db.close
365
- assert_raise(SQLite3::Exception) do
366
- db.total_changes
367
- end
368
- end
369
-
370
- def test_trace_requires_opendb
371
- @db.close
372
- assert_raise(SQLite3::Exception) do
373
- @db.trace { |x| }
374
- end
375
- end
376
-
377
- def test_trace_with_block
378
- result = nil
379
- @db.trace { |sql| result = sql }
380
- @db.execute "select 'foo'"
381
- assert_equal "select 'foo'", result
382
- end
383
-
384
- def test_trace_with_object
385
- obj = Class.new {
386
- attr_accessor :result
387
- def call sql; @result = sql end
388
- }.new
389
-
390
- @db.trace(obj)
391
- @db.execute "select 'foo'"
392
- assert_equal "select 'foo'", obj.result
393
- end
394
-
395
- def test_trace_takes_nil
396
- @db.trace(nil)
397
- @db.execute "select 'foo'"
398
- end
399
-
400
- def test_last_insert_row_id_closed
401
- @db.close
402
- assert_raise(SQLite3::Exception) do
403
- @db.last_insert_row_id
404
- end
405
- end
406
-
407
- def test_define_function
408
- called_with = nil
409
- @db.define_function("hello") do |value|
410
- called_with = value
411
- end
412
- @db.execute("select hello(10)")
413
- assert_equal 10, called_with
414
- end
415
-
416
- def test_call_func_arg_type
417
- called_with = nil
418
- @db.define_function("hello") do |b, c, d|
419
- called_with = [b, c, d]
420
- nil
421
- end
422
- @db.execute("select hello(2.2, 'foo', NULL)")
423
-
424
- assert_in_delta(2.2, called_with[0], 0.0001)
425
- assert_equal("foo", called_with[1])
426
- assert_nil(called_with[2])
427
- end
428
-
429
- def test_define_varargs
430
- called_with = nil
431
- @db.define_function("hello") do |*args|
432
- called_with = args
433
- nil
434
- end
435
- @db.execute("select hello(2.2, 'foo', NULL)")
436
-
437
- assert_in_delta(2.2, called_with[0], 0.0001)
438
- assert_equal("foo", called_with[1])
439
- assert_nil(called_with[2])
440
- end
441
-
442
- def test_call_func_blob
443
- called_with = nil
444
- @db.define_function("hello") do |a, b|
445
- called_with = [a, b, a.length]
446
- nil
447
- end
448
- blob = Blob.new("a\0fine\0kettle\0of\0fish")
449
- @db.execute("select hello(?, length(?))", [blob, blob])
450
- assert_equal [blob, blob.length, 21], called_with
451
- end
452
-
453
- def test_function_return
454
- @db.define_function("hello") { |a| 10 }
455
- assert_equal [10], @db.execute("select hello('world')").first
456
- end
457
-
458
- def test_function_return_types
459
- [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
460
- @db.define_function("hello") { |a| thing }
461
- assert_equal [thing], @db.execute("select hello('world')").first
462
- end
463
- end
464
-
465
- def test_function_gc_segfault
466
- @db.create_function("bug", -1) { |func, *values| func.result = values.join }
467
- # With a lot of data and a lot of threads, try to induce a GC segfault.
468
- params = Array.new(127, "?" * 28000)
469
- proc = Proc.new {
470
- db.execute("select bug(#{Array.new(params.length, "?").join(",")})", params)
471
- }
472
- m = Mutex.new
473
- 30.times.map { Thread.new { m.synchronize { proc.call } } }.each(&:join)
474
- end
475
-
476
- def test_function_return_type_round_trip
477
- [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
478
- @db.define_function("hello") { |a| a }
479
- assert_equal [thing], @db.execute("select hello(hello(?))", [thing]).first
480
- end
481
- end
482
-
483
- def test_define_function_closed
484
- @db.close
485
- assert_raise(SQLite3::Exception) do
486
- @db.define_function('foo') { }
487
- end
488
- end
489
-
490
- def test_inerrupt_closed
491
- @db.close
492
- assert_raise(SQLite3::Exception) do
493
- @db.interrupt
494
- end
495
- end
496
-
497
- def test_define_aggregate
498
- @db.execute "create table foo ( a integer primary key, b text )"
499
- @db.execute "insert into foo ( b ) values ( 'foo' )"
500
- @db.execute "insert into foo ( b ) values ( 'bar' )"
501
- @db.execute "insert into foo ( b ) values ( 'baz' )"
502
-
503
- acc = Class.new {
504
- attr_reader :sum
505
- alias :finalize :sum
506
- def initialize
507
- @sum = 0
508
- end
509
-
510
- def step a
511
- @sum += a
512
- end
513
- }.new
514
-
515
- @db.define_aggregator("accumulate", acc)
516
- value = @db.get_first_value( "select accumulate(a) from foo" )
517
- assert_equal 6, value
518
- end
519
-
520
- def test_authorizer_ok
521
- statements = []
522
-
523
- @db.authorizer = Class.new {
524
- def call action, a, b, c, d; true end
525
- }.new
526
- statements << @db.prepare("select 'fooooo'")
527
-
528
- @db.authorizer = Class.new {
529
- def call action, a, b, c, d; 0 end
530
- }.new
531
- statements << @db.prepare("select 'fooooo'")
532
- ensure
533
- statements.each(&:close)
534
- end
535
-
536
- def test_authorizer_ignore
537
- @db.authorizer = Class.new {
538
- def call action, a, b, c, d; nil end
539
- }.new
540
- stmt = @db.prepare("select 'fooooo'")
541
- assert_nil stmt.step
542
- ensure
543
- stmt.close if stmt
544
- end
545
-
546
- def test_authorizer_fail
547
- @db.authorizer = Class.new {
548
- def call action, a, b, c, d; false end
549
- }.new
550
- assert_raises(SQLite3::AuthorizationException) do
551
- @db.prepare("select 'fooooo'")
552
- end
553
- end
554
-
555
- def test_remove_auth
556
- @db.authorizer = Class.new {
557
- def call action, a, b, c, d; false end
558
- }.new
559
- assert_raises(SQLite3::AuthorizationException) do
560
- @db.prepare("select 'fooooo'")
561
- end
562
-
563
- @db.authorizer = nil
564
- s = @db.prepare("select 'fooooo'")
565
- ensure
566
- s.close if s
567
- end
568
-
569
- def test_close_with_open_statements
570
- s = @db.prepare("select 'foo'")
571
- assert_raises(SQLite3::BusyException) do
572
- @db.close
573
- end
574
- ensure
575
- s.close if s
576
- end
577
-
578
- def test_execute_with_empty_bind_params
579
- assert_equal [['foo']], @db.execute("select 'foo'", [])
580
- end
581
-
582
- def test_query_with_named_bind_params
583
- resultset = @db.query("select :n", {'n' => 'foo'})
584
- assert_equal [['foo']], resultset.to_a
585
- ensure
586
- resultset.close if resultset
587
- end
588
-
589
- def test_execute_with_named_bind_params
590
- assert_equal [['foo']], @db.execute("select :n", {'n' => 'foo'})
591
- end
592
-
593
- def test_strict_mode
594
- unless Gem::Requirement.new(">= 3.29.0").satisfied_by?(Gem::Version.new(SQLite3::SQLITE_VERSION))
595
- skip("strict mode feature not available in #{SQLite3::SQLITE_VERSION}")
596
- end
597
-
598
- db = SQLite3::Database.new(':memory:')
599
- db.execute('create table numbers (val int);')
600
- db.execute('create index index_numbers_nope ON numbers ("nope");') # nothing raised
601
-
602
- db = SQLite3::Database.new(':memory:', :strict => true)
603
- db.execute('create table numbers (val int);')
604
- error = assert_raises SQLite3::SQLException do
605
- db.execute('create index index_numbers_nope ON numbers ("nope");')
606
- end
607
- assert_includes error.message, "no such column: nope"
608
- end
609
-
610
- def test_load_extension_with_nonstring_argument
611
- db = SQLite3::Database.new(':memory:')
612
- skip("extensions are not enabled") unless db.respond_to?(:load_extension)
613
- assert_raises(TypeError) { db.load_extension(1) }
614
- assert_raises(TypeError) { db.load_extension(Pathname.new("foo.so")) }
615
- end
616
-
617
- def test_raw_float_infinity
618
- # https://github.com/sparklemotion/sqlite3-ruby/issues/396
619
- skip if SQLite3::SQLITE_LOADED_VERSION >= "3.43.0"
620
-
621
- db = SQLite3::Database.new ":memory:"
622
- db.execute("create table foo (temperature float)")
623
- db.execute("insert into foo values (?)", 37.5)
624
- db.execute("insert into foo values (?)", Float::INFINITY)
625
- assert_equal Float::INFINITY, db.execute("select avg(temperature) from foo").first.first
626
- end
627
-
628
- def test_default_transaction_mode
629
- tf = Tempfile.new 'database_default_transaction_mode'
630
- SQLite3::Database.new(tf.path) do |db|
631
- db.execute("create table foo (score int)")
632
- db.execute("insert into foo values (?)", 1)
633
- end
634
-
635
- test_cases = [
636
- {mode: nil, read: true, write: true},
637
- {mode: :deferred, read: true, write: true},
638
- {mode: :immediate, read: true, write: false},
639
- {mode: :exclusive, read: false, write: false},
640
- ]
641
-
642
- test_cases.each do |item|
643
- db = SQLite3::Database.new tf.path, default_transaction_mode: item[:mode]
644
- db2 = SQLite3::Database.new tf.path
645
- db.transaction do
646
- sql_for_read_test = "select * from foo"
647
- if item[:read]
648
- assert_nothing_raised{ db2.execute(sql_for_read_test) }
649
- else
650
- assert_raises(SQLite3::BusyException){ db2.execute(sql_for_read_test) }
651
- end
652
-
653
- sql_for_write_test = "insert into foo values (2)"
654
- if item[:write]
655
- assert_nothing_raised{ db2.execute(sql_for_write_test) }
656
- else
657
- assert_raises(SQLite3::BusyException){ db2.execute(sql_for_write_test) }
658
- end
659
- end
660
- ensure
661
- db.close if db && !db.closed?
662
- db2.close if db2 && !db2.closed?
663
- end
664
- ensure
665
- tf.unlink if tf
666
- end
667
- end
668
- end