sqlite3 1.3.5 → 1.3.13

Sign up to get free protection for your applications and to get access to all the features.
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