amalgalite 1.6.3-x64-mingw32 → 1.8.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/HISTORY.md +26 -0
- data/LICENSE +1 -1
- data/README.md +3 -2
- data/Rakefile +9 -8
- data/ext/amalgalite/c/amalgalite_constants.c +207 -1
- data/ext/amalgalite/c/amalgalite_database.c +80 -70
- data/ext/amalgalite/c/extconf.rb +8 -0
- data/ext/amalgalite/c/gen_constants.rb +23 -0
- data/ext/amalgalite/c/sqlite3.c +51527 -28444
- data/ext/amalgalite/c/sqlite3.h +2193 -990
- data/ext/amalgalite/c/sqlite3ext.h +77 -0
- data/lib/amalgalite/2.4/amalgalite.so +0 -0
- data/lib/amalgalite/2.5/amalgalite.so +0 -0
- data/lib/amalgalite/2.6/amalgalite.so +0 -0
- data/lib/amalgalite/2.7/amalgalite.so +0 -0
- data/lib/amalgalite/3.0/amalgalite.so +0 -0
- data/lib/amalgalite/aggregate.rb +6 -0
- data/lib/amalgalite/csv_table_importer.rb +3 -2
- data/lib/amalgalite/database.rb +2 -53
- data/lib/amalgalite/profile_tap.rb +2 -2
- data/lib/amalgalite/taps/io.rb +5 -2
- data/lib/amalgalite/trace_tap.rb +1 -1
- data/lib/amalgalite/version.rb +1 -1
- data/spec/aggregate_spec.rb +4 -0
- data/spec/database_spec.rb +12 -15
- data/spec/sqlite3/version_spec.rb +7 -7
- data/tasks/custom.rake +7 -8
- data/tasks/default.rake +13 -9
- data/tasks/extension.rake +12 -22
- data/tasks/this.rb +5 -5
- metadata +40 -35
- data/lib/amalgalite/2.2/amalgalite.so +0 -0
- data/lib/amalgalite/2.3/amalgalite.so +0 -0
@@ -328,22 +328,59 @@ VALUE am_sqlite3_database_exec(VALUE self, VALUE rSQL)
|
|
328
328
|
}
|
329
329
|
|
330
330
|
/**
|
331
|
-
* This function is registered with a sqlite3 database using the
|
332
|
-
* function.
|
333
|
-
* registered.
|
331
|
+
* This function is registered with a sqlite3 database using the
|
332
|
+
* sqlite3_trace_v2 function. During the registration process a handle on a
|
333
|
+
* VALUE is also registered.
|
334
334
|
*
|
335
335
|
* When this function is called, it calls the 'trace' method on the tap object,
|
336
|
-
* which is the VALUE that was registered during the
|
336
|
+
* which is the VALUE that was registered during the sqlite3_trace_v2 call.
|
337
337
|
*
|
338
|
-
* This function corresponds to the SQLite
|
338
|
+
* This function corresponds to the SQLite xCallback function specification.
|
339
|
+
*
|
340
|
+
* https://sqlite.org/c3ref/c_trace.html
|
339
341
|
*
|
340
342
|
*/
|
341
|
-
|
343
|
+
int amalgalite_xTraceCallback(unsigned trace_type, void* tap, void* prepared_statement, void* extra)
|
342
344
|
{
|
343
345
|
VALUE trace_obj = (VALUE) tap;
|
346
|
+
char* msg;
|
347
|
+
sqlite3_uint64 time;
|
348
|
+
|
349
|
+
switch(trace_type) {
|
350
|
+
case SQLITE_TRACE_STMT:
|
351
|
+
msg = (char*)extra;
|
352
|
+
|
353
|
+
/* The callback can compute the same text that would have been returned by the
|
354
|
+
* legacy sqlite3_trace() interface by using the X argument when X begins with
|
355
|
+
* "--" and invoking sqlite3_expanded_sql(P) otherwise.
|
356
|
+
*/
|
357
|
+
if (0 != strncmp(msg, "--", 2)) {
|
358
|
+
msg = sqlite3_expanded_sql(prepared_statement);
|
359
|
+
}
|
360
|
+
|
361
|
+
rb_funcall( trace_obj, rb_intern("trace"), 1, rb_str_new2( msg ) );
|
362
|
+
break;
|
344
363
|
|
345
|
-
|
346
|
-
|
364
|
+
case SQLITE_TRACE_PROFILE:
|
365
|
+
msg = sqlite3_expanded_sql(prepared_statement);
|
366
|
+
time = *(sqlite3_uint64*)extra;
|
367
|
+
rb_funcall( trace_obj, rb_intern("profile"),
|
368
|
+
2, rb_str_new2( msg ), SQLUINT64_2NUM(time) );
|
369
|
+
break;
|
370
|
+
|
371
|
+
case SQLITE_TRACE_ROW:
|
372
|
+
/* not implemented */
|
373
|
+
break;
|
374
|
+
|
375
|
+
case SQLITE_TRACE_CLOSE:
|
376
|
+
/* not implemented */
|
377
|
+
break;
|
378
|
+
|
379
|
+
default:
|
380
|
+
/* nothing */
|
381
|
+
break;
|
382
|
+
}
|
383
|
+
return 0;
|
347
384
|
}
|
348
385
|
|
349
386
|
|
@@ -351,12 +388,16 @@ void amalgalite_xTrace(void* tap, const char* msg)
|
|
351
388
|
* call-seq:
|
352
389
|
* database.register_trace_tap( tap_obj )
|
353
390
|
*
|
354
|
-
* This registers an object to be called
|
391
|
+
* This registers an object to be called for all the trace objects in the sqlite
|
392
|
+
* system. From an SQLite perspective, the trace object is registered for both
|
393
|
+
* SQLITE_TRACE_STMT and SQLITE_TRACE_PROFILE.
|
355
394
|
*
|
395
|
+
* The object must respond to both `trace` and `profile` methods. See
|
396
|
+
* Amalgalite::Trace::
|
356
397
|
* This is an experimental api and is subject to change, or removal.
|
357
398
|
*
|
358
399
|
*/
|
359
|
-
VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap)
|
400
|
+
VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap )
|
360
401
|
{
|
361
402
|
am_sqlite3 *am_db;
|
362
403
|
|
@@ -367,7 +408,7 @@ VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap)
|
|
367
408
|
*/
|
368
409
|
if ( Qnil == tap ) {
|
369
410
|
|
370
|
-
|
411
|
+
sqlite3_trace_v2( am_db->db, 0, NULL, NULL );
|
371
412
|
rb_gc_unregister_address( &(am_db->trace_obj) );
|
372
413
|
am_db->trace_obj = Qnil;
|
373
414
|
|
@@ -379,65 +420,12 @@ VALUE am_sqlite3_database_register_trace_tap(VALUE self, VALUE tap)
|
|
379
420
|
|
380
421
|
am_db->trace_obj = tap;
|
381
422
|
rb_gc_register_address( &(am_db->trace_obj) );
|
382
|
-
|
423
|
+
sqlite3_trace_v2( am_db->db, SQLITE_TRACE_STMT | SQLITE_TRACE_PROFILE, amalgalite_xTraceCallback, (void *)am_db->trace_obj );
|
383
424
|
}
|
384
425
|
|
385
426
|
return Qnil;
|
386
427
|
}
|
387
428
|
|
388
|
-
|
389
|
-
/**
|
390
|
-
* the amagliate trace function to be registered with register_trace_tap
|
391
|
-
* When it is called, it calls the 'trace' method on the tap object.
|
392
|
-
*
|
393
|
-
* This function conforms to the sqlite3 xProfile function specification.
|
394
|
-
*/
|
395
|
-
void amalgalite_xProfile(void* tap, const char* msg, sqlite3_uint64 time)
|
396
|
-
{
|
397
|
-
VALUE trace_obj = (VALUE) tap;
|
398
|
-
|
399
|
-
rb_funcall( trace_obj, rb_intern("profile"),
|
400
|
-
2, rb_str_new2( msg ), SQLUINT64_2NUM(time) );
|
401
|
-
|
402
|
-
return;
|
403
|
-
}
|
404
|
-
|
405
|
-
/**
|
406
|
-
* call-seq:
|
407
|
-
* database.register_profile_tap( tap_obj )
|
408
|
-
*
|
409
|
-
* This registers an object to be called with every profile event in SQLite.
|
410
|
-
*
|
411
|
-
* This is an experimental api and is subject to change or removal.
|
412
|
-
*
|
413
|
-
*/
|
414
|
-
VALUE am_sqlite3_database_register_profile_tap(VALUE self, VALUE tap)
|
415
|
-
{
|
416
|
-
am_sqlite3 *am_db;
|
417
|
-
|
418
|
-
Data_Get_Struct(self, am_sqlite3, am_db);
|
419
|
-
|
420
|
-
/* Qnil, unregister the item and tell the garbage collector we are done with
|
421
|
-
* it.
|
422
|
-
*/
|
423
|
-
|
424
|
-
if ( tap == Qnil ) {
|
425
|
-
sqlite3_profile( am_db->db, NULL, NULL );
|
426
|
-
rb_gc_unregister_address( &(am_db->profile_obj) );
|
427
|
-
am_db->profile_obj = Qnil;
|
428
|
-
|
429
|
-
/* register the item and store the reference to the object in the am_db
|
430
|
-
* structure. We also have to tell the Ruby garbage collector that we
|
431
|
-
* point to the Ruby object from C.
|
432
|
-
*/
|
433
|
-
} else {
|
434
|
-
am_db->profile_obj = tap;
|
435
|
-
rb_gc_register_address( &(am_db->profile_obj) );
|
436
|
-
sqlite3_profile( am_db->db, amalgalite_xProfile, (void *)am_db->profile_obj );
|
437
|
-
}
|
438
|
-
return Qnil;
|
439
|
-
}
|
440
|
-
|
441
429
|
/**
|
442
430
|
* invoke a ruby function. This is here to be used by rb_protect.
|
443
431
|
*/
|
@@ -794,8 +782,11 @@ void amalgalite_xStep( sqlite3_context* context, int argc, sqlite3_value** argv
|
|
794
782
|
VALUE klass = (VALUE) sqlite3_user_data( context );
|
795
783
|
result = rb_protect( amalgalite_wrap_new_aggregate, klass, &state );
|
796
784
|
|
785
|
+
/* exception was raised during initialization */
|
797
786
|
if ( state ) {
|
798
|
-
|
787
|
+
*aggregate_context = rb_gv_get("$!");
|
788
|
+
rb_gc_register_address( aggregate_context );
|
789
|
+
VALUE msg = rb_obj_as_string( *aggregate_context );
|
799
790
|
sqlite3_result_error( context, RSTRING_PTR(msg), (int)RSTRING_LEN(msg));
|
800
791
|
return;
|
801
792
|
} else {
|
@@ -844,8 +835,30 @@ void amalgalite_xFinal( sqlite3_context* context )
|
|
844
835
|
VALUE result;
|
845
836
|
int state;
|
846
837
|
am_protected_t protected;
|
838
|
+
VALUE exception = Qnil;
|
847
839
|
VALUE *aggregate_context = (VALUE*)sqlite3_aggregate_context( context, sizeof( VALUE ) );
|
848
|
-
|
840
|
+
|
841
|
+
/**
|
842
|
+
* check and see if an exception had been throw at some point during the
|
843
|
+
* initialization of hte aggregate or during the step function call
|
844
|
+
*
|
845
|
+
*/
|
846
|
+
if (TYPE(*aggregate_context) == T_OBJECT) {
|
847
|
+
/* if there is a @_exception value and it has a value then there was an
|
848
|
+
* exception during step function execution
|
849
|
+
*/
|
850
|
+
if (rb_ivar_defined( *aggregate_context, rb_intern("@_exception") )) {
|
851
|
+
exception = rb_iv_get( *aggregate_context, "@_exception" );
|
852
|
+
} else {
|
853
|
+
|
854
|
+
/* if the aggregate context itself is an exception, then there was
|
855
|
+
* an error during teh initialization of the aggregate context
|
856
|
+
*/
|
857
|
+
if (rb_obj_is_kind_of( *aggregate_context, rb_eException )) {
|
858
|
+
exception = *aggregate_context;
|
859
|
+
}
|
860
|
+
}
|
861
|
+
}
|
849
862
|
|
850
863
|
if ( Qnil == exception ) {
|
851
864
|
/* gather all the data to make the protected call */
|
@@ -868,8 +881,6 @@ void amalgalite_xFinal( sqlite3_context* context )
|
|
868
881
|
sqlite3_result_error( context, RSTRING_PTR(msg), (int)RSTRING_LEN(msg) );
|
869
882
|
}
|
870
883
|
|
871
|
-
|
872
|
-
|
873
884
|
/* release the aggregate instance from garbage collector protection */
|
874
885
|
rb_gc_unregister_address( aggregate_context );
|
875
886
|
|
@@ -1151,7 +1162,6 @@ void Init_amalgalite_database( )
|
|
1151
1162
|
rb_define_method(cAS_Database, "last_insert_rowid", am_sqlite3_database_last_insert_rowid, 0); /* in amalgalite_database.c */
|
1152
1163
|
rb_define_method(cAS_Database, "autocommit?", am_sqlite3_database_is_autocommit, 0); /* in amalgalite_database.c */
|
1153
1164
|
rb_define_method(cAS_Database, "register_trace_tap", am_sqlite3_database_register_trace_tap, 1); /* in amalgalite_database.c */
|
1154
|
-
rb_define_method(cAS_Database, "register_profile_tap", am_sqlite3_database_register_profile_tap, 1); /* in amalgalite_database.c */
|
1155
1165
|
rb_define_method(cAS_Database, "table_column_metadata", am_sqlite3_database_table_column_metadata, 3); /* in amalgalite_database.c */
|
1156
1166
|
rb_define_method(cAS_Database, "row_changes", am_sqlite3_database_row_changes, 0); /* in amalgalite_database.c */
|
1157
1167
|
rb_define_method(cAS_Database, "total_changes", am_sqlite3_database_total_changes, 0); /* in amalgalite_database.c */
|
data/ext/amalgalite/c/extconf.rb
CHANGED
@@ -6,9 +6,12 @@ require 'rbconfig'
|
|
6
6
|
$ruby = ARGV.shift if ARGV[0]
|
7
7
|
|
8
8
|
# make available table and column meta data api
|
9
|
+
$CFLAGS += " -DSQLITE_ENABLE_BYTECODE_VTAB=1"
|
9
10
|
$CFLAGS += " -DSQLITE_ENABLE_COLUMN_METADATA=1"
|
10
11
|
$CFLAGS += " -DSQLITE_ENABLE_DBSTAT_VTAB=1"
|
11
12
|
$CFLAGS += " -DSQLITE_ENABLE_DBPAGE_VTAB=1"
|
13
|
+
$CFLAGS += " -DSQLITE_ENABLE_DESERIALIZE=1"
|
14
|
+
$CFLAGS += " -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1"
|
12
15
|
$CFLAGS += " -DSQLITE_ENABLE_FTS3=1"
|
13
16
|
$CFLAGS += " -DSQLITE_ENABLE_FTS3_PARENTHESIS=1"
|
14
17
|
$CFLAGS += " -DSQLITE_ENABLE_FTS4=1"
|
@@ -16,14 +19,19 @@ $CFLAGS += " -DSQLITE_ENABLE_FTS5=1"
|
|
16
19
|
$CFLAGS += " -DSQLITE_ENABLE_GEOPOLY=1"
|
17
20
|
$CFLAGS += " -DSQLITE_ENABLE_JSON1=1"
|
18
21
|
$CFLAGS += " -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1"
|
22
|
+
$CFLAGS += " -DSQLITE_ENABLE_NULL_TRIM=1"
|
19
23
|
$CFLAGS += " -DSQLITE_ENABLE_PREUPDATE_HOOK=1"
|
24
|
+
$CFLAGS ++ " -DSQLITE_EANBLE_QPSG=1"
|
20
25
|
$CFLAGS += " -DSQLITE_ENABLE_RBU=1"
|
21
26
|
$CFLAGS += " -DSQLITE_ENABLE_RTREE=1"
|
22
27
|
$CFLAGS += " -DSQLITE_ENABLE_SESSION=1"
|
28
|
+
$CFLAGS += " -DSQLITE_ENABLE_SNAPSHOT=1"
|
23
29
|
$CFLAGS += " -DSQLITE_ENABLE_STMTVTAB=1"
|
24
30
|
$CFLAGS += " -DSQLITE_ENABLE_STAT4=1"
|
25
31
|
$CFLAGS += " -DSQLITE_ENABLE_UNLOCK_NOTIFY=1"
|
26
32
|
|
33
|
+
$CFLAGS += " -DSQLITE_OMIT_DEPRECATED=1"
|
34
|
+
|
27
35
|
# we compile sqlite the same way that the installation of ruby is compiled.
|
28
36
|
if RbConfig::MAKEFILE_CONFIG['configure_args'].include?( "--enable-pthread" ) then
|
29
37
|
$CFLAGS += " -DSQLITE_THREADSAFE=1"
|
@@ -38,6 +38,9 @@ result_codes = %w[
|
|
38
38
|
SQLITE_WARNING
|
39
39
|
SQLITE_ROW
|
40
40
|
SQLITE_DONE
|
41
|
+
SQLITE_ERROR_MISSING_COLLSEQ
|
42
|
+
SQLITE_ERROR_RETRY
|
43
|
+
SQLITE_ERROR_SNAPSHOT
|
41
44
|
SQLITE_IOERR_READ
|
42
45
|
SQLITE_IOERR_SHORT_READ
|
43
46
|
SQLITE_IOERR_WRITE
|
@@ -69,18 +72,28 @@ result_codes = %w[
|
|
69
72
|
SQLITE_IOERR_BEGIN_ATOMIC
|
70
73
|
SQLITE_IOERR_COMMIT_ATOMIC
|
71
74
|
SQLITE_IOERR_ROLLBACK_ATOMIC
|
75
|
+
SQLITE_IOERR_DATA
|
76
|
+
SQLITE_IOERR_CORRUPTFS
|
72
77
|
SQLITE_LOCKED_SHAREDCACHE
|
78
|
+
SQLITE_LOCKED_VTAB
|
73
79
|
SQLITE_BUSY_RECOVERY
|
74
80
|
SQLITE_BUSY_SNAPSHOT
|
81
|
+
SQLITE_BUSY_TIMEOUT
|
75
82
|
SQLITE_CANTOPEN_NOTEMPDIR
|
76
83
|
SQLITE_CANTOPEN_ISDIR
|
77
84
|
SQLITE_CANTOPEN_FULLPATH
|
78
85
|
SQLITE_CANTOPEN_CONVPATH
|
86
|
+
SQLITE_CANTOPEN_DIRTYWAL
|
87
|
+
SQLITE_CANTOPEN_SYMLINK
|
79
88
|
SQLITE_CORRUPT_VTAB
|
89
|
+
SQLITE_CORRUPT_SEQUENCE
|
90
|
+
SQLITE_CORRUPT_INDEX
|
80
91
|
SQLITE_READONLY_RECOVERY
|
81
92
|
SQLITE_READONLY_CANTLOCK
|
82
93
|
SQLITE_READONLY_ROLLBACK
|
83
94
|
SQLITE_READONLY_DBMOVED
|
95
|
+
SQLITE_READONLY_CANTINIT
|
96
|
+
SQLITE_READONLY_DIRECTORY
|
84
97
|
SQLITE_ABORT_ROLLBACK
|
85
98
|
SQLITE_CONSTRAINT_CHECK
|
86
99
|
SQLITE_CONSTRAINT_COMMITHOOK
|
@@ -92,11 +105,13 @@ result_codes = %w[
|
|
92
105
|
SQLITE_CONSTRAINT_UNIQUE
|
93
106
|
SQLITE_CONSTRAINT_VTAB
|
94
107
|
SQLITE_CONSTRAINT_ROWID
|
108
|
+
SQLITE_CONSTRAINT_PINNED
|
95
109
|
SQLITE_NOTICE_RECOVER_WAL
|
96
110
|
SQLITE_NOTICE_RECOVER_ROLLBACK
|
97
111
|
SQLITE_WARNING_AUTOINDEX
|
98
112
|
SQLITE_AUTH_USER
|
99
113
|
SQLITE_OK_LOAD_PERMANENTLY
|
114
|
+
SQLITE_OK_SYMLINK
|
100
115
|
]
|
101
116
|
|
102
117
|
deprecated_codes = %w[ SQLITE_GET_LOCKPROXYFILE SQLITE_SET_LOCKPROXYFILE SQLITE_LAST_ERRNO ]
|
@@ -150,6 +165,9 @@ text_encoding_codes = %w[
|
|
150
165
|
SQLITE_ANY
|
151
166
|
SQLITE_UTF16_ALIGNED
|
152
167
|
SQLITE_DETERMINISTIC
|
168
|
+
SQLITE_DIRECTONLY
|
169
|
+
SQLITE_SUBTYPE
|
170
|
+
SQLITE_INNOCUOUS
|
153
171
|
]
|
154
172
|
|
155
173
|
data_type_codes = %w[
|
@@ -174,6 +192,8 @@ ignore_codes = [
|
|
174
192
|
"SQLITE_FAIL",
|
175
193
|
"SQLITE_REPLACE",
|
176
194
|
"SQLITE_VTAB_CONSTRAINT_SUPPORT",
|
195
|
+
"SQLITE_VTAB_INNOCUOUS",
|
196
|
+
"SQLITE_VTAB_DIRECTONLY",
|
177
197
|
|
178
198
|
# sqlite destructor callback codes
|
179
199
|
"SQLITE_STATIC",
|
@@ -189,6 +209,9 @@ module_name_mapping = {
|
|
189
209
|
"SHM" => "SHM",
|
190
210
|
"SCANSTAT" => "ScanStat",
|
191
211
|
"STMTSTATUS" => "StatementStatus",
|
212
|
+
"CHANGESETAPPLY" => "ChangesetApply",
|
213
|
+
"CHANGESETSTART" => "ChangesetStart",
|
214
|
+
"TXN" => "Transaction",
|
192
215
|
}
|
193
216
|
|
194
217
|
defines = []
|