extralite 2.6 → 2.7.1
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/.yardopts +1 -1
- data/CHANGELOG.md +32 -17
- data/Gemfile +4 -0
- data/Gemfile-bundle +1 -1
- data/README.md +262 -75
- data/Rakefile +18 -0
- data/TODO.md +0 -9
- 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 +3 -3
- data/ext/extralite/common.c +173 -87
- data/ext/extralite/database.c +650 -315
- data/ext/extralite/extconf.rb +7 -11
- data/ext/extralite/extralite.h +89 -48
- data/ext/extralite/iterator.c +6 -84
- data/ext/extralite/query.c +165 -256
- 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 +27 -17
- data/lib/sequel/adapters/extralite.rb +1 -1
- data/test/helper.rb +2 -1
- data/test/perf_argv_transform.rb +74 -0
- data/test/perf_hash_transform.rb +66 -0
- data/test/perf_polyphony.rb +74 -0
- data/test/test_changeset.rb +2 -2
- data/test/test_database.rb +531 -115
- data/test/test_extralite.rb +2 -2
- data/test/test_iterator.rb +28 -13
- data/test/test_query.rb +348 -111
- data/test/test_sequel.rb +4 -4
- metadata +20 -14
- data/Gemfile.lock +0 -37
data/ext/extralite/common.c
CHANGED
@@ -162,6 +162,12 @@ static inline VALUE row_to_ary(sqlite3_stmt *stmt, int column_count) {
|
|
162
162
|
return row;
|
163
163
|
}
|
164
164
|
|
165
|
+
static inline void row_to_argv_values(sqlite3_stmt *stmt, int column_count, VALUE *values) {
|
166
|
+
for (int i = 0; i < column_count; i++) {
|
167
|
+
values[i] = get_column_value(stmt, i, sqlite3_column_type(stmt, i));
|
168
|
+
}
|
169
|
+
}
|
170
|
+
|
165
171
|
typedef struct {
|
166
172
|
sqlite3 *db;
|
167
173
|
sqlite3_stmt **stmt;
|
@@ -315,65 +321,130 @@ VALUE cleanup_stmt(query_ctx *ctx) {
|
|
315
321
|
return Qnil;
|
316
322
|
}
|
317
323
|
|
324
|
+
VALUE safe_query_argv(query_ctx *ctx);
|
325
|
+
|
318
326
|
VALUE safe_query_hash(query_ctx *ctx) {
|
319
|
-
VALUE array =
|
327
|
+
VALUE array = ROW_MULTI_P(ctx->row_mode) ? rb_ary_new() : Qnil;
|
320
328
|
VALUE row = Qnil;
|
321
329
|
int column_count = sqlite3_column_count(ctx->stmt);
|
322
330
|
VALUE column_names = get_column_names(ctx->stmt, column_count);
|
323
331
|
int row_count = 0;
|
332
|
+
int do_transform = !NIL_P(ctx->transform_proc);
|
324
333
|
|
325
334
|
while (stmt_iterate(ctx)) {
|
326
335
|
row = row_to_hash(ctx->stmt, column_count, column_names);
|
336
|
+
if (do_transform)
|
337
|
+
row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
|
327
338
|
row_count++;
|
328
|
-
switch (ctx->
|
329
|
-
case
|
339
|
+
switch (ctx->row_mode) {
|
340
|
+
case ROW_YIELD:
|
330
341
|
rb_yield(row);
|
331
342
|
break;
|
332
|
-
case
|
343
|
+
case ROW_MULTI:
|
333
344
|
rb_ary_push(array, row);
|
334
345
|
break;
|
335
|
-
case
|
346
|
+
case ROW_SINGLE:
|
336
347
|
return row;
|
337
348
|
}
|
338
349
|
if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
|
339
|
-
return
|
350
|
+
return ROW_MULTI_P(ctx->row_mode) ? array : ctx->self;
|
340
351
|
}
|
341
352
|
|
342
353
|
RB_GC_GUARD(column_names);
|
343
354
|
RB_GC_GUARD(row);
|
344
355
|
RB_GC_GUARD(array);
|
345
|
-
return
|
356
|
+
return ROW_MULTI_P(ctx->row_mode) ? array : Qnil;
|
357
|
+
}
|
358
|
+
|
359
|
+
#define MAX_ARGV_COLUMNS 8
|
360
|
+
#define NIL_ARGV_VALUES {Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil, Qnil}
|
361
|
+
#define ARGV_GC_GUARD(values) \
|
362
|
+
RB_GC_GUARD(values[0]); \
|
363
|
+
RB_GC_GUARD(values[1]); \
|
364
|
+
RB_GC_GUARD(values[2]); \
|
365
|
+
RB_GC_GUARD(values[3]); \
|
366
|
+
RB_GC_GUARD(values[4]); \
|
367
|
+
RB_GC_GUARD(values[5]); \
|
368
|
+
RB_GC_GUARD(values[6]); \
|
369
|
+
RB_GC_GUARD(values[7])
|
370
|
+
|
371
|
+
#define ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, return_rows) \
|
372
|
+
row_to_argv_values(ctx->stmt, column_count, argv_values); \
|
373
|
+
if (do_transform) \
|
374
|
+
row = rb_funcall2(ctx->transform_proc, ID_call, column_count, argv_values); \
|
375
|
+
else if (return_rows) \
|
376
|
+
row = column_count == 1 ? argv_values[0] : rb_ary_new_from_values(column_count, argv_values);
|
377
|
+
|
378
|
+
VALUE safe_query_argv(query_ctx *ctx) {
|
379
|
+
VALUE array = ROW_MULTI_P(ctx->row_mode) ? rb_ary_new() : Qnil;
|
380
|
+
VALUE argv_values[MAX_ARGV_COLUMNS] = NIL_ARGV_VALUES;
|
381
|
+
VALUE row = Qnil;
|
382
|
+
int column_count = sqlite3_column_count(ctx->stmt);
|
383
|
+
if (column_count > MAX_ARGV_COLUMNS)
|
384
|
+
rb_raise(cError, "Conversion is supported only up to %d columns", MAX_ARGV_COLUMNS);
|
385
|
+
|
386
|
+
int do_transform = !NIL_P(ctx->transform_proc);
|
387
|
+
int return_rows = (ctx->row_mode != ROW_YIELD);
|
388
|
+
|
389
|
+
int row_count = 0;
|
390
|
+
while (stmt_iterate(ctx)) {
|
391
|
+
row_count++;
|
392
|
+
ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, return_rows);
|
393
|
+
switch (ctx->row_mode) {
|
394
|
+
case ROW_YIELD:
|
395
|
+
if (do_transform)
|
396
|
+
rb_yield(row);
|
397
|
+
else
|
398
|
+
rb_yield_values2(column_count, argv_values);
|
399
|
+
break;
|
400
|
+
case ROW_MULTI:
|
401
|
+
rb_ary_push(array, row);
|
402
|
+
break;
|
403
|
+
case ROW_SINGLE:
|
404
|
+
return row;
|
405
|
+
}
|
406
|
+
if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
|
407
|
+
return ROW_MULTI_P(ctx->row_mode) ? array : ctx->self;
|
408
|
+
}
|
409
|
+
|
410
|
+
ARGV_GC_GUARD(argv_values);
|
411
|
+
RB_GC_GUARD(row);
|
412
|
+
RB_GC_GUARD(array);
|
413
|
+
return ROW_MULTI_P(ctx->row_mode) ? array : Qnil;
|
346
414
|
}
|
347
415
|
|
348
416
|
VALUE safe_query_ary(query_ctx *ctx) {
|
349
|
-
VALUE array =
|
417
|
+
VALUE array = ROW_MULTI_P(ctx->row_mode) ? rb_ary_new() : Qnil;
|
350
418
|
VALUE row = Qnil;
|
351
419
|
int column_count = sqlite3_column_count(ctx->stmt);
|
352
420
|
int row_count = 0;
|
421
|
+
int do_transform = !NIL_P(ctx->transform_proc);
|
353
422
|
|
354
423
|
while (stmt_iterate(ctx)) {
|
355
424
|
row = row_to_ary(ctx->stmt, column_count);
|
425
|
+
if (do_transform)
|
426
|
+
row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
|
356
427
|
row_count++;
|
357
|
-
switch (ctx->
|
358
|
-
case
|
428
|
+
switch (ctx->row_mode) {
|
429
|
+
case ROW_YIELD:
|
359
430
|
rb_yield(row);
|
360
431
|
break;
|
361
|
-
case
|
432
|
+
case ROW_MULTI:
|
362
433
|
rb_ary_push(array, row);
|
363
434
|
break;
|
364
|
-
case
|
435
|
+
case ROW_SINGLE:
|
365
436
|
return row;
|
366
437
|
}
|
367
438
|
if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
|
368
|
-
return
|
439
|
+
return ROW_MULTI_P(ctx->row_mode) ? array : ctx->self;
|
369
440
|
}
|
370
441
|
|
371
442
|
RB_GC_GUARD(row);
|
372
443
|
RB_GC_GUARD(array);
|
373
|
-
return
|
444
|
+
return ROW_MULTI_P(ctx->row_mode) ? array : Qnil;
|
374
445
|
}
|
375
446
|
|
376
|
-
VALUE
|
447
|
+
VALUE safe_query_single_row_hash(query_ctx *ctx) {
|
377
448
|
int column_count;
|
378
449
|
VALUE row = Qnil;
|
379
450
|
VALUE column_names;
|
@@ -381,64 +452,54 @@ VALUE safe_query_single_row(query_ctx *ctx) {
|
|
381
452
|
column_count = sqlite3_column_count(ctx->stmt);
|
382
453
|
column_names = get_column_names(ctx->stmt, column_count);
|
383
454
|
|
384
|
-
if (stmt_iterate(ctx))
|
455
|
+
if (stmt_iterate(ctx)) {
|
385
456
|
row = row_to_hash(ctx->stmt, column_count, column_names);
|
457
|
+
if (!NIL_P(ctx->transform_proc))
|
458
|
+
row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
|
459
|
+
}
|
386
460
|
|
387
461
|
RB_GC_GUARD(row);
|
388
462
|
RB_GC_GUARD(column_names);
|
389
463
|
return row;
|
390
464
|
}
|
391
465
|
|
392
|
-
VALUE
|
393
|
-
VALUE
|
394
|
-
VALUE
|
466
|
+
VALUE safe_query_single_row_argv(query_ctx *ctx) {
|
467
|
+
VALUE argv_values[MAX_ARGV_COLUMNS] = NIL_ARGV_VALUES;
|
468
|
+
VALUE row = Qnil;
|
395
469
|
int column_count = sqlite3_column_count(ctx->stmt);
|
396
|
-
|
397
|
-
|
398
|
-
|
470
|
+
if (column_count > MAX_ARGV_COLUMNS)
|
471
|
+
rb_raise(cError, "Conversion is supported only up to %d columns", MAX_ARGV_COLUMNS);
|
472
|
+
int do_transform = !NIL_P(ctx->transform_proc);
|
399
473
|
|
400
|
-
|
401
|
-
|
402
|
-
row_count++;
|
403
|
-
switch (ctx->mode) {
|
404
|
-
case QUERY_YIELD:
|
405
|
-
rb_yield(value);
|
406
|
-
break;
|
407
|
-
case QUERY_MULTI_ROW:
|
408
|
-
rb_ary_push(array, value);
|
409
|
-
break;
|
410
|
-
case QUERY_SINGLE_ROW:
|
411
|
-
return value;
|
412
|
-
}
|
413
|
-
if (ctx->max_rows != ALL_ROWS && row_count >= ctx->max_rows)
|
414
|
-
return MULTI_ROW_P(ctx->mode) ? array : ctx->self;
|
474
|
+
if (stmt_iterate(ctx)) {
|
475
|
+
ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, 1);
|
415
476
|
}
|
416
477
|
|
417
|
-
|
418
|
-
RB_GC_GUARD(
|
419
|
-
return
|
478
|
+
ARGV_GC_GUARD(argv_values);
|
479
|
+
RB_GC_GUARD(row);
|
480
|
+
return row;
|
420
481
|
}
|
421
482
|
|
422
|
-
VALUE
|
423
|
-
int column_count;
|
424
|
-
VALUE
|
425
|
-
|
426
|
-
column_count = sqlite3_column_count(ctx->stmt);
|
427
|
-
if (column_count != 1)
|
428
|
-
rb_raise(cError, "Expected query result to have 1 column");
|
483
|
+
VALUE safe_query_single_row_ary(query_ctx *ctx) {
|
484
|
+
int column_count = sqlite3_column_count(ctx->stmt);
|
485
|
+
VALUE row = Qnil;
|
486
|
+
int do_transform = !NIL_P(ctx->transform_proc);
|
429
487
|
|
430
|
-
if (stmt_iterate(ctx))
|
431
|
-
|
488
|
+
if (stmt_iterate(ctx)) {
|
489
|
+
row = row_to_ary(ctx->stmt, column_count);
|
490
|
+
if (do_transform)
|
491
|
+
row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
|
492
|
+
}
|
432
493
|
|
433
|
-
RB_GC_GUARD(
|
434
|
-
return
|
494
|
+
RB_GC_GUARD(row);
|
495
|
+
return row;
|
435
496
|
}
|
436
497
|
|
437
498
|
enum batch_mode {
|
438
499
|
BATCH_EXECUTE,
|
439
|
-
BATCH_QUERY_ARY,
|
440
500
|
BATCH_QUERY_HASH,
|
441
|
-
|
501
|
+
BATCH_QUERY_ARGV,
|
502
|
+
BATCH_QUERY_ARY,
|
442
503
|
};
|
443
504
|
|
444
505
|
static inline VALUE batch_iterate_hash(query_ctx *ctx) {
|
@@ -446,13 +507,17 @@ static inline VALUE batch_iterate_hash(query_ctx *ctx) {
|
|
446
507
|
VALUE row = Qnil;
|
447
508
|
int column_count = sqlite3_column_count(ctx->stmt);
|
448
509
|
VALUE column_names = get_column_names(ctx->stmt, column_count);
|
510
|
+
const int do_transform = !NIL_P(ctx->transform_proc);
|
449
511
|
|
450
512
|
while (stmt_iterate(ctx)) {
|
451
513
|
row = row_to_hash(ctx->stmt, column_count, column_names);
|
514
|
+
if (do_transform)
|
515
|
+
row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
|
452
516
|
rb_ary_push(rows, row);
|
453
517
|
}
|
454
518
|
|
455
519
|
RB_GC_GUARD(column_names);
|
520
|
+
RB_GC_GUARD(row);
|
456
521
|
RB_GC_GUARD(rows);
|
457
522
|
return rows;
|
458
523
|
}
|
@@ -461,27 +526,36 @@ static inline VALUE batch_iterate_ary(query_ctx *ctx) {
|
|
461
526
|
VALUE rows = rb_ary_new();
|
462
527
|
VALUE row = Qnil;
|
463
528
|
int column_count = sqlite3_column_count(ctx->stmt);
|
529
|
+
int do_transform = !NIL_P(ctx->transform_proc);
|
464
530
|
|
465
531
|
while (stmt_iterate(ctx)) {
|
466
532
|
row = row_to_ary(ctx->stmt, column_count);
|
533
|
+
if (do_transform)
|
534
|
+
row = rb_funcall(ctx->transform_proc, ID_call, 1, row);
|
467
535
|
rb_ary_push(rows, row);
|
468
536
|
}
|
469
537
|
|
538
|
+
RB_GC_GUARD(row);
|
470
539
|
RB_GC_GUARD(rows);
|
471
540
|
return rows;
|
472
541
|
}
|
473
542
|
|
474
|
-
static inline VALUE
|
543
|
+
static inline VALUE batch_iterate_argv(query_ctx *ctx) {
|
475
544
|
VALUE rows = rb_ary_new();
|
476
|
-
VALUE
|
545
|
+
VALUE argv_values[MAX_ARGV_COLUMNS] = NIL_ARGV_VALUES;
|
546
|
+
VALUE row = Qnil;
|
477
547
|
int column_count = sqlite3_column_count(ctx->stmt);
|
478
|
-
if (column_count
|
548
|
+
if (column_count > MAX_ARGV_COLUMNS)
|
549
|
+
rb_raise(cError, "Conversion is supported only up to %d columns", MAX_ARGV_COLUMNS);
|
550
|
+
int do_transform = !NIL_P(ctx->transform_proc);
|
479
551
|
|
480
552
|
while (stmt_iterate(ctx)) {
|
481
|
-
|
482
|
-
rb_ary_push(rows,
|
553
|
+
ARGV_GET_ROW(ctx, column_count, argv_values, row, do_transform, 1);
|
554
|
+
rb_ary_push(rows, row);
|
483
555
|
}
|
484
556
|
|
557
|
+
ARGV_GC_GUARD(argv_values);
|
558
|
+
RB_GC_GUARD(row);
|
485
559
|
RB_GC_GUARD(rows);
|
486
560
|
return rows;
|
487
561
|
}
|
@@ -491,34 +565,35 @@ static inline void batch_iterate(query_ctx *ctx, enum batch_mode mode, VALUE *ro
|
|
491
565
|
case BATCH_EXECUTE:
|
492
566
|
while (stmt_iterate(ctx));
|
493
567
|
break;
|
494
|
-
case BATCH_QUERY_ARY:
|
495
|
-
*rows = batch_iterate_ary(ctx);
|
496
|
-
break;
|
497
568
|
case BATCH_QUERY_HASH:
|
498
569
|
*rows = batch_iterate_hash(ctx);
|
499
570
|
break;
|
500
|
-
case
|
501
|
-
*rows =
|
571
|
+
case BATCH_QUERY_ARGV:
|
572
|
+
*rows = batch_iterate_argv(ctx);
|
573
|
+
break;
|
574
|
+
case BATCH_QUERY_ARY:
|
575
|
+
*rows = batch_iterate_ary(ctx);
|
502
576
|
break;
|
503
577
|
}
|
504
578
|
}
|
505
579
|
|
506
|
-
static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode
|
580
|
+
static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode batch_mode) {
|
507
581
|
int count = RARRAY_LEN(ctx->params);
|
508
582
|
int block_given = rb_block_given_p();
|
509
|
-
VALUE results = (
|
583
|
+
VALUE results = (batch_mode != BATCH_EXECUTE) && !block_given ? rb_ary_new() : Qnil;
|
510
584
|
VALUE rows = Qnil;
|
511
585
|
int changes = 0;
|
512
586
|
|
513
587
|
for (int i = 0; i < count; i++) {
|
514
588
|
sqlite3_reset(ctx->stmt);
|
515
589
|
sqlite3_clear_bindings(ctx->stmt);
|
590
|
+
Database_issue_query(ctx->db, ctx->sql);
|
516
591
|
bind_all_parameters_from_object(ctx->stmt, RARRAY_AREF(ctx->params, i));
|
517
592
|
|
518
|
-
batch_iterate(ctx,
|
593
|
+
batch_iterate(ctx, batch_mode, &rows);
|
519
594
|
changes += sqlite3_changes(ctx->sqlite3_db);
|
520
595
|
|
521
|
-
if (
|
596
|
+
if (batch_mode != BATCH_EXECUTE) {
|
522
597
|
if (block_given)
|
523
598
|
rb_yield(rows);
|
524
599
|
else
|
@@ -529,7 +604,7 @@ static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode mode) {
|
|
529
604
|
RB_GC_GUARD(rows);
|
530
605
|
RB_GC_GUARD(results);
|
531
606
|
|
532
|
-
if (
|
607
|
+
if (batch_mode == BATCH_EXECUTE || block_given)
|
533
608
|
return INT2FIX(changes);
|
534
609
|
else
|
535
610
|
return results;
|
@@ -537,7 +612,7 @@ static inline VALUE batch_run_array(query_ctx *ctx, enum batch_mode mode) {
|
|
537
612
|
|
538
613
|
struct batch_execute_each_ctx {
|
539
614
|
query_ctx *ctx;
|
540
|
-
enum batch_mode
|
615
|
+
enum batch_mode batch_mode;
|
541
616
|
int block_given;
|
542
617
|
VALUE results;
|
543
618
|
int changes;
|
@@ -549,12 +624,13 @@ static VALUE batch_run_each_iter(RB_BLOCK_CALL_FUNC_ARGLIST(yield_value, vctx))
|
|
549
624
|
|
550
625
|
sqlite3_reset(each_ctx->ctx->stmt);
|
551
626
|
sqlite3_clear_bindings(each_ctx->ctx->stmt);
|
627
|
+
Database_issue_query(each_ctx->ctx->db, each_ctx->ctx->sql);
|
552
628
|
bind_all_parameters_from_object(each_ctx->ctx->stmt, yield_value);
|
553
629
|
|
554
|
-
batch_iterate(each_ctx->ctx, each_ctx->
|
630
|
+
batch_iterate(each_ctx->ctx, each_ctx->batch_mode, &rows);
|
555
631
|
each_ctx->changes += sqlite3_changes(each_ctx->ctx->sqlite3_db);
|
556
632
|
|
557
|
-
if (each_ctx->
|
633
|
+
if (each_ctx->batch_mode != BATCH_EXECUTE) {
|
558
634
|
if (each_ctx->block_given)
|
559
635
|
rb_yield(rows);
|
560
636
|
else
|
@@ -565,26 +641,26 @@ static VALUE batch_run_each_iter(RB_BLOCK_CALL_FUNC_ARGLIST(yield_value, vctx))
|
|
565
641
|
return Qnil;
|
566
642
|
}
|
567
643
|
|
568
|
-
static inline VALUE batch_run_each(query_ctx *ctx, enum batch_mode
|
644
|
+
static inline VALUE batch_run_each(query_ctx *ctx, enum batch_mode batch_mode) {
|
569
645
|
struct batch_execute_each_ctx each_ctx = {
|
570
646
|
.ctx = ctx,
|
571
|
-
.
|
647
|
+
.batch_mode = batch_mode,
|
572
648
|
.block_given = rb_block_given_p(),
|
573
|
-
.results = ((
|
649
|
+
.results = ((batch_mode != BATCH_EXECUTE) && !rb_block_given_p() ? rb_ary_new() : Qnil),
|
574
650
|
.changes = 0
|
575
651
|
};
|
576
652
|
rb_block_call(ctx->params, ID_each, 0, 0, batch_run_each_iter, (VALUE)&each_ctx);
|
577
653
|
|
578
|
-
if (
|
654
|
+
if (batch_mode == BATCH_EXECUTE || each_ctx.block_given)
|
579
655
|
return INT2FIX(each_ctx.changes);
|
580
656
|
else
|
581
657
|
return each_ctx.results;
|
582
658
|
}
|
583
659
|
|
584
|
-
static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode
|
660
|
+
static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode batch_mode) {
|
585
661
|
VALUE params = Qnil;
|
586
662
|
int block_given = rb_block_given_p();
|
587
|
-
VALUE results = (
|
663
|
+
VALUE results = (batch_mode != BATCH_EXECUTE) && !block_given ? rb_ary_new() : Qnil;
|
588
664
|
VALUE rows = Qnil;
|
589
665
|
int changes = 0;
|
590
666
|
|
@@ -594,12 +670,13 @@ static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode mode) {
|
|
594
670
|
|
595
671
|
sqlite3_reset(ctx->stmt);
|
596
672
|
sqlite3_clear_bindings(ctx->stmt);
|
673
|
+
Database_issue_query(ctx->db, ctx->sql);
|
597
674
|
bind_all_parameters_from_object(ctx->stmt, params);
|
598
675
|
|
599
|
-
batch_iterate(ctx,
|
676
|
+
batch_iterate(ctx, batch_mode, &rows);
|
600
677
|
changes += sqlite3_changes(ctx->sqlite3_db);
|
601
678
|
|
602
|
-
if (
|
679
|
+
if (batch_mode != BATCH_EXECUTE) {
|
603
680
|
if (block_given)
|
604
681
|
rb_yield(rows);
|
605
682
|
else
|
@@ -611,21 +688,21 @@ static inline VALUE batch_run_proc(query_ctx *ctx, enum batch_mode mode) {
|
|
611
688
|
RB_GC_GUARD(results);
|
612
689
|
RB_GC_GUARD(params);
|
613
690
|
|
614
|
-
if (
|
691
|
+
if (batch_mode == BATCH_EXECUTE || block_given)
|
615
692
|
return INT2FIX(changes);
|
616
693
|
else
|
617
694
|
return results;
|
618
695
|
}
|
619
696
|
|
620
|
-
static inline VALUE batch_run(query_ctx *ctx, enum batch_mode
|
697
|
+
static inline VALUE batch_run(query_ctx *ctx, enum batch_mode batch_mode) {
|
621
698
|
if (TYPE(ctx->params) == T_ARRAY)
|
622
|
-
return batch_run_array(ctx,
|
699
|
+
return batch_run_array(ctx, batch_mode);
|
623
700
|
|
624
701
|
if (rb_respond_to(ctx->params, ID_each))
|
625
|
-
return batch_run_each(ctx,
|
702
|
+
return batch_run_each(ctx, batch_mode);
|
626
703
|
|
627
704
|
if (rb_respond_to(ctx->params, ID_call))
|
628
|
-
return batch_run_proc(ctx,
|
705
|
+
return batch_run_proc(ctx, batch_mode);
|
629
706
|
|
630
707
|
rb_raise(cParameterError, "Invalid parameter source supplied to #batch_execute");
|
631
708
|
}
|
@@ -635,15 +712,24 @@ VALUE safe_batch_execute(query_ctx *ctx) {
|
|
635
712
|
}
|
636
713
|
|
637
714
|
VALUE safe_batch_query(query_ctx *ctx) {
|
638
|
-
|
715
|
+
switch (ctx->query_mode) {
|
716
|
+
case QUERY_HASH:
|
717
|
+
return batch_run(ctx, BATCH_QUERY_HASH);
|
718
|
+
case QUERY_ARGV:
|
719
|
+
return batch_run(ctx, BATCH_QUERY_ARGV);
|
720
|
+
case QUERY_ARY:
|
721
|
+
return batch_run(ctx, BATCH_QUERY_ARY);
|
722
|
+
default:
|
723
|
+
rb_raise(cError, "Invalid query mode (safe_batch_query)");
|
724
|
+
}
|
639
725
|
}
|
640
726
|
|
641
727
|
VALUE safe_batch_query_ary(query_ctx *ctx) {
|
642
728
|
return batch_run(ctx, BATCH_QUERY_ARY);
|
643
729
|
}
|
644
730
|
|
645
|
-
VALUE
|
646
|
-
return batch_run(ctx,
|
731
|
+
VALUE safe_batch_query_argv(query_ctx *ctx) {
|
732
|
+
return batch_run(ctx, BATCH_QUERY_ARGV);
|
647
733
|
}
|
648
734
|
|
649
735
|
VALUE safe_query_columns(query_ctx *ctx) {
|