sqlite3-ruby 1.2.5 → 1.3.0.beta.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/API_CHANGES.rdoc +48 -0
  2. data/{History.txt → CHANGELOG.rdoc} +24 -0
  3. data/Manifest.txt +14 -14
  4. data/{README.txt → README.rdoc} +1 -6
  5. data/Rakefile +8 -3
  6. data/ext/sqlite3/database.c +687 -0
  7. data/ext/sqlite3/database.h +15 -0
  8. data/ext/sqlite3/exception.c +94 -0
  9. data/ext/sqlite3/exception.h +8 -0
  10. data/ext/sqlite3/extconf.rb +26 -0
  11. data/ext/sqlite3/sqlite3.c +33 -0
  12. data/ext/sqlite3/sqlite3_ruby.h +43 -0
  13. data/ext/sqlite3/statement.c +412 -0
  14. data/ext/sqlite3/statement.h +16 -0
  15. data/lib/sqlite3.rb +9 -0
  16. data/lib/sqlite3/database.rb +94 -302
  17. data/lib/sqlite3/errors.rb +0 -24
  18. data/lib/sqlite3/pragmas.rb +16 -7
  19. data/lib/sqlite3/resultset.rb +25 -81
  20. data/lib/sqlite3/statement.rb +22 -107
  21. data/lib/sqlite3/version.rb +4 -4
  22. data/setup.rb +2 -2
  23. data/tasks/native.rake +13 -17
  24. data/tasks/vendor_sqlite3.rake +10 -7
  25. data/test/helper.rb +1 -65
  26. data/test/test_database.rb +239 -189
  27. data/test/test_encoding.rb +115 -0
  28. data/test/test_integration.rb +38 -35
  29. data/test/test_integration_open_close.rb +1 -1
  30. data/test/test_integration_pending.rb +6 -4
  31. data/test/test_integration_resultset.rb +20 -8
  32. data/test/test_integration_statement.rb +1 -2
  33. data/test/test_sqlite3.rb +9 -0
  34. data/test/test_statement.rb +193 -0
  35. metadata +82 -48
  36. data/ext/sqlite3_api/extconf.rb +0 -10
  37. data/ext/sqlite3_api/sqlite3_api.i +0 -362
  38. data/ext/sqlite3_api/sqlite3_api_wrap.c +0 -5018
  39. data/lib/sqlite3/driver/dl/api.rb +0 -152
  40. data/lib/sqlite3/driver/dl/driver.rb +0 -307
  41. data/lib/sqlite3/driver/native/driver.rb +0 -219
  42. data/tasks/benchmark.rake +0 -9
  43. data/tasks/gem.rake +0 -32
  44. data/test/bm.rb +0 -140
  45. data/test/driver/dl/tc_driver.rb +0 -292
  46. data/test/native-vs-dl.rb +0 -126
  47. data/test/test_errors.rb +0 -17
@@ -0,0 +1,115 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'helper'
4
+
5
+ module SQLite3
6
+ class TestEncoding < Test::Unit::TestCase
7
+ def setup
8
+ @db = SQLite3::Database.new(':memory:')
9
+ @create = "create table ex(id int, data string)"
10
+ @insert = "insert into ex(id, data) values (?, ?)"
11
+ @db.execute(@create);
12
+ end
13
+
14
+ def test_default_internal_is_honored
15
+ before_enc = Encoding.default_internal
16
+
17
+ str = "壁に耳あり、障子に目あり"
18
+ stmt = @db.prepare('insert into ex(data) values (?)')
19
+ stmt.bind_param 1, str
20
+ stmt.step
21
+
22
+ Encoding.default_internal = 'EUC-JP'
23
+ string = @db.execute('select data from ex').first.first
24
+
25
+ assert_equal Encoding.default_internal, string.encoding
26
+ assert_equal str.encode('EUC-JP'), string
27
+ assert_equal str, string.encode(str.encoding)
28
+ ensure
29
+ Encoding.default_internal = before_enc
30
+ end
31
+
32
+ def test_blob_is_binary
33
+ str = "猫舌"
34
+ @db.execute('create table foo(data text)')
35
+ stmt = @db.prepare('insert into foo(data) values (?)')
36
+ stmt.bind_param(1, SQLite3::Blob.new(str))
37
+ stmt.step
38
+
39
+ string = @db.execute('select data from foo').first.first
40
+ assert_equal Encoding.find('ASCII-8BIT'), string.encoding
41
+ assert_equal str, string.force_encoding('UTF-8')
42
+ end
43
+
44
+ def test_blob_is_ascii8bit
45
+ str = "猫舌"
46
+ @db.execute('create table foo(data text)')
47
+ stmt = @db.prepare('insert into foo(data) values (?)')
48
+ stmt.bind_param(1, str.dup.force_encoding("ASCII-8BIT"))
49
+ stmt.step
50
+
51
+ string = @db.execute('select data from foo').first.first
52
+ assert_equal Encoding.find('ASCII-8BIT'), string.encoding
53
+ assert_equal str, string.force_encoding('UTF-8')
54
+ end
55
+
56
+ def test_blob_with_eucjp
57
+ str = "猫舌".encode("EUC-JP")
58
+ @db.execute('create table foo(data text)')
59
+ stmt = @db.prepare('insert into foo(data) values (?)')
60
+ stmt.bind_param(1, SQLite3::Blob.new(str))
61
+ stmt.step
62
+
63
+ string = @db.execute('select data from foo').first.first
64
+ assert_equal Encoding.find('ASCII-8BIT'), string.encoding
65
+ assert_equal str, string.force_encoding('EUC-JP')
66
+ end
67
+
68
+ def test_db_with_eucjp
69
+ db = SQLite3::Database.new(':memory:'.encode('EUC-JP'))
70
+ assert_equal(Encoding.find('UTF-8'), db.encoding)
71
+ end
72
+
73
+ def test_db_with_utf16
74
+ db = SQLite3::Database.new(':memory:'.encode('UTF-16LE'))
75
+ assert_equal(Encoding.find('UTF-16LE'), db.encoding)
76
+ end
77
+
78
+ def test_statement_eucjp
79
+ str = "猫舌"
80
+ @db.execute("insert into ex(data) values ('#{str}')".encode('EUC-JP'))
81
+ row = @db.execute("select data from ex")
82
+ assert_equal @db.encoding, row.first.first.encoding
83
+ assert_equal str, row.first.first
84
+ end
85
+
86
+ def test_statement_utf8
87
+ str = "猫舌"
88
+ @db.execute("insert into ex(data) values ('#{str}')")
89
+ row = @db.execute("select data from ex")
90
+ assert_equal @db.encoding, row.first.first.encoding
91
+ assert_equal str, row.first.first
92
+ end
93
+
94
+ def test_encoding
95
+ assert_equal Encoding.find("UTF-8"), @db.encoding
96
+ end
97
+
98
+ def test_utf_8
99
+ str = "猫舌"
100
+ @db.execute(@insert, 10, str)
101
+ row = @db.execute("select data from ex")
102
+ assert_equal @db.encoding, row.first.first.encoding
103
+ assert_equal str, row.first.first
104
+ end
105
+
106
+ def test_euc_jp
107
+ str = "猫舌".encode('EUC-JP')
108
+ @db.execute(@insert, 10, str)
109
+ row = @db.execute("select data from ex")
110
+ assert_equal @db.encoding, row.first.first.encoding
111
+ assert_equal str.encode('UTF-8'), row.first.first
112
+ end
113
+
114
+ end if RUBY_VERSION >= '1.9.1'
115
+ end
@@ -1,8 +1,8 @@
1
- require File.join(File.dirname(__FILE__), 'helper')
1
+ require 'helper'
2
2
 
3
3
  class TC_Database_Integration < Test::Unit::TestCase
4
4
  def setup
5
- @db = SQLite3::Database.new( "test.db" )
5
+ @db = SQLite3::Database.new(":memory:")
6
6
  @db.transaction do
7
7
  @db.execute "create table foo ( a integer primary key, b text )"
8
8
  @db.execute "insert into foo ( b ) values ( 'foo' )"
@@ -13,7 +13,6 @@ class TC_Database_Integration < Test::Unit::TestCase
13
13
 
14
14
  def teardown
15
15
  @db.close
16
- File.delete( "test.db" )
17
16
  end
18
17
 
19
18
  def test_table_info_with_type_translation_active
@@ -25,9 +24,9 @@ class TC_Database_Integration < Test::Unit::TestCase
25
24
  @db.transaction do
26
25
  @db.execute "create table defaults_test ( a string default NULL, b string default 'Hello' )"
27
26
  data = @db.table_info( "defaults_test" )
28
- assert_equal({"name" => "a", "type" => "string", "dflt_value" => nil, "notnull" => "0", "cid" => "0", "pk" => "0"},
27
+ assert_equal({"name" => "a", "type" => "string", "dflt_value" => nil, "notnull" => 0, "cid" => 0, "pk" => 0},
29
28
  data[0])
30
- assert_equal({"name" => "b", "type" => "string", "dflt_value" => "Hello", "notnull" => "0", "cid" => "1", "pk" => "0"},
29
+ assert_equal({"name" => "b", "type" => "string", "dflt_value" => "Hello", "notnull" => 0, "cid" => 1, "pk" => 0},
31
30
  data[1])
32
31
  end
33
32
  end
@@ -36,9 +35,9 @@ class TC_Database_Integration < Test::Unit::TestCase
36
35
  @db.transaction do
37
36
  @db.execute "create table no_defaults_test ( a integer default 1, b integer )"
38
37
  data = @db.table_info( "no_defaults_test" )
39
- assert_equal({"name" => "a", "type" => "integer", "dflt_value" => "1", "notnull" => "0", "cid" => "0", "pk" => "0"},
38
+ assert_equal({"name" => "a", "type" => "integer", "dflt_value" => "1", "notnull" => 0, "cid" => 0, "pk" => 0},
40
39
  data[0])
41
- assert_equal({"name" => "b", "type" => "integer", "dflt_value" => nil, "notnull" => "0", "cid" => "1", "pk" => "0"},
40
+ assert_equal({"name" => "b", "type" => "integer", "dflt_value" => nil, "notnull" => 0, "cid" => 1, "pk" => 0},
42
41
  data[1])
43
42
  end
44
43
  end
@@ -50,21 +49,25 @@ class TC_Database_Integration < Test::Unit::TestCase
50
49
  assert @db.complete?( "select * from foo;" )
51
50
  end
52
51
 
53
- def test_complete_fail_utf16
54
- assert !@db.complete?( "select * from foo".to_utf16(false), true )
55
- end
52
+ # FIXME: do people really need UTF16 sql statements?
53
+ #def test_complete_fail_utf16
54
+ # assert !@db.complete?( "select * from foo".to_utf16(false), true )
55
+ #end
56
56
 
57
- def test_complete_success_utf16
58
- assert @db.complete?( "select * from foo;".to_utf16(true), true )
59
- end
57
+ # FIXME: do people really need UTF16 sql statements?
58
+ #def test_complete_success_utf16
59
+ # assert @db.complete?( "select * from foo;".to_utf16(true), true )
60
+ #end
60
61
 
61
62
  def test_errmsg
62
63
  assert_equal "not an error", @db.errmsg
63
64
  end
64
65
 
65
- def test_errmsg_utf16
66
- assert_equal "not an error".to_utf16, @db.errmsg(true)
67
- end
66
+ # FIXME: do people really need UTF16 error messages?
67
+ #def test_errmsg_utf16
68
+ # msg = Iconv.conv('UTF-16', 'UTF-8', 'not an error')
69
+ # assert_equal msg, @db.errmsg(true)
70
+ #end
68
71
 
69
72
  def test_errcode
70
73
  assert_equal 0, @db.errcode
@@ -72,26 +75,26 @@ class TC_Database_Integration < Test::Unit::TestCase
72
75
 
73
76
  def test_trace
74
77
  result = nil
75
- @db.trace( "data" ) { |data,sql| result = [ data, sql ]; 0 }
78
+ @db.trace { |sql| result = sql }
76
79
  @db.execute "select * from foo"
77
- assert_equal ["data","select * from foo"], result
80
+ assert_equal "select * from foo", result
78
81
  end
79
82
 
80
83
  def test_authorizer_okay
81
- @db.authorizer( "data" ) { |data,type,a,b,c,d| 0 }
84
+ @db.authorizer { |type,a,b,c,d| 0 }
82
85
  rows = @db.execute "select * from foo"
83
86
  assert_equal 3, rows.length
84
87
  end
85
88
 
86
89
  def test_authorizer_error
87
- @db.authorizer( "data" ) { |data,type,a,b,c,d| 1 }
90
+ @db.authorizer { |type,a,b,c,d| 1 }
88
91
  assert_raise( SQLite3::AuthorizationException ) do
89
92
  @db.execute "select * from foo"
90
93
  end
91
94
  end
92
95
 
93
96
  def test_authorizer_silent
94
- @db.authorizer( "data" ) { |data,type,a,b,c,d| 2 }
97
+ @db.authorizer { |type,a,b,c,d| 2 }
95
98
  rows = @db.execute "select * from foo"
96
99
  assert rows.empty?
97
100
  end
@@ -184,7 +187,7 @@ class TC_Database_Integration < Test::Unit::TestCase
184
187
  def test_execute2_no_block_no_bind_no_match
185
188
  columns, *rows = @db.execute2( "select * from foo where a > 100" )
186
189
  assert rows.empty?
187
- assert [ "a", "b" ], columns
190
+ assert_equal [ "a", "b" ], columns
188
191
  end
189
192
 
190
193
  def test_execute2_with_block_no_bind_no_match
@@ -199,13 +202,13 @@ class TC_Database_Integration < Test::Unit::TestCase
199
202
  def test_execute2_no_block_with_bind_no_match
200
203
  columns, *rows = @db.execute2( "select * from foo where a > ?", 100 )
201
204
  assert rows.empty?
202
- assert [ "a", "b" ], columns
205
+ assert_equal [ "a", "b" ], columns
203
206
  end
204
207
 
205
208
  def test_execute2_with_block_with_bind_no_match
206
209
  called = 0
207
210
  @db.execute2( "select * from foo where a > ?", 100 ) do |row|
208
- assert [ "a", "b" ], row unless called == 0
211
+ assert_equal [ "a", "b" ], row unless called == 0
209
212
  called += 1
210
213
  end
211
214
  assert_equal 1, called
@@ -214,13 +217,13 @@ class TC_Database_Integration < Test::Unit::TestCase
214
217
  def test_execute2_no_block_no_bind_with_match
215
218
  columns, *rows = @db.execute2( "select * from foo where a = 1" )
216
219
  assert_equal 1, rows.length
217
- assert [ "a", "b" ], columns
220
+ assert_equal [ "a", "b" ], columns
218
221
  end
219
222
 
220
223
  def test_execute2_with_block_no_bind_with_match
221
224
  called = 0
222
225
  @db.execute2( "select * from foo where a = 1" ) do |row|
223
- assert [ "a", "b" ], row unless called == 0
226
+ assert_equal [ 1, "foo" ], row unless called == 0
224
227
  called += 1
225
228
  end
226
229
  assert_equal 2, called
@@ -229,7 +232,7 @@ class TC_Database_Integration < Test::Unit::TestCase
229
232
  def test_execute2_no_block_with_bind_with_match
230
233
  columns, *rows = @db.execute2( "select * from foo where a = ?", 1 )
231
234
  assert_equal 1, rows.length
232
- assert [ "a", "b" ], columns
235
+ assert_equal [ "a", "b" ], columns
233
236
  end
234
237
 
235
238
  def test_execute2_with_block_with_bind_with_match
@@ -265,7 +268,7 @@ class TC_Database_Integration < Test::Unit::TestCase
265
268
  insert into bar values ( 'seven', 8, ? );
266
269
  SQL
267
270
  rows = @db.execute( "select * from bar" ).map { |a,b,c| c }
268
- assert_equal %w{1 1 1}, rows
271
+ assert_equal [1, 1, 1], rows
269
272
  end
270
273
 
271
274
  def test_query_no_block_no_bind_no_match
@@ -339,7 +342,7 @@ class TC_Database_Integration < Test::Unit::TestCase
339
342
 
340
343
  def test_get_first_row_no_bind_with_match
341
344
  result = @db.get_first_row( "select * from foo where a=1" )
342
- assert_equal [ "1", "foo" ], result
345
+ assert_equal [ 1, "foo" ], result
343
346
  end
344
347
 
345
348
  def test_get_first_row_with_bind_no_match
@@ -349,7 +352,7 @@ class TC_Database_Integration < Test::Unit::TestCase
349
352
 
350
353
  def test_get_first_row_with_bind_with_match
351
354
  result = @db.get_first_row( "select * from foo where a=?", 1 )
352
- assert_equal [ "1", "foo" ], result
355
+ assert_equal [ 1, "foo" ], result
353
356
  end
354
357
 
355
358
  def test_get_first_value_no_bind_no_match
@@ -458,7 +461,7 @@ class TC_Database_Integration < Test::Unit::TestCase
458
461
  func.result = x
459
462
  end
460
463
 
461
- assert_raise( SQLite3::SQLException ) do
464
+ assert_raise( SQLite3::InterruptException ) do
462
465
  @db.execute "select abort(a) from foo"
463
466
  end
464
467
  end
@@ -483,7 +486,7 @@ class TC_Database_Integration < Test::Unit::TestCase
483
486
  @db.create_aggregate( "accumulate", 1, step, final )
484
487
 
485
488
  value = @db.get_first_value( "select accumulate(a) from foo" )
486
- assert_equal "6", value
489
+ assert_equal 6, value
487
490
  end
488
491
 
489
492
  def test_create_aggregate_with_block
@@ -497,7 +500,7 @@ class TC_Database_Integration < Test::Unit::TestCase
497
500
  end
498
501
 
499
502
  value = @db.get_first_value( "select accumulate(a) from foo" )
500
- assert_equal "6", value
503
+ assert_equal 6, value
501
504
  end
502
505
 
503
506
  def test_create_aggregate_with_no_data
@@ -512,7 +515,7 @@ class TC_Database_Integration < Test::Unit::TestCase
512
515
 
513
516
  value = @db.get_first_value(
514
517
  "select accumulate(a) from foo where a = 100" )
515
- assert_equal "0", value
518
+ assert_equal 0, value
516
519
  end
517
520
 
518
521
  def test_create_aggregate_handler
@@ -531,7 +534,7 @@ class TC_Database_Integration < Test::Unit::TestCase
531
534
 
532
535
  @db.create_aggregate_handler( handler )
533
536
  value = @db.get_first_value( "select multiply(a) from foo" )
534
- assert_equal "6", value
537
+ assert_equal 6, value
535
538
  end
536
539
 
537
540
  def test_bind_array_parameter
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), 'helper')
1
+ require 'helper'
2
2
 
3
3
  class TC_OpenClose < Test::Unit::TestCase
4
4
  def test_create_close
@@ -1,11 +1,11 @@
1
- require File.join(File.dirname(__FILE__), 'helper')
1
+ require 'helper'
2
2
 
3
3
  require 'thread'
4
4
  require 'benchmark'
5
5
 
6
6
  class TC_Integration_Pending < Test::Unit::TestCase
7
7
  def setup
8
- @db = SQLite3::Database.new( "test.db" )
8
+ @db = SQLite3::Database.new("test.db")
9
9
  @db.transaction do
10
10
  @db.execute "create table foo ( a integer primary key, b text )"
11
11
  @db.execute "insert into foo ( b ) values ( 'foo' )"
@@ -65,8 +65,9 @@ class TC_Integration_Pending < Test::Unit::TestCase
65
65
  db2.close if db2
66
66
  end
67
67
  end
68
+ sleep 1
68
69
 
69
- @db.busy_handler do |data, count|
70
+ @db.busy_handler do |count|
70
71
  handler_call_count += 1
71
72
  false
72
73
  end
@@ -97,6 +98,7 @@ class TC_Integration_Pending < Test::Unit::TestCase
97
98
  end
98
99
  end
99
100
 
101
+ sleep 1
100
102
  time = Benchmark.measure do
101
103
  assert_raise( SQLite3::BusyException ) do
102
104
  @db.execute "insert into foo (b) values ( 'from 2' )"
@@ -108,4 +110,4 @@ class TC_Integration_Pending < Test::Unit::TestCase
108
110
 
109
111
  assert time.real*1000 >= 1000
110
112
  end
111
- end
113
+ end
@@ -1,8 +1,8 @@
1
- require File.join(File.dirname(__FILE__), 'helper')
1
+ require 'helper'
2
2
 
3
3
  class TC_ResultSet < Test::Unit::TestCase
4
4
  def setup
5
- @db = SQLite3::Database.new( "test.db" )
5
+ @db = SQLite3::Database.new(":memory:")
6
6
  @db.transaction do
7
7
  @db.execute "create table foo ( a integer primary key, b text )"
8
8
  @db.execute "insert into foo ( b ) values ( 'foo' )"
@@ -16,7 +16,6 @@ class TC_ResultSet < Test::Unit::TestCase
16
16
  def teardown
17
17
  @stmt.close
18
18
  @db.close
19
- File.delete( "test.db" )
20
19
  end
21
20
 
22
21
  def test_reset_unused
@@ -56,7 +55,7 @@ class TC_ResultSet < Test::Unit::TestCase
56
55
 
57
56
  def test_next_no_type_translation_no_hash
58
57
  @result.reset( 1 )
59
- assert_equal [ "1", "foo" ], @result.next
58
+ assert_equal [ 1, "foo" ], @result.next
60
59
  end
61
60
 
62
61
  def test_next_type_translation
@@ -68,7 +67,7 @@ class TC_ResultSet < Test::Unit::TestCase
68
67
  def test_next_type_translation_with_untyped_column
69
68
  @db.type_translation = true
70
69
  @db.query( "select count(*) from foo" ) do |result|
71
- assert_equal ["3"], result.next
70
+ assert_equal [3], result.next
72
71
  end
73
72
  end
74
73
 
@@ -98,10 +97,23 @@ class TC_ResultSet < Test::Unit::TestCase
98
97
  end
99
98
  end
100
99
 
100
+ def test_real_translation
101
+ @db.type_translation = true
102
+ @db.execute('create table foo_real(a real)')
103
+ @db.execute('insert into foo_real values (42)' )
104
+ @db.query('select a, sum(a), typeof(a), typeof(sum(a)) from foo_real') do |result|
105
+ result = result.next
106
+ assert result[0].is_a?(Float)
107
+ assert result[1].is_a?(Float)
108
+ assert result[2].is_a?(String)
109
+ assert result[3].is_a?(String)
110
+ end
111
+ end
112
+
101
113
  def test_next_results_as_hash
102
114
  @db.results_as_hash = true
103
115
  @result.reset( 1 )
104
- assert_equal( { "a" => "1", "b" => "foo", 0 => "1", 1 => "foo" },
116
+ assert_equal( { "a" => 1, "b" => "foo", 0 => 1, 1 => "foo" },
105
117
  @result.next )
106
118
  end
107
119
 
@@ -110,7 +122,7 @@ class TC_ResultSet < Test::Unit::TestCase
110
122
  @result.reset( 1 )
111
123
  row = @result.next
112
124
  row.each do |_, v|
113
- assert_equal true, v.tainted?
125
+ assert(v.tainted?) if String === v
114
126
  end
115
127
  end
116
128
 
@@ -118,7 +130,7 @@ class TC_ResultSet < Test::Unit::TestCase
118
130
  @result.reset( 1 )
119
131
  row = @result.next
120
132
  row.each do |v|
121
- assert_equal true, v.tainted?
133
+ assert(v.tainted?) if String === v
122
134
  end
123
135
  end
124
136