extralite 2.5 → 2.7
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +34 -13
- data/Gemfile +4 -0
- data/Gemfile-bundle +1 -1
- data/LICENSE +1 -1
- data/README.md +1059 -247
- data/Rakefile +18 -0
- data/TODO.md +0 -7
- data/examples/kv_store.rb +49 -0
- data/examples/multi_fiber.rb +16 -0
- data/examples/on_progress.rb +9 -0
- data/examples/pubsub_store_polyphony.rb +194 -0
- data/examples/pubsub_store_threads.rb +204 -0
- data/ext/extralite/changeset.c +463 -0
- data/ext/extralite/common.c +177 -91
- data/ext/extralite/database.c +745 -276
- data/ext/extralite/extconf-bundle.rb +10 -4
- data/ext/extralite/extconf.rb +34 -34
- data/ext/extralite/extralite.h +104 -47
- data/ext/extralite/extralite_ext.c +6 -0
- data/ext/extralite/iterator.c +14 -86
- data/ext/extralite/query.c +171 -264
- data/extralite-bundle.gemspec +1 -1
- data/extralite.gemspec +1 -1
- data/gemspec.rb +10 -11
- data/lib/extralite/version.rb +1 -1
- data/lib/extralite.rb +69 -10
- data/lib/sequel/adapters/extralite.rb +1 -1
- data/test/helper.rb +9 -1
- data/test/perf_argv_transform.rb +74 -0
- data/test/perf_ary.rb +14 -12
- data/test/perf_hash.rb +17 -15
- data/test/perf_hash_prepared.rb +58 -0
- data/test/perf_hash_transform.rb +66 -0
- data/test/perf_polyphony.rb +74 -0
- data/test/test_changeset.rb +161 -0
- data/test/test_database.rb +720 -104
- data/test/test_extralite.rb +2 -2
- data/test/test_iterator.rb +28 -13
- data/test/test_query.rb +352 -110
- data/test/test_sequel.rb +4 -4
- metadata +24 -16
- data/Gemfile.lock +0 -37
- data/test/perf_prepared.rb +0 -64
data/test/test_query.rb
CHANGED
@@ -2,8 +2,9 @@
|
|
2
2
|
|
3
3
|
require_relative 'helper'
|
4
4
|
require 'date'
|
5
|
+
require 'json'
|
5
6
|
|
6
|
-
class QueryTest <
|
7
|
+
class QueryTest < Minitest::Test
|
7
8
|
def setup
|
8
9
|
@db = Extralite::Database.new(':memory:')
|
9
10
|
@db.query('create table if not exists t (x,y,z)')
|
@@ -17,10 +18,47 @@ class QueryTest < MiniTest::Test
|
|
17
18
|
|
18
19
|
def test_prepare
|
19
20
|
query = @db.prepare('select 1')
|
20
|
-
assert_equal 1, query.
|
21
|
+
assert_equal({ '1': 1 }, query.next)
|
21
22
|
|
22
23
|
query = @db.prepare('select x from t where y = ?', 5)
|
23
|
-
assert_equal 4, query.
|
24
|
+
assert_equal({ x: 4 }, query.next)
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_mode
|
28
|
+
query = @db.prepare('select 1')
|
29
|
+
assert_equal :hash, query.mode
|
30
|
+
|
31
|
+
query.mode = :argv
|
32
|
+
assert_equal :argv, query.mode
|
33
|
+
|
34
|
+
query.mode = :ary
|
35
|
+
assert_equal :ary, query.mode
|
36
|
+
|
37
|
+
assert_raises(Extralite::Error) { query.mode = :foo }
|
38
|
+
assert_equal :ary, query.mode
|
39
|
+
|
40
|
+
query.mode = :hash
|
41
|
+
assert_equal :hash, query.mode
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_prepare_argv
|
45
|
+
query = @db.prepare_argv('select 1')
|
46
|
+
assert_equal :argv, query.mode
|
47
|
+
|
48
|
+
assert_equal 1, query.next
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_prepare_argv_with_too_many_columns
|
52
|
+
q = @db.prepare_argv('select 1, 2, 3, 4, 5, 6, 7, 8, 9')
|
53
|
+
|
54
|
+
assert_raises(Extralite::Error) { q.next }
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_prepare_ary
|
58
|
+
query = @db.prepare_ary('select 1')
|
59
|
+
assert_equal :ary, query.mode
|
60
|
+
|
61
|
+
assert_equal [1], query.next
|
24
62
|
end
|
25
63
|
|
26
64
|
def test_query_props
|
@@ -33,8 +71,13 @@ class QueryTest < MiniTest::Test
|
|
33
71
|
def test_bind
|
34
72
|
@db.query("insert into t values ('a', 'b', 'c')")
|
35
73
|
|
36
|
-
q = @db.
|
37
|
-
results = q.bind(foo: 'c').
|
74
|
+
q = @db.prepare_ary('select * from t where `z` = :foo')
|
75
|
+
results = q.bind(foo: 'c').to_a
|
76
|
+
|
77
|
+
assert_equal [['a', 'b', 'c']], results
|
78
|
+
|
79
|
+
# try again with the same parameters
|
80
|
+
results = q.to_a
|
38
81
|
|
39
82
|
assert_equal [['a', 'b', 'c']], results
|
40
83
|
end
|
@@ -56,19 +99,6 @@ class QueryTest < MiniTest::Test
|
|
56
99
|
# EOF should repeat
|
57
100
|
v = query.next
|
58
101
|
assert_nil v
|
59
|
-
|
60
|
-
query = @db.prepare('select * from t')
|
61
|
-
v = query.next_hash
|
62
|
-
assert_equal({ x: 1, y: 2, z: 3}, v)
|
63
|
-
|
64
|
-
v = query.next_hash
|
65
|
-
assert_equal({ x: 4, y: 5, z: 6}, v)
|
66
|
-
|
67
|
-
v = query.next_hash
|
68
|
-
assert_equal({ x: 7, y: 8, z: 9}, v)
|
69
|
-
|
70
|
-
v = query.next_hash
|
71
|
-
assert_nil v
|
72
102
|
end
|
73
103
|
|
74
104
|
def test_query_next_with_row_count
|
@@ -129,97 +159,112 @@ class QueryTest < MiniTest::Test
|
|
129
159
|
end
|
130
160
|
|
131
161
|
def test_query_next_ary
|
132
|
-
query = @db.
|
133
|
-
v = query.
|
162
|
+
query = @db.prepare_ary('select * from t')
|
163
|
+
v = query.next
|
134
164
|
assert_equal([1, 2, 3], v)
|
135
165
|
|
136
|
-
v = query.
|
166
|
+
v = query.next
|
137
167
|
assert_equal([4, 5, 6], v)
|
138
168
|
|
139
|
-
v = query.
|
169
|
+
v = query.next
|
140
170
|
assert_equal([7, 8, 9], v)
|
141
171
|
|
142
|
-
v = query.
|
172
|
+
v = query.next
|
143
173
|
assert_nil v
|
144
174
|
|
145
|
-
v = query.
|
175
|
+
v = query.next
|
146
176
|
assert_nil v
|
147
177
|
end
|
148
178
|
|
149
179
|
def test_query_next_ary_with_row_count
|
150
|
-
query = @db.
|
151
|
-
v = query.
|
180
|
+
query = @db.prepare_ary('select * from t')
|
181
|
+
v = query.next(1)
|
152
182
|
assert_equal([[1, 2, 3]], v)
|
153
183
|
|
154
|
-
v = query.
|
184
|
+
v = query.next(2)
|
155
185
|
assert_equal([[4, 5, 6], [7, 8, 9]], v)
|
156
186
|
|
157
|
-
v = query.
|
187
|
+
v = query.next(2)
|
158
188
|
assert_equal([], v)
|
159
189
|
|
160
|
-
v = query.
|
190
|
+
v = query.next(2)
|
161
191
|
assert_nil v
|
162
192
|
end
|
163
193
|
|
164
194
|
def test_query_next_ary_with_block
|
165
|
-
query = @db.
|
195
|
+
query = @db.prepare_ary('select * from t')
|
166
196
|
buf = []
|
167
|
-
v = query.
|
197
|
+
v = query.next { |r| buf << r }
|
168
198
|
assert_equal query, v
|
169
199
|
assert_equal [[1, 2, 3]], buf
|
170
200
|
|
171
201
|
buf = []
|
172
|
-
v = query.
|
202
|
+
v = query.next(2) { |r| buf << r }
|
173
203
|
assert_equal query, v
|
174
204
|
assert_equal [[4, 5, 6], [7, 8, 9]], buf
|
175
205
|
|
176
206
|
buf = []
|
177
|
-
v = query.
|
207
|
+
v = query.next(2) { |r| buf << r }
|
178
208
|
assert_equal query, v
|
179
209
|
assert_equal [], buf
|
180
210
|
end
|
181
211
|
|
182
|
-
def
|
183
|
-
query = @db.
|
184
|
-
v = query.
|
212
|
+
def test_query_next_argv_single_column
|
213
|
+
query = @db.prepare_argv('select x from t')
|
214
|
+
v = query.next
|
185
215
|
assert_equal(1, v)
|
186
216
|
|
187
|
-
v = query.
|
217
|
+
v = query.next
|
188
218
|
assert_equal(4, v)
|
189
219
|
|
190
|
-
v = query.
|
220
|
+
v = query.next
|
191
221
|
assert_equal(7, v)
|
192
222
|
|
193
|
-
v = query.
|
223
|
+
v = query.next
|
224
|
+
assert_nil v
|
225
|
+
end
|
226
|
+
|
227
|
+
def test_query_next_argv_multi_column
|
228
|
+
query = @db.prepare_argv('select x, y from t')
|
229
|
+
v = query.next
|
230
|
+
assert_equal([1, 2], v)
|
231
|
+
|
232
|
+
v = query.next
|
233
|
+
assert_equal([4, 5], v)
|
234
|
+
|
235
|
+
v = query.next
|
236
|
+
assert_equal([7, 8], v)
|
237
|
+
|
238
|
+
v = query.next
|
194
239
|
assert_nil v
|
195
240
|
end
|
196
241
|
|
197
|
-
def
|
198
|
-
query = @db.
|
199
|
-
v = query.
|
242
|
+
def test_query_next_argv_with_row_count
|
243
|
+
query = @db.prepare_argv('select x from t')
|
244
|
+
v = query.next(1)
|
200
245
|
assert_equal([1], v)
|
201
246
|
|
202
|
-
v = query.
|
247
|
+
v = query.next(3)
|
203
248
|
assert_equal([4, 7], v)
|
204
249
|
|
205
|
-
v = query.
|
250
|
+
v = query.next(2)
|
206
251
|
assert_nil v
|
207
252
|
end
|
208
253
|
|
209
|
-
def
|
210
|
-
query = @db.
|
254
|
+
def test_query_next_argv_with_block
|
255
|
+
query = @db.prepare_argv('select x, y from t')
|
211
256
|
buf = []
|
212
|
-
v = query.
|
257
|
+
v = query.next { |x, y| buf << [x, y] }
|
213
258
|
assert_equal query, v
|
214
|
-
assert_equal [1], buf
|
259
|
+
assert_equal [[1, 2]], buf
|
215
260
|
|
216
261
|
buf = []
|
217
|
-
v = query.
|
262
|
+
v = query.next(2) { |x, y| buf << [x, y] }
|
218
263
|
assert_equal query, v
|
219
|
-
assert_equal [4, 7], buf
|
264
|
+
assert_equal [[4, 5], [7, 8]], buf
|
220
265
|
|
221
266
|
buf = []
|
222
|
-
v = query.
|
267
|
+
v = query.next(2) { |x, y| buf << [x, y] }
|
223
268
|
assert_equal query, v
|
224
269
|
assert_equal [], buf
|
225
270
|
end
|
@@ -228,14 +273,13 @@ class QueryTest < MiniTest::Test
|
|
228
273
|
assert_equal [{ x: 1, y: 2, z: 3 }], @query.bind(1).to_a
|
229
274
|
assert_equal [{ x: 4, y: 5, z: 6 }], @query.bind(4).to_a
|
230
275
|
|
231
|
-
|
232
|
-
assert_equal [{ x: 4, y: 5, z: 6 }], @query.bind(4).to_a_hash
|
276
|
+
@query.mode = :ary
|
233
277
|
|
234
|
-
assert_equal [[1, 2, 3]], @query.bind(1).
|
235
|
-
assert_equal [[4, 5, 6]], @query.bind(4).
|
278
|
+
assert_equal [[1, 2, 3]], @query.bind(1).to_a
|
279
|
+
assert_equal [[4, 5, 6]], @query.bind(4).to_a
|
236
280
|
|
237
|
-
query = @db.
|
238
|
-
assert_equal [2, 5, 8], query.
|
281
|
+
query = @db.prepare_argv('select y from t')
|
282
|
+
assert_equal [2, 5, 8], query.to_a
|
239
283
|
end
|
240
284
|
|
241
285
|
def test_query_each
|
@@ -280,23 +324,24 @@ class QueryTest < MiniTest::Test
|
|
280
324
|
|
281
325
|
def test_query_each_ary
|
282
326
|
buf = []
|
283
|
-
@query.
|
327
|
+
@query.mode = :ary
|
328
|
+
@query.bind(1).each { |r| buf << r }
|
284
329
|
assert_equal [[1, 2, 3]], buf
|
285
330
|
|
286
331
|
# each should reset the stmt
|
287
332
|
buf = []
|
288
|
-
@query.
|
333
|
+
@query.each { |r| buf << r }
|
289
334
|
assert_equal [[1, 2, 3]], buf
|
290
335
|
|
291
|
-
query = @db.
|
336
|
+
query = @db.prepare_ary('select * from t')
|
292
337
|
buf = []
|
293
|
-
query.
|
338
|
+
query.each { |r| buf << r }
|
294
339
|
assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9]], buf
|
295
340
|
end
|
296
341
|
|
297
342
|
def test_query_each_ary_without_block
|
298
|
-
query = @db.
|
299
|
-
iter = query.
|
343
|
+
query = @db.prepare_ary('select * from t')
|
344
|
+
iter = query.each
|
300
345
|
assert_kind_of Extralite::Iterator, iter
|
301
346
|
|
302
347
|
buf = []
|
@@ -305,26 +350,54 @@ class QueryTest < MiniTest::Test
|
|
305
350
|
assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9]], buf
|
306
351
|
end
|
307
352
|
|
308
|
-
def
|
309
|
-
|
353
|
+
def test_query_each_argv
|
354
|
+
buf = []
|
355
|
+
@query.mode = :argv
|
356
|
+
@query.bind(1).each { |a, b, c| buf << [a, b, c] }
|
357
|
+
assert_equal [[1, 2, 3]], buf
|
358
|
+
|
359
|
+
# each should reset the stmt
|
310
360
|
buf = []
|
311
|
-
query.
|
361
|
+
@query.each { |a, b, c| buf << [a, b, c] }
|
362
|
+
assert_equal [[1, 2, 3]], buf
|
363
|
+
|
364
|
+
query = @db.prepare_argv('select * from t')
|
365
|
+
buf = []
|
366
|
+
query.each { |a, b, c| buf << [a, b, c] }
|
367
|
+
assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9]], buf
|
368
|
+
end
|
369
|
+
|
370
|
+
def test_query_each_argv_without_block
|
371
|
+
query = @db.prepare_argv('select * from t')
|
372
|
+
iter = query.each
|
373
|
+
assert_kind_of Extralite::Iterator, iter
|
374
|
+
|
375
|
+
buf = []
|
376
|
+
v = iter.each { |a, b, c| buf << [a, b, c] }
|
377
|
+
assert_equal iter, v
|
378
|
+
assert_equal [[1, 2, 3], [4, 5, 6], [7, 8, 9]], buf
|
379
|
+
end
|
380
|
+
|
381
|
+
def test_query_each_argv_single_column
|
382
|
+
query = @db.prepare_argv('select x from t where x = ?')
|
383
|
+
buf = []
|
384
|
+
query.bind(1).each { |r| buf << r }
|
312
385
|
assert_equal [1], buf
|
313
386
|
|
314
387
|
# each should reset the stmt
|
315
388
|
buf = []
|
316
|
-
query.
|
389
|
+
query.each { |r| buf << r }
|
317
390
|
assert_equal [1], buf
|
318
391
|
|
319
|
-
query = @db.
|
392
|
+
query = @db.prepare_argv('select x from t')
|
320
393
|
buf = []
|
321
|
-
query.
|
394
|
+
query.each { |r| buf << r }
|
322
395
|
assert_equal [1, 4, 7], buf
|
323
396
|
end
|
324
397
|
|
325
|
-
def
|
326
|
-
query = @db.
|
327
|
-
iter = query.
|
398
|
+
def test_query_each_argv_single_column_without_block
|
399
|
+
query = @db.prepare_argv('select x from t')
|
400
|
+
iter = query.each
|
328
401
|
assert_kind_of Extralite::Iterator, iter
|
329
402
|
|
330
403
|
buf = []
|
@@ -411,33 +484,33 @@ class QueryTest < MiniTest::Test
|
|
411
484
|
class Foo; end
|
412
485
|
|
413
486
|
def test_parameter_binding_from_hash
|
414
|
-
assert_equal 42, @db.
|
415
|
-
assert_equal 42, @db.
|
416
|
-
assert_equal 42, @db.
|
417
|
-
assert_nil @db.
|
487
|
+
assert_equal 42, @db.prepare_argv('select :bar').bind(foo: 41, bar: 42).next
|
488
|
+
assert_equal 42, @db.prepare_argv('select :bar').bind('foo' => 41, 'bar' => 42).next
|
489
|
+
assert_equal 42, @db.prepare_argv('select ?8').bind(7 => 41, 8 => 42).next
|
490
|
+
assert_nil @db.prepare_argv('select :bar').bind(foo: 41).next
|
418
491
|
|
419
|
-
error = assert_raises(Extralite::ParameterError) { @db.
|
492
|
+
error = assert_raises(Extralite::ParameterError) { @db.prepare_argv('select ?').bind(Foo.new => 42).next }
|
420
493
|
assert_equal error.message, 'Cannot bind parameter with a key of type QueryTest::Foo'
|
421
494
|
|
422
|
-
error = assert_raises(Extralite::ParameterError) { @db.
|
495
|
+
error = assert_raises(Extralite::ParameterError) { @db.prepare_argv('select ?').bind(%w[a b] => 42).next }
|
423
496
|
assert_equal error.message, 'Cannot bind parameter with a key of type Array'
|
424
497
|
end
|
425
498
|
|
426
499
|
def test_parameter_binding_from_struct
|
427
|
-
foo_bar = Struct.new(:
|
500
|
+
foo_bar = Struct.new(:':foo', :bar)
|
428
501
|
value = foo_bar.new(41, 42)
|
429
|
-
assert_equal 41, @db.
|
430
|
-
assert_equal 42, @db.
|
431
|
-
assert_nil @db.
|
502
|
+
assert_equal 41, @db.prepare_argv('select :foo').bind(value).next
|
503
|
+
assert_equal 42, @db.prepare_argv('select :bar').bind(value).next
|
504
|
+
assert_nil @db.prepare_argv('select :baz').bind(value).next
|
432
505
|
end
|
433
506
|
|
434
507
|
def test_parameter_binding_from_data_class
|
435
508
|
skip "Data isn't supported in Ruby < 3.2" if RUBY_VERSION < '3.2'
|
436
509
|
|
437
|
-
foo_bar = Data.define(:
|
438
|
-
value = foo_bar.new(
|
439
|
-
assert_equal 42, @db.
|
440
|
-
assert_nil @db.
|
510
|
+
foo_bar = Data.define(:':foo', :bar)
|
511
|
+
value = foo_bar.new(':foo': 41, bar: 42)
|
512
|
+
assert_equal 42, @db.prepare_argv('select :bar').bind(value).next
|
513
|
+
assert_nil @db.prepare_argv('select :baz').bind(value).next
|
441
514
|
end
|
442
515
|
|
443
516
|
def test_query_columns
|
@@ -446,10 +519,10 @@ class QueryTest < MiniTest::Test
|
|
446
519
|
end
|
447
520
|
|
448
521
|
def test_query_columns_with_parameterized_sql
|
449
|
-
q = @db.
|
522
|
+
q = @db.prepare_ary('select * from t where z = :z')
|
450
523
|
q.bind(z: 9)
|
451
524
|
assert_equal [:x, :y, :z], q.columns
|
452
|
-
assert_equal [[7, 8, 9]], q.
|
525
|
+
assert_equal [[7, 8, 9]], q.to_a
|
453
526
|
end
|
454
527
|
|
455
528
|
def test_query_close
|
@@ -659,16 +732,16 @@ class QueryTest < MiniTest::Test
|
|
659
732
|
[[3, 3]]
|
660
733
|
], results
|
661
734
|
|
662
|
-
q = @db.
|
735
|
+
q = @db.prepare_ary('update foo set b = ? returning *')
|
663
736
|
|
664
|
-
results = q.
|
737
|
+
results = q.batch_query([42, 43])
|
665
738
|
assert_equal [
|
666
739
|
[[1, 42], [2, 42], [3, 42]],
|
667
740
|
[[1, 43], [2, 43], [3, 43]]
|
668
741
|
], results
|
669
742
|
|
670
743
|
array = []
|
671
|
-
changes = q.
|
744
|
+
changes = q.batch_query([44, 45]) do |rows|
|
672
745
|
array << rows
|
673
746
|
end
|
674
747
|
assert_equal 6, changes
|
@@ -690,16 +763,16 @@ class QueryTest < MiniTest::Test
|
|
690
763
|
[[3, 3]]
|
691
764
|
], results
|
692
765
|
|
693
|
-
q = @db.
|
766
|
+
q = @db.prepare_ary('update foo set b = ? returning *')
|
694
767
|
|
695
|
-
results = q.
|
768
|
+
results = q.batch_query(42..43)
|
696
769
|
assert_equal [
|
697
770
|
[[1, 42], [2, 42], [3, 42]],
|
698
771
|
[[1, 43], [2, 43], [3, 43]]
|
699
772
|
], results
|
700
773
|
|
701
774
|
array = []
|
702
|
-
changes = q.
|
775
|
+
changes = q.batch_query(44..45) do |rows|
|
703
776
|
array << rows
|
704
777
|
end
|
705
778
|
assert_equal 6, changes
|
@@ -721,10 +794,10 @@ class QueryTest < MiniTest::Test
|
|
721
794
|
[[3, 3]]
|
722
795
|
], results
|
723
796
|
|
724
|
-
q = @db.
|
797
|
+
q = @db.prepare_ary('update foo set b = ? returning *')
|
725
798
|
|
726
799
|
pr = parameter_source_proc([42, 43])
|
727
|
-
results = q.
|
800
|
+
results = q.batch_query(pr)
|
728
801
|
assert_equal [
|
729
802
|
[[1, 42], [2, 42], [3, 42]],
|
730
803
|
[[1, 43], [2, 43], [3, 43]]
|
@@ -732,7 +805,7 @@ class QueryTest < MiniTest::Test
|
|
732
805
|
|
733
806
|
array = []
|
734
807
|
pr = parameter_source_proc([44, 45])
|
735
|
-
changes = q.
|
808
|
+
changes = q.batch_query(pr) do |rows|
|
736
809
|
array << rows
|
737
810
|
end
|
738
811
|
assert_equal 6, changes
|
@@ -754,16 +827,16 @@ class QueryTest < MiniTest::Test
|
|
754
827
|
[[3, 3]]
|
755
828
|
], results
|
756
829
|
|
757
|
-
q = @db.
|
830
|
+
q = @db.prepare_argv('update foo set b = ? returning b * 10 + a')
|
758
831
|
|
759
|
-
results = q.
|
832
|
+
results = q.batch_query([42, 43])
|
760
833
|
assert_equal [
|
761
834
|
[421, 422, 423],
|
762
835
|
[431, 432, 433]
|
763
836
|
], results
|
764
837
|
|
765
838
|
array = []
|
766
|
-
changes = q.
|
839
|
+
changes = q.batch_query([44, 45]) do |rows|
|
767
840
|
array << rows
|
768
841
|
end
|
769
842
|
assert_equal 6, changes
|
@@ -785,16 +858,16 @@ class QueryTest < MiniTest::Test
|
|
785
858
|
[[3, 3]]
|
786
859
|
], results
|
787
860
|
|
788
|
-
q = @db.
|
861
|
+
q = @db.prepare_argv('update foo set b = ? returning b * 10 + a')
|
789
862
|
|
790
|
-
results = q.
|
863
|
+
results = q.batch_query(42..43)
|
791
864
|
assert_equal [
|
792
865
|
[421, 422, 423],
|
793
866
|
[431, 432, 433]
|
794
867
|
], results
|
795
868
|
|
796
869
|
array = []
|
797
|
-
changes = q.
|
870
|
+
changes = q.batch_query(44..45) do |rows|
|
798
871
|
array << rows
|
799
872
|
end
|
800
873
|
assert_equal 6, changes
|
@@ -816,10 +889,10 @@ class QueryTest < MiniTest::Test
|
|
816
889
|
[[3, 3]]
|
817
890
|
], results
|
818
891
|
|
819
|
-
q = @db.
|
892
|
+
q = @db.prepare_argv('update foo set b = ? returning b * 10 + a')
|
820
893
|
|
821
894
|
pr = parameter_source_proc([42, 43])
|
822
|
-
results = q.
|
895
|
+
results = q.batch_query(pr)
|
823
896
|
assert_equal [
|
824
897
|
[421, 422, 423],
|
825
898
|
[431, 432, 433]
|
@@ -827,7 +900,7 @@ class QueryTest < MiniTest::Test
|
|
827
900
|
|
828
901
|
array = []
|
829
902
|
pr = parameter_source_proc([44, 45])
|
830
|
-
changes = q.
|
903
|
+
changes = q.batch_query(pr) do |rows|
|
831
904
|
array << rows
|
832
905
|
end
|
833
906
|
assert_equal 6, changes
|
@@ -863,7 +936,7 @@ class QueryTest < MiniTest::Test
|
|
863
936
|
end
|
864
937
|
|
865
938
|
def test_query_eof
|
866
|
-
query = @db.
|
939
|
+
query = @db.prepare_argv('select x from t')
|
867
940
|
assert_equal false, query.eof?
|
868
941
|
|
869
942
|
query.next
|
@@ -884,13 +957,13 @@ class QueryTest < MiniTest::Test
|
|
884
957
|
query.next
|
885
958
|
assert_equal false, query.eof?
|
886
959
|
|
887
|
-
assert_equal [1, 4, 7], query.
|
960
|
+
assert_equal [1, 4, 7], query.to_a
|
888
961
|
assert_equal true, query.eof?
|
889
962
|
end
|
890
963
|
|
891
964
|
def test_query_inspect
|
892
965
|
q = @db.prepare('select x from t')
|
893
|
-
assert_match
|
966
|
+
assert_match(/^\#\<Extralite::Query:0x[0-9a-f]+ #{q.sql.inspect}\>$/, q.inspect)
|
894
967
|
end
|
895
968
|
|
896
969
|
def test_query_clone
|
@@ -910,6 +983,175 @@ class QueryTest < MiniTest::Test
|
|
910
983
|
assert_kind_of Extralite::Query, q2
|
911
984
|
assert_equal @db, q2.database
|
912
985
|
assert_equal q1.sql, q2.sql
|
913
|
-
|
986
|
+
refute_same q1, q2
|
987
|
+
|
988
|
+
q1 = @db.prepare_argv('select x from t')
|
989
|
+
q2 = q1.dup
|
990
|
+
|
991
|
+
assert_kind_of Extralite::Query, q2
|
992
|
+
assert_equal @db, q2.database
|
993
|
+
assert_equal q1.sql, q2.sql
|
994
|
+
refute_same q1, q2
|
995
|
+
assert_equal :argv, q2.mode
|
996
|
+
end
|
997
|
+
|
998
|
+
def test_query_dup_with_transform
|
999
|
+
q1 = @db.prepare_ary('select x, y from t') { |a| a * 2 }
|
1000
|
+
q2 = q1.dup
|
1001
|
+
|
1002
|
+
assert_equal [
|
1003
|
+
[1, 2, 1, 2],
|
1004
|
+
[4, 5, 4, 5],
|
1005
|
+
[7, 8, 7, 8],
|
1006
|
+
], q2.to_a
|
1007
|
+
end
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
class QueryTransformTest < Minitest::Test
|
1011
|
+
def setup
|
1012
|
+
@db = Extralite::Database.new(':memory:')
|
1013
|
+
@db.query('create table t (a, b, c)')
|
1014
|
+
|
1015
|
+
@q1 = @db.prepare_argv('select c from t where a = ?')
|
1016
|
+
@q2 = @db.prepare_argv('select c from t order by a')
|
1017
|
+
|
1018
|
+
@q3 = @db.prepare('select * from t where a = ?')
|
1019
|
+
@q4 = @db.prepare('select * from t order by a')
|
1020
|
+
|
1021
|
+
@q5 = @db.prepare('select a, b from t where a = ?')
|
1022
|
+
@q6 = @db.prepare('select a, b from t order by a')
|
1023
|
+
|
1024
|
+
@db.batch_execute('insert into t (a, b, c) values (?, ?, ?)', [
|
1025
|
+
[1, 2, { foo: 42, bar: 43 }.to_json],
|
1026
|
+
[4, 5, { foo: 45, bar: 46 }.to_json]
|
1027
|
+
])
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
class MyModel
|
1031
|
+
def initialize(h)
|
1032
|
+
@h = h
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
def values
|
1036
|
+
@h
|
1037
|
+
end
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
def test_transform_hash
|
1041
|
+
q = @q5.transform { |h| MyModel.new(h) }
|
1042
|
+
assert_equal @q5, q
|
1043
|
+
|
1044
|
+
o = @q5.bind(1).next
|
1045
|
+
assert_kind_of MyModel, o
|
1046
|
+
assert_equal({ a: 1, b: 2 }, o.values)
|
1047
|
+
|
1048
|
+
o = @q5.bind(4).next
|
1049
|
+
assert_kind_of MyModel, o
|
1050
|
+
assert_equal({ a: 4, b: 5 }, o.values)
|
1051
|
+
|
1052
|
+
assert_equal [
|
1053
|
+
[{ a: 1, b: 2 }],
|
1054
|
+
[{ a: 4, b: 5 }]
|
1055
|
+
], @q5.batch_query([[1], [4]]).map { |a| a.map(&:values) }
|
1056
|
+
|
1057
|
+
@q6.transform { |h| MyModel.new(h) }
|
1058
|
+
assert_equal [
|
1059
|
+
{ a: 1, b: 2 },
|
1060
|
+
{ a: 4, b: 5 }
|
1061
|
+
], @q6.to_a.map(&:values)
|
1062
|
+
|
1063
|
+
buf = []
|
1064
|
+
@q6.each { |r| buf << r.values }
|
1065
|
+
assert_equal [
|
1066
|
+
{ a: 1, b: 2 },
|
1067
|
+
{ a: 4, b: 5 }
|
1068
|
+
], buf
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
def test_transform_ary
|
1072
|
+
@q5.mode = :ary
|
1073
|
+
q = @q5.transform { |h| MyModel.new(h) }
|
1074
|
+
assert_equal @q5, q
|
1075
|
+
|
1076
|
+
o = @q5.bind(1).next
|
1077
|
+
assert_kind_of MyModel, o
|
1078
|
+
assert_equal([1, 2], o.values)
|
1079
|
+
|
1080
|
+
o = @q5.bind(4).next
|
1081
|
+
assert_kind_of MyModel, o
|
1082
|
+
assert_equal([4, 5], o.values)
|
1083
|
+
|
1084
|
+
assert_equal [
|
1085
|
+
[[1, 2]],
|
1086
|
+
[[4, 5]]
|
1087
|
+
], @q5.batch_query([[1], [4]]).map { |a| a.map(&:values) }
|
1088
|
+
|
1089
|
+
@q6.mode = :ary
|
1090
|
+
@q6.transform { |h| MyModel.new(h) }
|
1091
|
+
assert_equal [
|
1092
|
+
[1, 2],
|
1093
|
+
[4, 5]
|
1094
|
+
], @q6.to_a.map(&:values)
|
1095
|
+
|
1096
|
+
buf = []
|
1097
|
+
@q6.each { |r| buf << r.values }
|
1098
|
+
assert_equal [
|
1099
|
+
[1, 2],
|
1100
|
+
[4, 5]
|
1101
|
+
], buf
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
def test_transform_argv_single_column
|
1105
|
+
q = @q1.transform { |c| JSON.parse(c, symbolize_names: true) }
|
1106
|
+
assert_equal @q1, q
|
1107
|
+
|
1108
|
+
assert_equal({ foo: 42, bar: 43 }, @q1.bind(1).next)
|
1109
|
+
assert_equal({ foo: 45, bar: 46 }, @q1.bind(4).next)
|
1110
|
+
|
1111
|
+
assert_equal [
|
1112
|
+
[{ foo: 42, bar: 43 }],
|
1113
|
+
[{ foo: 45, bar: 46 }]
|
1114
|
+
], @q1.batch_query([[1], [4]])
|
1115
|
+
|
1116
|
+
@q2.transform { |c| JSON.parse(c, symbolize_names: true) }
|
1117
|
+
assert_equal [
|
1118
|
+
{ foo: 42, bar: 43 },
|
1119
|
+
{ foo: 45, bar: 46 }
|
1120
|
+
], @q2.to_a
|
1121
|
+
|
1122
|
+
buf = []
|
1123
|
+
@q2.each { |r| buf << r }
|
1124
|
+
assert_equal [
|
1125
|
+
{ foo: 42, bar: 43 },
|
1126
|
+
{ foo: 45, bar: 46 }
|
1127
|
+
], buf
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
def test_transform_argv_multi_column
|
1131
|
+
@q3.mode = :argv
|
1132
|
+
q = @q3.transform { |a, b, c| { a: a, b: b, c: JSON.parse(c, symbolize_names: true) } }
|
1133
|
+
assert_equal @q3, q
|
1134
|
+
|
1135
|
+
assert_equal({ a: 1, b: 2, c: { foo: 42, bar: 43 }}, @q3.bind(1).next)
|
1136
|
+
assert_equal({ a: 4, b: 5, c: { foo: 45, bar: 46 }}, @q3.bind(4).next)
|
1137
|
+
|
1138
|
+
assert_equal [
|
1139
|
+
[{ a: 1, b: 2, c: { foo: 42, bar: 43 }}],
|
1140
|
+
[{ a: 4, b: 5, c: { foo: 45, bar: 46 }}]
|
1141
|
+
], @q3.batch_query([[1], [4]])
|
1142
|
+
|
1143
|
+
@q4.mode = :argv
|
1144
|
+
@q4.transform { |a, b, c| { a: a, b: b, c: JSON.parse(c, symbolize_names: true) } }
|
1145
|
+
assert_equal [
|
1146
|
+
{ a: 1, b: 2, c: { foo: 42, bar: 43 }},
|
1147
|
+
{ a: 4, b: 5, c: { foo: 45, bar: 46 }}
|
1148
|
+
], @q4.to_a
|
1149
|
+
|
1150
|
+
buf = []
|
1151
|
+
@q4.each { |r| buf << r }
|
1152
|
+
assert_equal [
|
1153
|
+
{ a: 1, b: 2, c: { foo: 42, bar: 43 }},
|
1154
|
+
{ a: 4, b: 5, c: { foo: 45, bar: 46 }}
|
1155
|
+
], buf
|
914
1156
|
end
|
915
1157
|
end
|