sqlite3 1.3.5 → 1.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/test/helper.rb CHANGED
@@ -1,3 +1,18 @@
1
1
  require 'sqlite3'
2
- require 'test/unit'
3
- require 'iconv'
2
+ require 'minitest/autorun'
3
+
4
+ unless RUBY_VERSION >= "1.9"
5
+ require 'iconv'
6
+ end
7
+
8
+ module SQLite3
9
+ class TestCase < Minitest::Test
10
+ alias :assert_not_equal :refute_equal
11
+ alias :assert_not_nil :refute_nil
12
+ alias :assert_raise :assert_raises
13
+
14
+ def assert_nothing_raised
15
+ yield
16
+ end
17
+ end
18
+ end
data/test/test_backup.rb CHANGED
@@ -1,7 +1,7 @@
1
- require File.expand_path('helper', File.dirname(__FILE__))
1
+ require 'helper'
2
2
 
3
3
  module SQLite3
4
- class TestBackup < Test::Unit::TestCase
4
+ class TestBackup < SQLite3::TestCase
5
5
  def setup
6
6
  @sdb = SQLite3::Database.new(':memory:')
7
7
  @ddb = SQLite3::Database.new(':memory:')
@@ -3,7 +3,7 @@
3
3
  require 'helper'
4
4
 
5
5
  module SQLite3
6
- class TestCollation < Test::Unit::TestCase
6
+ class TestCollation < SQLite3::TestCase
7
7
  class Comparator
8
8
  attr_reader :calls
9
9
  def initialize
@@ -1,17 +1,50 @@
1
1
  require 'helper'
2
+ require 'tempfile'
3
+ require 'pathname'
2
4
 
3
5
  module SQLite3
4
- class TestDatabase < Test::Unit::TestCase
6
+ class TestDatabase < SQLite3::TestCase
5
7
  attr_reader :db
6
8
 
7
9
  def setup
8
10
  @db = SQLite3::Database.new(':memory:')
11
+ super
9
12
  end
10
13
 
11
14
  def test_segv
12
15
  assert_raises(TypeError) { SQLite3::Database.new 1 }
13
16
  end
14
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.expand_path(tf.path), File.expand_path(@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.expand_path(tf.path), File.expand_path(@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
+ assert_equal File.expand_path(tf.path), File.expand_path(@db.filename('testing'))
44
+ ensure
45
+ tf.unlink if tf
46
+ end
47
+
15
48
  def test_bignum
16
49
  num = 4907021672125087844
17
50
  db.execute 'CREATE TABLE "employees" ("token" integer(8), "name" varchar(20) NOT NULL)'
@@ -22,9 +55,9 @@ module SQLite3
22
55
 
23
56
  def test_blob
24
57
  @db.execute("CREATE TABLE blobs ( id INTEGER, hash BLOB(10) )")
25
- str = "\0foo"
26
- @db.execute("INSERT INTO blobs VALUES (0, ?)", [str])
27
- assert_equal [[0, str]], @db.execute("SELECT * FROM blobs")
58
+ blob = Blob.new("foo\0bar")
59
+ @db.execute("INSERT INTO blobs VALUES (0, ?)", [blob])
60
+ assert_equal [[0, blob, blob.length, blob.length*2]], @db.execute("SELECT id, hash, length(hash), length(hex(hash)) FROM blobs")
28
61
  end
29
62
 
30
63
  def test_get_first_row
@@ -60,6 +93,14 @@ module SQLite3
60
93
  assert_equal [[30]], @db.execute("select number from items")
61
94
  end
62
95
 
96
+ def test_batch_last_comment_is_processed
97
+ # FIXME: nil as a successful return value is kinda dumb
98
+ assert_nil @db.execute_batch <<-eosql
99
+ CREATE TABLE items (id integer PRIMARY KEY AUTOINCREMENT);
100
+ -- omg
101
+ eosql
102
+ end
103
+
63
104
  def test_new
64
105
  db = SQLite3::Database.new(':memory:')
65
106
  assert db
@@ -77,8 +118,12 @@ module SQLite3
77
118
  # determine if Ruby is running on Big Endian platform
78
119
  utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
79
120
 
80
- db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
81
- :utf16 => true)
121
+ if RUBY_VERSION >= "1.9"
122
+ db = SQLite3::Database.new(':memory:'.encode(utf16), :utf16 => true)
123
+ else
124
+ db = SQLite3::Database.new(Iconv.conv(utf16, 'UTF-8', ':memory:'),
125
+ :utf16 => true)
126
+ end
82
127
  assert db
83
128
  end
84
129
 
@@ -97,12 +142,33 @@ module SQLite3
97
142
  assert thing.closed?
98
143
  end
99
144
 
145
+ def test_block_closes_self_even_raised
146
+ thing = nil
147
+ begin
148
+ SQLite3::Database.new(':memory:') do |db|
149
+ thing = db
150
+ raise
151
+ end
152
+ rescue
153
+ end
154
+ assert thing.closed?
155
+ end
156
+
100
157
  def test_prepare
101
158
  db = SQLite3::Database.new(':memory:')
102
159
  stmt = db.prepare('select "hello world"')
103
160
  assert_instance_of(SQLite3::Statement, stmt)
104
161
  end
105
162
 
163
+ def test_block_prepare_does_not_double_close
164
+ db = SQLite3::Database.new(':memory:')
165
+ r = db.prepare('select "hello world"') do |stmt|
166
+ stmt.close
167
+ :foo
168
+ end
169
+ assert_equal :foo, r
170
+ end
171
+
106
172
  def test_total_changes
107
173
  db = SQLite3::Database.new(':memory:')
108
174
  db.execute("create table foo ( a integer primary key, b text )")
@@ -223,18 +289,47 @@ module SQLite3
223
289
  assert_equal [2.2, 'foo', nil], called_with
224
290
  end
225
291
 
292
+ def test_call_func_blob
293
+ called_with = nil
294
+ @db.define_function("hello") do |a, b|
295
+ called_with = [a, b, a.length]
296
+ nil
297
+ end
298
+ blob = Blob.new("a\0fine\0kettle\0of\0fish")
299
+ @db.execute("select hello(?, length(?))", [blob, blob])
300
+ assert_equal [blob, blob.length, 21], called_with
301
+ end
302
+
226
303
  def test_function_return
227
304
  @db.define_function("hello") { |a| 10 }
228
305
  assert_equal [10], @db.execute("select hello('world')").first
229
306
  end
230
307
 
231
308
  def test_function_return_types
232
- [10, 2.2, nil, "foo"].each do |thing|
309
+ [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
233
310
  @db.define_function("hello") { |a| thing }
234
311
  assert_equal [thing], @db.execute("select hello('world')").first
235
312
  end
236
313
  end
237
314
 
315
+ def test_function_gc_segfault
316
+ @db.create_function("bug", -1) { |func, *values| func.result = values.join }
317
+ # With a lot of data and a lot of threads, try to induce a GC segfault.
318
+ params = Array.new(127, "?" * 28000)
319
+ proc = Proc.new {
320
+ db.execute("select bug(#{Array.new(params.length, "?").join(",")})", params)
321
+ }
322
+ m = Mutex.new
323
+ 30.times.map { Thread.new { m.synchronize { proc.call } } }.each(&:join)
324
+ end
325
+
326
+ def test_function_return_type_round_trip
327
+ [10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
328
+ @db.define_function("hello") { |a| a }
329
+ assert_equal [thing], @db.execute("select hello(hello(?))", [thing]).first
330
+ end
331
+ end
332
+
238
333
  def test_define_function_closed
239
334
  @db.close
240
335
  assert_raise(SQLite3::Exception) do
@@ -1,9 +1,9 @@
1
1
  require 'helper'
2
2
 
3
3
  module SQLite3
4
- class TestDatabaseReadonly < Test::Unit::TestCase
4
+ class TestDatabaseReadonly < SQLite3::TestCase
5
5
  def setup
6
- File.unlink 'test-readonly.db' if File.exists?('test-readonly.db')
6
+ File.unlink 'test-readonly.db' if File.exist?('test-readonly.db')
7
7
  @db = SQLite3::Database.new('test-readonly.db')
8
8
  @db.execute("CREATE TABLE foos (id integer)")
9
9
  @db.close
@@ -11,7 +11,7 @@ module SQLite3
11
11
 
12
12
  def teardown
13
13
  @db.close unless @db.closed?
14
- File.unlink 'test-readonly.db'
14
+ File.unlink 'test-readonly.db' if File.exist?('test-readonly.db')
15
15
  end
16
16
 
17
17
  def test_open_readonly_database
@@ -19,6 +19,13 @@ module SQLite3
19
19
  assert @db.readonly?
20
20
  end
21
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
+
22
29
  def test_insert_readonly_database
23
30
  @db = SQLite3::Database.new('test-readonly.db', :readonly => true)
24
31
  assert_raise(SQLite3::ReadOnlyException) do
@@ -1,12 +1,15 @@
1
1
  require 'helper'
2
2
 
3
3
  module SQLite3
4
- class TestDeprecated < Test::Unit::TestCase
4
+ class TestDeprecated < SQLite3::TestCase
5
+ attr_reader :db
6
+
5
7
  def setup
6
8
  super
7
9
  @warn_before = $-w
8
10
  $-w = false
9
11
  @db = SQLite3::Database.new(':memory:')
12
+ @db.execute 'CREATE TABLE test_table (name text, age int)'
10
13
  end
11
14
 
12
15
  def teardown
@@ -14,6 +17,10 @@ module SQLite3
14
17
  $-w = @warn_before
15
18
  end
16
19
 
20
+ def test_query_with_many_bind_params_not_nil
21
+ assert_equal [[1, 2]], db.query('select ?, ?', 1, 2).to_a
22
+ end
23
+
17
24
  def test_execute_with_many_bind_params_not_nil
18
25
  assert_equal [[1, 2]], @db.execute("select ?, ?", 1, 2).to_a
19
26
  end
@@ -3,7 +3,7 @@
3
3
  require 'helper'
4
4
 
5
5
  module SQLite3
6
- class TestEncoding < Test::Unit::TestCase
6
+ class TestEncoding < SQLite3::TestCase
7
7
  def setup
8
8
  @db = SQLite3::Database.new(':memory:')
9
9
  @create = "create table ex(id int, data string)"
@@ -11,6 +11,40 @@ module SQLite3
11
11
  @db.execute(@create);
12
12
  end
13
13
 
14
+ def test_select_encoding_on_utf_16
15
+ str = "foo"
16
+ utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
17
+ db = SQLite3::Database.new(':memory:'.encode(utf16))
18
+ db.execute @create
19
+ db.execute "insert into ex (id, data) values (1, \"#{str}\")"
20
+
21
+ stmt = db.prepare 'select * from ex where data = ?'
22
+ ['US-ASCII', utf16, 'EUC-JP', 'UTF-8'].each do |enc|
23
+ stmt.bind_param 1, str.encode(enc)
24
+ assert_equal 1, stmt.to_a.length
25
+ stmt.reset!
26
+ end
27
+ end
28
+
29
+ def test_insert_encoding
30
+ str = "foo"
31
+ utf16 = ([1].pack("I") == [1].pack("N")) ? "UTF-16BE" : "UTF-16LE"
32
+ db = SQLite3::Database.new(':memory:'.encode(utf16))
33
+ db.execute @create
34
+ stmt = db.prepare @insert
35
+
36
+ ['US-ASCII', utf16, 'EUC-JP', 'UTF-8'].each_with_index do |enc,i|
37
+ stmt.bind_param 1, i
38
+ stmt.bind_param 2, str.encode(enc)
39
+ stmt.to_a
40
+ stmt.reset!
41
+ end
42
+
43
+ db.execute('select data from ex').flatten.each do |s|
44
+ assert_equal str, s
45
+ end
46
+ end
47
+
14
48
  def test_default_internal_is_honored
15
49
  warn_before = $-w
16
50
  $-w = false
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TC_Database_Integration < Test::Unit::TestCase
3
+ class TC_Database_Integration < SQLite3::TestCase
4
4
  def setup
5
5
  @db = SQLite3::Database.new(":memory:")
6
6
  @db.transaction do
@@ -21,12 +21,14 @@ class TC_Database_Integration < Test::Unit::TestCase
21
21
 
22
22
  def test_table_info_with_defaults_for_version_3_3_8_and_higher
23
23
  @db.transaction do
24
- @db.execute "create table defaults_test ( a string default NULL, b string default 'Hello' )"
24
+ @db.execute "create table defaults_test ( a string default NULL, b string default 'Hello', c string default '--- []\n' )"
25
25
  data = @db.table_info( "defaults_test" )
26
26
  assert_equal({"name" => "a", "type" => "string", "dflt_value" => nil, "notnull" => 0, "cid" => 0, "pk" => 0},
27
27
  data[0])
28
28
  assert_equal({"name" => "b", "type" => "string", "dflt_value" => "Hello", "notnull" => 0, "cid" => 1, "pk" => 0},
29
29
  data[1])
30
+ assert_equal({"name" => "c", "type" => "string", "dflt_value" => "--- []\n", "notnull" => 0, "cid" => 2, "pk" => 0},
31
+ data[2])
30
32
  end
31
33
  end
32
34
 
@@ -236,7 +238,7 @@ class TC_Database_Integration < Test::Unit::TestCase
236
238
 
237
239
  def test_execute2_with_block_with_bind_with_match
238
240
  called = 0
239
- @db.execute2( "select * from foo where a = ?", 1 ) do |row|
241
+ @db.execute2( "select * from foo where a = ?", 1 ) do
240
242
  called += 1
241
243
  end
242
244
  assert_equal 2, called
@@ -497,6 +499,10 @@ class TC_Database_Integration < Test::Unit::TestCase
497
499
 
498
500
  value = @db.get_first_value( "select accumulate(a) from foo" )
499
501
  assert_equal 6, value
502
+
503
+ # calling #get_first_value twice don't add up to the latest result
504
+ value = @db.get_first_value( "select accumulate(a) from foo" )
505
+ assert_equal 6, value
500
506
  end
501
507
 
502
508
  def test_create_aggregate_with_block
@@ -528,21 +534,36 @@ class TC_Database_Integration < Test::Unit::TestCase
528
534
  assert_equal 0, value
529
535
  end
530
536
 
531
- def test_create_aggregate_handler
532
- handler = Class.new do
533
- class << self
534
- def arity; 1; end
535
- def text_rep; SQLite3::Constants::TextRep::ANY; end
536
- def name; "multiply"; end
537
- end
538
- def step(ctx, a)
539
- ctx[:buffer] ||= 1
540
- ctx[:buffer] *= a.to_i
537
+ class AggregateHandler
538
+ class << self
539
+ def arity; 1; end
540
+ def text_rep; SQLite3::Constants::TextRep::ANY; end
541
+ def name; "multiply"; end
542
+ end
543
+ def step(ctx, a)
544
+ ctx[:buffer] ||= 1
545
+ ctx[:buffer] *= a.to_i
546
+ end
547
+ def finalize(ctx); ctx.result = ctx[:buffer]; end
548
+ end
549
+
550
+ def test_aggregate_initialized_twice
551
+ initialized = 0
552
+ handler = Class.new(AggregateHandler) do
553
+ define_method(:initialize) do
554
+ initialized += 1
555
+ super()
541
556
  end
542
- def finalize(ctx); ctx.result = ctx[:buffer]; end
543
557
  end
544
558
 
545
- @db.create_aggregate_handler( handler )
559
+ @db.create_aggregate_handler handler
560
+ @db.get_first_value( "select multiply(a) from foo" )
561
+ @db.get_first_value( "select multiply(a) from foo" )
562
+ assert_equal 2, initialized
563
+ end
564
+
565
+ def test_create_aggregate_handler
566
+ @db.create_aggregate_handler AggregateHandler
546
567
  value = @db.get_first_value( "select multiply(a) from foo" )
547
568
  assert_equal 6, value
548
569
  end
@@ -1,6 +1,6 @@
1
1
  require 'helper'
2
2
 
3
- class TC_OpenClose < Test::Unit::TestCase
3
+ class TC_OpenClose < SQLite3::TestCase
4
4
  def test_create_close
5
5
  begin
6
6
  db = SQLite3::Database.new( "test-create.db" )
@@ -3,7 +3,7 @@ require 'helper'
3
3
  require 'thread'
4
4
  require 'benchmark'
5
5
 
6
- class TC_Integration_Pending < Test::Unit::TestCase
6
+ class TC_Integration_Pending < SQLite3::TestCase
7
7
  def setup
8
8
  @db = SQLite3::Database.new("test.db")
9
9
  @db.transaction do
@@ -69,7 +69,7 @@ class TC_Integration_Pending < Test::Unit::TestCase
69
69
  end
70
70
  sleep 1
71
71
 
72
- @db.busy_handler do |count|
72
+ @db.busy_handler do
73
73
  handler_call_count += 1
74
74
  false
75
75
  end