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,336 @@
1
+ require 'helper'
2
+
3
+ class TC_Integration_Aggregate < SQLite3::TestCase
4
+ def setup
5
+ @db = SQLite3::Database.new(":memory:")
6
+ @db.transaction do
7
+ @db.execute "create table foo ( a integer primary key, b text, c integer )"
8
+ @db.execute "insert into foo ( b, c ) values ( 'foo', 10 )"
9
+ @db.execute "insert into foo ( b, c ) values ( 'bar', 11 )"
10
+ @db.execute "insert into foo ( b, c ) values ( 'bar', 12 )"
11
+ end
12
+ end
13
+
14
+ def teardown
15
+ @db.close
16
+ end
17
+
18
+ def test_create_aggregate_without_block
19
+ step = proc do |ctx,a|
20
+ ctx[:sum] ||= 0
21
+ ctx[:sum] += a.to_i
22
+ end
23
+
24
+ final = proc { |ctx| ctx.result = ctx[:sum] }
25
+
26
+ @db.create_aggregate( "accumulate", 1, step, final )
27
+
28
+ value = @db.get_first_value( "select accumulate(a) from foo" )
29
+ assert_equal 6, value
30
+
31
+ # calling #get_first_value twice don't add up to the latest result
32
+ value = @db.get_first_value( "select accumulate(a) from foo" )
33
+ assert_equal 6, value
34
+ end
35
+
36
+ def test_create_aggregate_with_block
37
+ @db.create_aggregate( "accumulate", 1 ) do
38
+ step do |ctx,a|
39
+ ctx[:sum] ||= 0
40
+ ctx[:sum] += a.to_i
41
+ end
42
+
43
+ finalize { |ctx| ctx.result = ctx[:sum] }
44
+ end
45
+
46
+ value = @db.get_first_value( "select accumulate(a) from foo" )
47
+ assert_equal 6, value
48
+ end
49
+
50
+ def test_create_aggregate_with_group_by
51
+ @db.create_aggregate( "accumulate", 1 ) do
52
+ step do |ctx,a|
53
+ ctx[:sum] ||= 0
54
+ ctx[:sum] += a.to_i
55
+ end
56
+
57
+ finalize { |ctx| ctx.result = ctx[:sum] }
58
+ end
59
+
60
+ values = @db.execute( "select b, accumulate(c) from foo group by b order by b" )
61
+ assert_equal "bar", values[0][0]
62
+ assert_equal 23, values[0][1]
63
+ assert_equal "foo", values[1][0]
64
+ assert_equal 10, values[1][1]
65
+ end
66
+
67
+ def test_create_aggregate_with_the_same_function_twice_in_a_query
68
+ @db.create_aggregate( "accumulate", 1 ) do
69
+ step do |ctx,a|
70
+ ctx[:sum] ||= 0
71
+ ctx[:sum] += a.to_i
72
+ end
73
+
74
+ finalize { |ctx| ctx.result = ctx[:sum] }
75
+ end
76
+
77
+ values = @db.get_first_row( "select accumulate(a), accumulate(c) from foo" )
78
+ assert_equal 6, values[0]
79
+ assert_equal 33, values[1]
80
+ end
81
+
82
+ def test_create_aggregate_with_two_different_functions
83
+ @db.create_aggregate( "accumulate", 1 ) do
84
+ step do |ctx,a|
85
+ ctx[:sum] ||= 0
86
+ ctx[:sum] += a.to_i
87
+ end
88
+
89
+ finalize { |ctx| ctx.result = ctx[:sum] }
90
+ end
91
+
92
+ @db.create_aggregate( "multiply", 1 ) do
93
+ step do |ctx,a|
94
+ ctx[:sum] ||= 1
95
+ ctx[:sum] *= a.to_i
96
+ end
97
+
98
+ finalize { |ctx| ctx.result = ctx[:sum] }
99
+ end
100
+
101
+ GC.start
102
+
103
+ values = @db.get_first_row( "select accumulate(a), multiply(c) from foo" )
104
+ assert_equal 6, values[0]
105
+ assert_equal 1320, values[1]
106
+
107
+ value = @db.get_first_value( "select accumulate(c) from foo")
108
+ assert_equal 33, value
109
+
110
+ value = @db.get_first_value( "select multiply(a) from foo")
111
+ assert_equal 6, value
112
+ end
113
+
114
+ def test_create_aggregate_overwrite_function
115
+ @db.create_aggregate( "accumulate", 1 ) do
116
+ step do |ctx,a|
117
+ ctx[:sum] ||= 0
118
+ ctx[:sum] += a.to_i
119
+ end
120
+
121
+ finalize { |ctx| ctx.result = ctx[:sum] }
122
+ end
123
+
124
+ value = @db.get_first_value( "select accumulate(c) from foo")
125
+ assert_equal 33, value
126
+
127
+ GC.start
128
+
129
+ @db.create_aggregate( "accumulate", 1 ) do
130
+ step do |ctx,a|
131
+ ctx[:sum] ||= 1
132
+ ctx[:sum] *= a.to_i
133
+ end
134
+
135
+ finalize { |ctx| ctx.result = ctx[:sum] }
136
+ end
137
+
138
+ value = @db.get_first_value( "select accumulate(c) from foo")
139
+ assert_equal 1320, value
140
+ end
141
+
142
+ def test_create_aggregate_overwrite_function_with_different_arity
143
+ @db.create_aggregate( "accumulate", -1 ) do
144
+ step do |ctx,*args|
145
+ ctx[:sum] ||= 0
146
+ args.each { |a| ctx[:sum] += a.to_i }
147
+ end
148
+
149
+ finalize { |ctx| ctx.result = ctx[:sum] }
150
+ end
151
+
152
+ @db.create_aggregate( "accumulate", 2 ) do
153
+ step do |ctx,a,b|
154
+ ctx[:sum] ||= 1
155
+ ctx[:sum] *= (a.to_i + b.to_i)
156
+ end
157
+
158
+ finalize { |ctx| ctx.result = ctx[:sum] }
159
+ end
160
+
161
+ GC.start
162
+
163
+ values = @db.get_first_row( "select accumulate(c), accumulate(a,c) from foo")
164
+ assert_equal 33, values[0]
165
+ assert_equal 2145, values[1]
166
+ end
167
+
168
+ def test_create_aggregate_with_invalid_arity
169
+ assert_raise ArgumentError do
170
+ @db.create_aggregate( "accumulate", 1000 ) do
171
+ step {|ctx,*args| }
172
+ finalize { |ctx| }
173
+ end
174
+ end
175
+ end
176
+
177
+ class CustomException < Exception
178
+ end
179
+
180
+ def test_create_aggregate_with_exception_in_step
181
+ @db.create_aggregate( "raiseexception", 1 ) do
182
+ step do |ctx,a|
183
+ raise CustomException.new( "bogus aggregate handler" )
184
+ end
185
+
186
+ finalize { |ctx| ctx.result = 42 }
187
+ end
188
+
189
+ assert_raise CustomException do
190
+ @db.get_first_value( "select raiseexception(a) from foo")
191
+ end
192
+ end
193
+
194
+ def test_create_aggregate_with_exception_in_finalize
195
+ @db.create_aggregate( "raiseexception", 1 ) do
196
+ step do |ctx,a|
197
+ raise CustomException.new( "bogus aggregate handler" )
198
+ end
199
+
200
+ finalize do |ctx|
201
+ raise CustomException.new( "bogus aggregate handler" )
202
+ end
203
+ end
204
+
205
+ assert_raise CustomException do
206
+ @db.get_first_value( "select raiseexception(a) from foo")
207
+ end
208
+ end
209
+
210
+ def test_create_aggregate_with_no_data
211
+ @db.create_aggregate( "accumulate", 1 ) do
212
+ step do |ctx,a|
213
+ ctx[:sum] ||= 0
214
+ ctx[:sum] += a.to_i
215
+ end
216
+
217
+ finalize { |ctx| ctx.result = ctx[:sum] || 0 }
218
+ end
219
+
220
+ value = @db.get_first_value(
221
+ "select accumulate(a) from foo where a = 100" )
222
+ assert_equal 0, value
223
+ end
224
+
225
+ class AggregateHandler
226
+ class << self
227
+ def arity; 1; end
228
+ def text_rep; SQLite3::Constants::TextRep::ANY; end
229
+ def name; "multiply"; end
230
+ end
231
+ def step(ctx, a)
232
+ ctx[:buffer] ||= 1
233
+ ctx[:buffer] *= a.to_i
234
+ end
235
+ def finalize(ctx); ctx.result = ctx[:buffer]; end
236
+ end
237
+
238
+ def test_aggregate_initialized_twice
239
+ initialized = 0
240
+ handler = Class.new(AggregateHandler) do
241
+ define_method(:initialize) do
242
+ initialized += 1
243
+ super()
244
+ end
245
+ end
246
+
247
+ @db.create_aggregate_handler handler
248
+ @db.get_first_value( "select multiply(a) from foo" )
249
+ @db.get_first_value( "select multiply(a) from foo" )
250
+ assert_equal 2, initialized
251
+ end
252
+
253
+ def test_create_aggregate_handler_call_with_wrong_arity
254
+ @db.create_aggregate_handler AggregateHandler
255
+
256
+ assert_raise(SQLite3::SQLException) do
257
+ @db.get_first_value( "select multiply(a,c) from foo" )
258
+ end
259
+ end
260
+
261
+ class RaiseExceptionStepAggregateHandler
262
+ class << self
263
+ def arity; 1; end
264
+ def text_rep; SQLite3::Constants::TextRep::ANY; end
265
+ def name; "raiseexception"; end
266
+ end
267
+ def step(ctx, a)
268
+ raise CustomException.new( "bogus aggregate handler" )
269
+ end
270
+ def finalize(ctx); ctx.result = nil; end
271
+ end
272
+
273
+ def test_create_aggregate_handler_with_exception_step
274
+ @db.create_aggregate_handler RaiseExceptionStepAggregateHandler
275
+ assert_raise CustomException do
276
+ @db.get_first_value( "select raiseexception(a) from foo")
277
+ end
278
+ end
279
+
280
+ class RaiseExceptionNewAggregateHandler
281
+ class << self
282
+ def name; "raiseexception"; end
283
+ end
284
+ def initialize
285
+ raise CustomException.new( "bogus aggregate handler" )
286
+ end
287
+ def step(ctx, a); end
288
+ def finalize(ctx); ctx.result = nil; end
289
+ end
290
+
291
+ def test_create_aggregate_handler_with_exception_new
292
+ @db.create_aggregate_handler RaiseExceptionNewAggregateHandler
293
+ assert_raise CustomException do
294
+ @db.get_first_value( "select raiseexception(a) from foo")
295
+ end
296
+ end
297
+
298
+ def test_create_aggregate_handler
299
+ @db.create_aggregate_handler AggregateHandler
300
+ value = @db.get_first_value( "select multiply(a) from foo" )
301
+ assert_equal 6, value
302
+ end
303
+
304
+ class AccumulateAggregator
305
+ def step(*args)
306
+ @sum ||= 0
307
+ args.each { |a| @sum += a.to_i }
308
+ end
309
+
310
+ def finalize
311
+ @sum
312
+ end
313
+ end
314
+
315
+ class AccumulateAggregator2
316
+ def step(a, b)
317
+ @sum ||= 1
318
+ @sum *= (a.to_i + b.to_i)
319
+ end
320
+
321
+ def finalize
322
+ @sum
323
+ end
324
+ end
325
+
326
+ def test_define_aggregator_with_two_different_arities
327
+ @db.define_aggregator( "accumulate", AccumulateAggregator.new )
328
+ @db.define_aggregator( "accumulate", AccumulateAggregator2.new )
329
+
330
+ GC.start
331
+
332
+ values = @db.get_first_row( "select accumulate(c), accumulate(a,c) from foo")
333
+ assert_equal 33, values[0]
334
+ assert_equal 2145, values[1]
335
+ end
336
+ end
@@ -0,0 +1,30 @@
1
+ require 'helper'
2
+
3
+ class TC_OpenClose < SQLite3::TestCase
4
+ def test_create_close
5
+ begin
6
+ db = SQLite3::Database.new( "test-create.db" )
7
+ assert File.exist?( "test-create.db" )
8
+ assert_nothing_raised { db.close }
9
+ ensure
10
+ File.delete( "test-create.db" ) rescue nil
11
+ end
12
+ end
13
+
14
+ def test_open_close
15
+ begin
16
+ File.open( "test-open.db", "w" ) { |f| }
17
+ assert File.exist?( "test-open.db" )
18
+ db = SQLite3::Database.new( "test-open.db" )
19
+ assert_nothing_raised { db.close }
20
+ ensure
21
+ File.delete( "test-open.db" ) rescue nil
22
+ end
23
+ end
24
+
25
+ def test_bad_open
26
+ assert_raise( SQLite3::CantOpenException ) do
27
+ SQLite3::Database.new( "." )
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,115 @@
1
+ require 'helper'
2
+
3
+ require 'thread'
4
+ require 'benchmark'
5
+
6
+ class TC_Integration_Pending < SQLite3::TestCase
7
+ def setup
8
+ @db = SQLite3::Database.new("test.db")
9
+ @db.transaction do
10
+ @db.execute "create table foo ( a integer primary key, b text )"
11
+ @db.execute "insert into foo ( b ) values ( 'foo' )"
12
+ @db.execute "insert into foo ( b ) values ( 'bar' )"
13
+ @db.execute "insert into foo ( b ) values ( 'baz' )"
14
+ end
15
+ end
16
+
17
+ def teardown
18
+ @db.close
19
+ File.delete( "test.db" )
20
+ end
21
+
22
+ def test_busy_handler_outwait
23
+ skip("not working in 1.9") if RUBY_VERSION >= '1.9'
24
+
25
+ busy = Mutex.new
26
+ busy.lock
27
+ handler_call_count = 0
28
+
29
+ t = Thread.new(busy) do |locker|
30
+ begin
31
+ db2 = SQLite3::Database.open( "test.db" )
32
+ db2.transaction( :exclusive ) do
33
+ locker.lock
34
+ end
35
+ ensure
36
+ db2.close if db2
37
+ end
38
+ end
39
+
40
+ @db.busy_handler do |data,count|
41
+ handler_call_count += 1
42
+ busy.unlock
43
+ true
44
+ end
45
+
46
+ assert_nothing_raised do
47
+ @db.execute "insert into foo (b) values ( 'from 2' )"
48
+ end
49
+
50
+ t.join
51
+
52
+ assert_equal 1, handler_call_count
53
+ end
54
+
55
+ def test_busy_handler_impatient
56
+ busy = Mutex.new
57
+ busy.lock
58
+ handler_call_count = 0
59
+
60
+ t = Thread.new do
61
+ begin
62
+ db2 = SQLite3::Database.open( "test.db" )
63
+ db2.transaction( :exclusive ) do
64
+ busy.lock
65
+ end
66
+ ensure
67
+ db2.close if db2
68
+ end
69
+ end
70
+ sleep 1
71
+
72
+ @db.busy_handler do
73
+ handler_call_count += 1
74
+ false
75
+ end
76
+
77
+ assert_raise( SQLite3::BusyException ) do
78
+ @db.execute "insert into foo (b) values ( 'from 2' )"
79
+ end
80
+
81
+ busy.unlock
82
+ t.join
83
+
84
+ assert_equal 1, handler_call_count
85
+ end
86
+
87
+ def test_busy_timeout
88
+ @db.busy_timeout 1000
89
+ busy = Mutex.new
90
+ busy.lock
91
+
92
+ t = Thread.new do
93
+ begin
94
+ db2 = SQLite3::Database.open( "test.db" )
95
+ db2.transaction( :exclusive ) do
96
+ busy.lock
97
+ end
98
+ ensure
99
+ db2.close if db2
100
+ end
101
+ end
102
+
103
+ sleep 1
104
+ time = Benchmark.measure do
105
+ assert_raise( SQLite3::BusyException ) do
106
+ @db.execute "insert into foo (b) values ( 'from 2' )"
107
+ end
108
+ end
109
+
110
+ busy.unlock
111
+ t.join
112
+
113
+ assert time.real*1000 >= 1000
114
+ end
115
+ end
@@ -0,0 +1,142 @@
1
+ require 'helper'
2
+
3
+ class TC_ResultSet < SQLite3::TestCase
4
+ def setup
5
+ @db = SQLite3::Database.new(":memory:")
6
+ @db.transaction do
7
+ @db.execute "create table foo ( a integer primary key, b text )"
8
+ @db.execute "insert into foo ( b ) values ( 'foo' )"
9
+ @db.execute "insert into foo ( b ) values ( 'bar' )"
10
+ @db.execute "insert into foo ( b ) values ( 'baz' )"
11
+ end
12
+ @stmt = @db.prepare( "select * from foo where a in ( ?, ? )" )
13
+ @result = @stmt.execute
14
+ end
15
+
16
+ def teardown
17
+ @stmt.close
18
+ @db.close
19
+ end
20
+
21
+ def test_reset_unused
22
+ assert_nothing_raised { @result.reset }
23
+ assert @result.to_a.empty?
24
+ end
25
+
26
+ def test_reset_used
27
+ @result.to_a
28
+ assert_nothing_raised { @result.reset }
29
+ assert @result.to_a.empty?
30
+ end
31
+
32
+ def test_reset_with_bind
33
+ @result.to_a
34
+ assert_nothing_raised { @result.reset( 1, 2 ) }
35
+ assert_equal 2, @result.to_a.length
36
+ end
37
+
38
+ def test_eof_inner
39
+ @result.reset( 1 )
40
+ assert !@result.eof?
41
+ end
42
+
43
+ def test_eof_edge
44
+ @result.reset( 1 )
45
+ @result.next # to first row
46
+ @result.next # to end of result set
47
+ assert @result.eof?
48
+ end
49
+
50
+ def test_next_eof
51
+ @result.reset( 1 )
52
+ assert_not_nil @result.next
53
+ assert_nil @result.next
54
+ end
55
+
56
+ def test_next_no_type_translation_no_hash
57
+ @result.reset( 1 )
58
+ assert_equal [ 1, "foo" ], @result.next
59
+ end
60
+
61
+ def test_next_type_translation
62
+ @result.reset( 1 )
63
+ assert_equal [ 1, "foo" ], @result.next
64
+ end
65
+
66
+ def test_next_type_translation_with_untyped_column
67
+ @db.query( "select count(*) from foo" ) do |result|
68
+ assert_equal [3], result.next
69
+ end
70
+ end
71
+
72
+ def test_type_translation_with_null_column
73
+ time = '1974-07-25 14:39:00'
74
+
75
+ @db.execute "create table bar ( a integer, b time, c string )"
76
+ @db.execute "insert into bar (a, b, c) values (NULL, '#{time}', 'hello')"
77
+ @db.execute "insert into bar (a, b, c) values (1, NULL, 'hello')"
78
+ @db.execute "insert into bar (a, b, c) values (2, '#{time}', NULL)"
79
+ @db.query( "select * from bar" ) do |result|
80
+ assert_equal [nil, time, 'hello'], result.next
81
+ assert_equal [1, nil, 'hello'], result.next
82
+ assert_equal [2, time, nil], result.next
83
+ end
84
+ end
85
+
86
+ def test_real_translation
87
+ @db.execute('create table foo_real(a real)')
88
+ @db.execute('insert into foo_real values (42)' )
89
+ @db.query('select a, sum(a), typeof(a), typeof(sum(a)) from foo_real') do |result|
90
+ result = result.next
91
+ assert result[0].is_a?(Float)
92
+ assert result[1].is_a?(Float)
93
+ assert result[2].is_a?(String)
94
+ assert result[3].is_a?(String)
95
+ end
96
+ end
97
+
98
+ def test_next_results_as_hash
99
+ @db.results_as_hash = true
100
+ @result.reset( 1 )
101
+ hash = @result.next
102
+ assert_equal( { "a" => 1, "b" => "foo" },
103
+ hash )
104
+ assert_equal hash[0], 1
105
+ assert_equal hash[1], "foo"
106
+ end
107
+
108
+ def test_each
109
+ called = 0
110
+ @result.reset( 1, 2 )
111
+ @result.each { |row| called += 1 }
112
+ assert_equal 2, called
113
+ end
114
+
115
+ def test_enumerable
116
+ @result.reset( 1, 2 )
117
+ assert_equal 2, @result.to_a.length
118
+ end
119
+
120
+ def test_types
121
+ assert_equal [ "integer", "text" ], @result.types
122
+ end
123
+
124
+ def test_columns
125
+ assert_equal [ "a", "b" ], @result.columns
126
+ end
127
+
128
+ def test_close
129
+ stmt = @db.prepare( "select * from foo" )
130
+ result = stmt.execute
131
+ assert !result.closed?
132
+ result.close
133
+ assert result.closed?
134
+ assert stmt.closed?
135
+ assert_raise( SQLite3::Exception ) { result.reset }
136
+ assert_raise( SQLite3::Exception ) { result.next }
137
+ assert_raise( SQLite3::Exception ) { result.each }
138
+ assert_raise( SQLite3::Exception ) { result.close }
139
+ assert_raise( SQLite3::Exception ) { result.types }
140
+ assert_raise( SQLite3::Exception ) { result.columns }
141
+ end
142
+ end