sqlite3 1.5.0-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sqlite3 might be problematic. Click here for more details.

Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/API_CHANGES.md +49 -0
  4. data/CHANGELOG.md +425 -0
  5. data/CONTRIBUTING.md +24 -0
  6. data/ChangeLog.cvs +88 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +27 -0
  9. data/LICENSE-DEPENDENCIES +20 -0
  10. data/README.md +233 -0
  11. data/ext/sqlite3/aggregator.c +274 -0
  12. data/ext/sqlite3/aggregator.h +12 -0
  13. data/ext/sqlite3/backup.c +168 -0
  14. data/ext/sqlite3/backup.h +15 -0
  15. data/ext/sqlite3/database.c +853 -0
  16. data/ext/sqlite3/database.h +17 -0
  17. data/ext/sqlite3/exception.c +98 -0
  18. data/ext/sqlite3/exception.h +8 -0
  19. data/ext/sqlite3/extconf.rb +252 -0
  20. data/ext/sqlite3/sqlite3.c +163 -0
  21. data/ext/sqlite3/sqlite3_ruby.h +48 -0
  22. data/ext/sqlite3/statement.c +442 -0
  23. data/ext/sqlite3/statement.h +16 -0
  24. data/faq/faq.md +431 -0
  25. data/faq/faq.rb +145 -0
  26. data/faq/faq.yml +426 -0
  27. data/lib/sqlite3/2.6/sqlite3_native.bundle +0 -0
  28. data/lib/sqlite3/2.7/sqlite3_native.bundle +0 -0
  29. data/lib/sqlite3/3.0/sqlite3_native.bundle +0 -0
  30. data/lib/sqlite3/3.1/sqlite3_native.bundle +0 -0
  31. data/lib/sqlite3/constants.rb +50 -0
  32. data/lib/sqlite3/database.rb +741 -0
  33. data/lib/sqlite3/errors.rb +35 -0
  34. data/lib/sqlite3/pragmas.rb +595 -0
  35. data/lib/sqlite3/resultset.rb +187 -0
  36. data/lib/sqlite3/statement.rb +145 -0
  37. data/lib/sqlite3/translator.rb +118 -0
  38. data/lib/sqlite3/value.rb +57 -0
  39. data/lib/sqlite3/version.rb +23 -0
  40. data/lib/sqlite3.rb +15 -0
  41. data/test/helper.rb +27 -0
  42. data/test/test_backup.rb +33 -0
  43. data/test/test_collation.rb +82 -0
  44. data/test/test_database.rb +545 -0
  45. data/test/test_database_flags.rb +95 -0
  46. data/test/test_database_readonly.rb +36 -0
  47. data/test/test_database_readwrite.rb +41 -0
  48. data/test/test_deprecated.rb +44 -0
  49. data/test/test_encoding.rb +155 -0
  50. data/test/test_integration.rb +507 -0
  51. data/test/test_integration_aggregate.rb +336 -0
  52. data/test/test_integration_open_close.rb +30 -0
  53. data/test/test_integration_pending.rb +115 -0
  54. data/test/test_integration_resultset.rb +142 -0
  55. data/test/test_integration_statement.rb +194 -0
  56. data/test/test_result_set.rb +37 -0
  57. data/test/test_sqlite3.rb +30 -0
  58. data/test/test_statement.rb +263 -0
  59. data/test/test_statement_execute.rb +35 -0
  60. metadata +190 -0
@@ -0,0 +1,545 @@
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 test_segv
15
+ assert_raises { SQLite3::Database.new 1 }
16
+ end
17
+
18
+ def test_db_filename
19
+ tf = nil
20
+ assert_equal '', @db.filename('main')
21
+ tf = Tempfile.new 'thing'
22
+ @db = SQLite3::Database.new tf.path
23
+ assert_equal File.realdirpath(tf.path), File.realdirpath(@db.filename('main'))
24
+ ensure
25
+ tf.unlink if tf
26
+ end
27
+
28
+ def test_filename
29
+ tf = nil
30
+ assert_equal '', @db.filename
31
+ tf = Tempfile.new 'thing'
32
+ @db = SQLite3::Database.new tf.path
33
+ assert_equal File.realdirpath(tf.path), File.realdirpath(@db.filename)
34
+ ensure
35
+ tf.unlink if tf
36
+ end
37
+
38
+ def test_filename_with_attachment
39
+ tf = nil
40
+ assert_equal '', @db.filename
41
+ tf = Tempfile.new 'thing'
42
+ @db.execute "ATTACH DATABASE '#{tf.path}' AS 'testing'"
43
+
44
+ assert_equal File.realdirpath(tf.path), File.realdirpath(@db.filename('testing'))
45
+ ensure
46
+ tf.unlink if tf
47
+ end
48
+
49
+
50
+ def test_filename_to_path
51
+ tf = Tempfile.new 'thing'
52
+ pn = Pathname tf.path
53
+ db = SQLite3::Database.new pn
54
+ assert_equal pn.realdirpath.to_s, File.realdirpath(db.filename)
55
+ ensure
56
+ tf.close! if tf
57
+ end
58
+
59
+
60
+ def test_error_code
61
+ begin
62
+ db.execute 'SELECT'
63
+ rescue SQLite3::SQLException => e
64
+ end
65
+ assert_equal 1, e.code
66
+ end
67
+
68
+ def test_extended_error_code
69
+ db.extended_result_codes = true
70
+ db.execute 'CREATE TABLE "employees" ("token" integer NOT NULL)'
71
+ begin
72
+ db.execute 'INSERT INTO employees (token) VALUES (NULL)'
73
+ rescue SQLite3::ConstraintException => e
74
+ end
75
+ assert_equal 1299, e.code
76
+ end
77
+
78
+ def test_bignum
79
+ num = 4907021672125087844
80
+ db.execute 'CREATE TABLE "employees" ("token" integer(8), "name" varchar(20) NOT NULL)'
81
+ db.execute "INSERT INTO employees(name, token) VALUES('employee-1', ?)", [num]
82
+ rows = db.execute 'select token from employees'
83
+ assert_equal num, rows.first.first
84
+ end
85
+
86
+ def test_blob
87
+ @db.execute("CREATE TABLE blobs ( id INTEGER, hash BLOB(10) )")
88
+ blob = Blob.new("foo\0bar")
89
+ @db.execute("INSERT INTO blobs VALUES (0, ?)", [blob])
90
+ assert_equal [[0, blob, blob.length, blob.length*2]], @db.execute("SELECT id, hash, length(hash), length(hex(hash)) FROM blobs")
91
+ end
92
+
93
+ def test_get_first_row
94
+ assert_equal [1], @db.get_first_row('SELECT 1')
95
+ end
96
+
97
+ def test_get_first_row_with_type_translation_and_hash_results
98
+ @db.results_as_hash = true
99
+ @db.type_translation = true
100
+ assert_equal({"1"=>1}, @db.get_first_row('SELECT 1'))
101
+ end
102
+
103
+ def test_execute_with_type_translation_and_hash
104
+ @db.results_as_hash = true
105
+ @db.type_translation = true
106
+ rows = []
107
+ @db.execute('SELECT 1') { |row| rows << row }
108
+
109
+ assert_equal({"1"=>1}, rows.first)
110
+ end
111
+
112
+ def test_encoding
113
+ assert @db.encoding, 'database has encoding'
114
+ end
115
+
116
+ def test_changes
117
+ @db.execute("CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, number integer)")
118
+ assert_equal 0, @db.changes
119
+ @db.execute("INSERT INTO items (number) VALUES (10)")
120
+ assert_equal 1, @db.changes
121
+ @db.execute_batch(
122
+ "UPDATE items SET number = (number + :nn) WHERE (number = :n)",
123
+ {"nn" => 20, "n" => 10})
124
+ assert_equal 1, @db.changes
125
+ assert_equal [[30]], @db.execute("select number from items")
126
+ end
127
+
128
+ def test_batch_last_comment_is_processed
129
+ # FIXME: nil as a successful return value is kinda dumb
130
+ assert_nil @db.execute_batch <<-eosql
131
+ CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT);
132
+ -- omg
133
+ eosql
134
+ end
135
+
136
+ def test_execute_batch2
137
+ @db.results_as_hash = true
138
+ return_value = @db.execute_batch2 <<-eosql
139
+ CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT, name string);
140
+ INSERT INTO items (name) VALUES ("foo");
141
+ INSERT INTO items (name) VALUES ("bar");
142
+ SELECT * FROM items;
143
+ eosql
144
+ assert_equal return_value, [{"id"=>"1","name"=>"foo"}, {"id"=>"2", "name"=>"bar"}]
145
+
146
+ return_value = @db.execute_batch2('SELECT * FROM items;') do |result|
147
+ result["id"] = result["id"].to_i
148
+ result
149
+ end
150
+ assert_equal return_value, [{"id"=>1,"name"=>"foo"}, {"id"=>2, "name"=>"bar"}]
151
+
152
+ return_value = @db.execute_batch2('INSERT INTO items (name) VALUES ("oof")')
153
+ assert_equal return_value, []
154
+
155
+ return_value = @db.execute_batch2(
156
+ 'CREATE TABLE employees (id integer PRIMARY KEY AUTOINCREMENT, name string, age integer(3));
157
+ INSERT INTO employees (age) VALUES (30);
158
+ INSERT INTO employees (age) VALUES (40);
159
+ INSERT INTO employees (age) VALUES (20);
160
+ SELECT age FROM employees;') do |result|
161
+ result["age"] = result["age"].to_i
162
+ result
163
+ end
164
+ assert_equal return_value, [{"age"=>30}, {"age"=>40}, {"age"=>20}]
165
+
166
+ return_value = @db.execute_batch2('SELECT name FROM employees');
167
+ assert_equal return_value, [{"name"=>nil}, {"name"=>nil}, {"name"=>nil}]
168
+
169
+ @db.results_as_hash = false
170
+ return_value = @db.execute_batch2(
171
+ 'CREATE TABLE managers (id integer PRIMARY KEY AUTOINCREMENT, age integer(3));
172
+ INSERT INTO managers (age) VALUES (50);
173
+ INSERT INTO managers (age) VALUES (60);
174
+ SELECT id, age from managers;') do |result|
175
+ result = result.map do |res|
176
+ res.to_i
177
+ end
178
+ result
179
+ end
180
+ assert_equal return_value, [[1, 50], [2, 60]]
181
+
182
+ assert_raises (RuntimeError) do
183
+ # "names" is not a valid column
184
+ @db.execute_batch2 'INSERT INTO items (names) VALUES ("bazz")'
185
+ end
186
+
187
+ end
188
+
189
+ def test_new
190
+ db = SQLite3::Database.new(':memory:')
191
+ assert db
192
+ end
193
+
194
+ def test_new_yields_self
195
+ thing = nil
196
+ SQLite3::Database.new(':memory:') do |db|
197
+ thing = db
198
+ end
199
+ assert_instance_of(SQLite3::Database, thing)
200
+ end
201
+
202
+ def test_new_with_options
203
+ # determine if Ruby is running on Big Endian platform
204
+ utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
205
+
206
+ if RUBY_VERSION >= "1.9"
207
+ db = SQLite3::Database.new(':memory:'.encode(utf16), :utf16 => true)
208
+ else
209
+ db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
210
+ :utf16 => true)
211
+ end
212
+ assert db
213
+ end
214
+
215
+ def test_close
216
+ db = SQLite3::Database.new(':memory:')
217
+ db.close
218
+ assert db.closed?
219
+ end
220
+
221
+ def test_block_closes_self
222
+ thing = nil
223
+ SQLite3::Database.new(':memory:') do |db|
224
+ thing = db
225
+ assert !thing.closed?
226
+ end
227
+ assert thing.closed?
228
+ end
229
+
230
+ def test_block_closes_self_even_raised
231
+ thing = nil
232
+ begin
233
+ SQLite3::Database.new(':memory:') do |db|
234
+ thing = db
235
+ raise
236
+ end
237
+ rescue
238
+ end
239
+ assert thing.closed?
240
+ end
241
+
242
+ def test_prepare
243
+ db = SQLite3::Database.new(':memory:')
244
+ stmt = db.prepare('select "hello world"')
245
+ assert_instance_of(SQLite3::Statement, stmt)
246
+ end
247
+
248
+ def test_block_prepare_does_not_double_close
249
+ db = SQLite3::Database.new(':memory:')
250
+ r = db.prepare('select "hello world"') do |stmt|
251
+ stmt.close
252
+ :foo
253
+ end
254
+ assert_equal :foo, r
255
+ end
256
+
257
+ def test_total_changes
258
+ db = SQLite3::Database.new(':memory:')
259
+ db.execute("create table foo ( a integer primary key, b text )")
260
+ db.execute("insert into foo (b) values ('hello')")
261
+ assert_equal 1, db.total_changes
262
+ end
263
+
264
+ def test_execute_returns_list_of_hash
265
+ db = SQLite3::Database.new(':memory:', :results_as_hash => true)
266
+ db.execute("create table foo ( a integer primary key, b text )")
267
+ db.execute("insert into foo (b) values ('hello')")
268
+ rows = db.execute("select * from foo")
269
+ assert_equal [{"a"=>1, "b"=>"hello"}], rows
270
+ end
271
+
272
+ def test_execute_yields_hash
273
+ db = SQLite3::Database.new(':memory:', :results_as_hash => true)
274
+ db.execute("create table foo ( a integer primary key, b text )")
275
+ db.execute("insert into foo (b) values ('hello')")
276
+ db.execute("select * from foo") do |row|
277
+ assert_equal({"a"=>1, "b"=>"hello"}, row)
278
+ end
279
+ end
280
+
281
+ def test_table_info
282
+ db = SQLite3::Database.new(':memory:', :results_as_hash => true)
283
+ db.execute("create table foo ( a integer primary key, b text )")
284
+ info = [{
285
+ "name" => "a",
286
+ "pk" => 1,
287
+ "notnull" => 0,
288
+ "type" => "integer",
289
+ "dflt_value" => nil,
290
+ "cid" => 0
291
+ },
292
+ {
293
+ "name" => "b",
294
+ "pk" => 0,
295
+ "notnull" => 0,
296
+ "type" => "text",
297
+ "dflt_value" => nil,
298
+ "cid" => 1
299
+ }]
300
+ assert_equal info, db.table_info('foo')
301
+ end
302
+
303
+ def test_total_changes_closed
304
+ db = SQLite3::Database.new(':memory:')
305
+ db.close
306
+ assert_raise(SQLite3::Exception) do
307
+ db.total_changes
308
+ end
309
+ end
310
+
311
+ def test_trace_requires_opendb
312
+ @db.close
313
+ assert_raise(SQLite3::Exception) do
314
+ @db.trace { |x| }
315
+ end
316
+ end
317
+
318
+ def test_trace_with_block
319
+ result = nil
320
+ @db.trace { |sql| result = sql }
321
+ @db.execute "select 'foo'"
322
+ assert_equal "select 'foo'", result
323
+ end
324
+
325
+ def test_trace_with_object
326
+ obj = Class.new {
327
+ attr_accessor :result
328
+ def call sql; @result = sql end
329
+ }.new
330
+
331
+ @db.trace(obj)
332
+ @db.execute "select 'foo'"
333
+ assert_equal "select 'foo'", obj.result
334
+ end
335
+
336
+ def test_trace_takes_nil
337
+ @db.trace(nil)
338
+ @db.execute "select 'foo'"
339
+ end
340
+
341
+ def test_last_insert_row_id_closed
342
+ @db.close
343
+ assert_raise(SQLite3::Exception) do
344
+ @db.last_insert_row_id
345
+ end
346
+ end
347
+
348
+ def test_define_function
349
+ called_with = nil
350
+ @db.define_function("hello") do |value|
351
+ called_with = value
352
+ end
353
+ @db.execute("select hello(10)")
354
+ assert_equal 10, called_with
355
+ end
356
+
357
+ def test_call_func_arg_type
358
+ called_with = nil
359
+ @db.define_function("hello") do |b, c, d|
360
+ called_with = [b, c, d]
361
+ nil
362
+ end
363
+ @db.execute("select hello(2.2, 'foo', NULL)")
364
+
365
+ assert_in_delta(2.2, called_with[0], 0.0001)
366
+ assert_equal("foo", called_with[1])
367
+ assert_nil(called_with[2])
368
+ end
369
+
370
+ def test_define_varargs
371
+ called_with = nil
372
+ @db.define_function("hello") do |*args|
373
+ called_with = args
374
+ nil
375
+ end
376
+ @db.execute("select hello(2.2, 'foo', NULL)")
377
+
378
+ assert_in_delta(2.2, called_with[0], 0.0001)
379
+ assert_equal("foo", called_with[1])
380
+ assert_nil(called_with[2])
381
+ end
382
+
383
+ def test_call_func_blob
384
+ called_with = nil
385
+ @db.define_function("hello") do |a, b|
386
+ called_with = [a, b, a.length]
387
+ nil
388
+ end
389
+ blob = Blob.new("a\0fine\0kettle\0of\0fish")
390
+ @db.execute("select hello(?, length(?))", [blob, blob])
391
+ assert_equal [blob, blob.length, 21], called_with
392
+ end
393
+
394
+ def test_function_return
395
+ @db.define_function("hello") { |a| 10 }
396
+ assert_equal [10], @db.execute("select hello('world')").first
397
+ end
398
+
399
+ def test_function_return_types
400
+ [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
401
+ @db.define_function("hello") { |a| thing }
402
+ assert_equal [thing], @db.execute("select hello('world')").first
403
+ end
404
+ end
405
+
406
+ def test_function_gc_segfault
407
+ @db.create_function("bug", -1) { |func, *values| func.result = values.join }
408
+ # With a lot of data and a lot of threads, try to induce a GC segfault.
409
+ params = Array.new(127, "?" * 28000)
410
+ proc = Proc.new {
411
+ db.execute("select bug(#{Array.new(params.length, "?").join(",")})", params)
412
+ }
413
+ m = Mutex.new
414
+ 30.times.map { Thread.new { m.synchronize { proc.call } } }.each(&:join)
415
+ end
416
+
417
+ def test_function_return_type_round_trip
418
+ [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
419
+ @db.define_function("hello") { |a| a }
420
+ assert_equal [thing], @db.execute("select hello(hello(?))", [thing]).first
421
+ end
422
+ end
423
+
424
+ def test_define_function_closed
425
+ @db.close
426
+ assert_raise(SQLite3::Exception) do
427
+ @db.define_function('foo') { }
428
+ end
429
+ end
430
+
431
+ def test_inerrupt_closed
432
+ @db.close
433
+ assert_raise(SQLite3::Exception) do
434
+ @db.interrupt
435
+ end
436
+ end
437
+
438
+ def test_define_aggregate
439
+ @db.execute "create table foo ( a integer primary key, b text )"
440
+ @db.execute "insert into foo ( b ) values ( 'foo' )"
441
+ @db.execute "insert into foo ( b ) values ( 'bar' )"
442
+ @db.execute "insert into foo ( b ) values ( 'baz' )"
443
+
444
+ acc = Class.new {
445
+ attr_reader :sum
446
+ alias :finalize :sum
447
+ def initialize
448
+ @sum = 0
449
+ end
450
+
451
+ def step a
452
+ @sum += a
453
+ end
454
+ }.new
455
+
456
+ @db.define_aggregator("accumulate", acc)
457
+ value = @db.get_first_value( "select accumulate(a) from foo" )
458
+ assert_equal 6, value
459
+ end
460
+
461
+ def test_authorizer_ok
462
+ @db.authorizer = Class.new {
463
+ def call action, a, b, c, d; true end
464
+ }.new
465
+ @db.prepare("select 'fooooo'")
466
+
467
+ @db.authorizer = Class.new {
468
+ def call action, a, b, c, d; 0 end
469
+ }.new
470
+ @db.prepare("select 'fooooo'")
471
+ end
472
+
473
+ def test_authorizer_ignore
474
+ @db.authorizer = Class.new {
475
+ def call action, a, b, c, d; nil end
476
+ }.new
477
+ stmt = @db.prepare("select 'fooooo'")
478
+ assert_nil stmt.step
479
+ end
480
+
481
+ def test_authorizer_fail
482
+ @db.authorizer = Class.new {
483
+ def call action, a, b, c, d; false end
484
+ }.new
485
+ assert_raises(SQLite3::AuthorizationException) do
486
+ @db.prepare("select 'fooooo'")
487
+ end
488
+ end
489
+
490
+ def test_remove_auth
491
+ @db.authorizer = Class.new {
492
+ def call action, a, b, c, d; false end
493
+ }.new
494
+ assert_raises(SQLite3::AuthorizationException) do
495
+ @db.prepare("select 'fooooo'")
496
+ end
497
+
498
+ @db.authorizer = nil
499
+ @db.prepare("select 'fooooo'")
500
+ end
501
+
502
+ def test_close_with_open_statements
503
+ @db.prepare("select 'foo'")
504
+ assert_raises(SQLite3::BusyException) do
505
+ @db.close
506
+ end
507
+ end
508
+
509
+ def test_execute_with_empty_bind_params
510
+ assert_equal [['foo']], @db.execute("select 'foo'", [])
511
+ end
512
+
513
+ def test_query_with_named_bind_params
514
+ assert_equal [['foo']], @db.query("select :n", {'n' => 'foo'}).to_a
515
+ end
516
+
517
+ def test_execute_with_named_bind_params
518
+ assert_equal [['foo']], @db.execute("select :n", {'n' => 'foo'})
519
+ end
520
+
521
+ def test_strict_mode
522
+ unless Gem::Requirement.new(">= 3.29.0").satisfied_by?(Gem::Version.new(SQLite3::SQLITE_VERSION))
523
+ skip("strict mode feature not available in #{SQLite3::SQLITE_VERSION}")
524
+ end
525
+
526
+ db = SQLite3::Database.new(':memory:')
527
+ db.execute('create table numbers (val int);')
528
+ db.execute('create index index_numbers_nope ON numbers ("nope");') # nothing raised
529
+
530
+ db = SQLite3::Database.new(':memory:', :strict => true)
531
+ db.execute('create table numbers (val int);')
532
+ error = assert_raises SQLite3::SQLException do
533
+ db.execute('create index index_numbers_nope ON numbers ("nope");')
534
+ end
535
+ assert_includes error.message, "no such column: nope"
536
+ end
537
+
538
+ def test_load_extension_with_nonstring_argument
539
+ db = SQLite3::Database.new(':memory:')
540
+ skip("extensions are not enabled") unless db.respond_to?(:load_extension)
541
+ assert_raises(TypeError) { db.load_extension(1) }
542
+ assert_raises(TypeError) { db.load_extension(Pathname.new("foo.so")) }
543
+ end
544
+ end
545
+ end
@@ -0,0 +1,95 @@
1
+ require 'helper'
2
+
3
+ module SQLite3
4
+ class TestDatabaseFlags < SQLite3::TestCase
5
+ def setup
6
+ File.unlink 'test-flags.db' if File.exist?('test-flags.db')
7
+ @db = SQLite3::Database.new('test-flags.db')
8
+ @db.execute("CREATE TABLE foos (id integer)")
9
+ @db.close
10
+ end
11
+
12
+ def teardown
13
+ @db.close unless @db.closed?
14
+ File.unlink 'test-flags.db' if File.exist?('test-flags.db')
15
+ end
16
+
17
+ def test_open_database_flags_constants
18
+ defined_to_date = [:READONLY, :READWRITE, :CREATE, :DELETEONCLOSE,
19
+ :EXCLUSIVE, :MAIN_DB, :TEMP_DB, :TRANSIENT_DB,
20
+ :MAIN_JOURNAL, :TEMP_JOURNAL, :SUBJOURNAL,
21
+ :MASTER_JOURNAL, :NOMUTEX, :FULLMUTEX]
22
+ if SQLite3::SQLITE_VERSION_NUMBER > 3007002
23
+ defined_to_date += [:AUTOPROXY, :SHAREDCACHE, :PRIVATECACHE, :WAL]
24
+ end
25
+ if SQLite3::SQLITE_VERSION_NUMBER > 3007007
26
+ defined_to_date += [:URI]
27
+ end
28
+ if SQLite3::SQLITE_VERSION_NUMBER > 3007013
29
+ defined_to_date += [:MEMORY]
30
+ end
31
+ assert defined_to_date.sort == SQLite3::Constants::Open.constants.sort
32
+ end
33
+
34
+ def test_open_database_flags_conflicts_with_readonly
35
+ assert_raise(RuntimeError) do
36
+ @db = SQLite3::Database.new('test-flags.db', :flags => 2, :readonly => true)
37
+ end
38
+ end
39
+
40
+ def test_open_database_flags_conflicts_with_readwrite
41
+ assert_raise(RuntimeError) do
42
+ @db = SQLite3::Database.new('test-flags.db', :flags => 2, :readwrite => true)
43
+ end
44
+ end
45
+
46
+ def test_open_database_readonly_flags
47
+ @db = SQLite3::Database.new('test-flags.db', :flags => SQLite3::Constants::Open::READONLY)
48
+ assert @db.readonly?
49
+ end
50
+
51
+ def test_open_database_readwrite_flags
52
+ @db = SQLite3::Database.new('test-flags.db', :flags => SQLite3::Constants::Open::READWRITE)
53
+ assert !@db.readonly?
54
+ end
55
+
56
+ def test_open_database_readonly_flags_cant_open
57
+ File.unlink 'test-flags.db'
58
+ assert_raise(SQLite3::CantOpenException) do
59
+ @db = SQLite3::Database.new('test-flags.db', :flags => SQLite3::Constants::Open::READONLY)
60
+ end
61
+ end
62
+
63
+ def test_open_database_readwrite_flags_cant_open
64
+ File.unlink 'test-flags.db'
65
+ assert_raise(SQLite3::CantOpenException) do
66
+ @db = SQLite3::Database.new('test-flags.db', :flags => SQLite3::Constants::Open::READWRITE)
67
+ end
68
+ end
69
+
70
+ def test_open_database_misuse_flags
71
+ assert_raise(SQLite3::MisuseException) do
72
+ flags = SQLite3::Constants::Open::READONLY | SQLite3::Constants::Open::READWRITE # <== incompatible flags
73
+ @db = SQLite3::Database.new('test-flags.db', :flags => flags)
74
+ end
75
+ end
76
+
77
+ def test_open_database_create_flags
78
+ File.unlink 'test-flags.db'
79
+ flags = SQLite3::Constants::Open::READWRITE | SQLite3::Constants::Open::CREATE
80
+ @db = SQLite3::Database.new('test-flags.db', :flags => flags) do |db|
81
+ db.execute("CREATE TABLE foos (id integer)")
82
+ db.execute("INSERT INTO foos (id) VALUES (12)")
83
+ end
84
+ assert File.exist?('test-flags.db')
85
+ end
86
+
87
+ def test_open_database_exotic_flags
88
+ flags = SQLite3::Constants::Open::READWRITE | SQLite3::Constants::Open::CREATE
89
+ exotic_flags = SQLite3::Constants::Open::NOMUTEX | SQLite3::Constants::Open::TEMP_DB
90
+ @db = SQLite3::Database.new('test-flags.db', :flags => flags | exotic_flags)
91
+ @db.execute("INSERT INTO foos (id) VALUES (12)")
92
+ assert @db.changes == 1
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+
3
+ module SQLite3
4
+ class TestDatabaseReadonly < SQLite3::TestCase
5
+ def setup
6
+ File.unlink 'test-readonly.db' if File.exist?('test-readonly.db')
7
+ @db = SQLite3::Database.new('test-readonly.db')
8
+ @db.execute("CREATE TABLE foos (id integer)")
9
+ @db.close
10
+ end
11
+
12
+ def teardown
13
+ @db.close unless @db.closed?
14
+ File.unlink 'test-readonly.db' if File.exist?('test-readonly.db')
15
+ end
16
+
17
+ def test_open_readonly_database
18
+ @db = SQLite3::Database.new('test-readonly.db', :readonly => true)
19
+ assert @db.readonly?
20
+ end
21
+
22
+ def test_open_readonly_not_exists_database
23
+ File.unlink 'test-readonly.db'
24
+ assert_raise(SQLite3::CantOpenException) do
25
+ @db = SQLite3::Database.new('test-readonly.db', :readonly => true)
26
+ end
27
+ end
28
+
29
+ def test_insert_readonly_database
30
+ @db = SQLite3::Database.new('test-readonly.db', :readonly => true)
31
+ assert_raise(SQLite3::ReadOnlyException) do
32
+ @db.execute("INSERT INTO foos (id) VALUES (12)")
33
+ end
34
+ end
35
+ end
36
+ end