amalgalite 1.4.1-x86-mingw32 → 1.7.0-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CONTRIBUTING.md +11 -0
- data/HISTORY.md +45 -0
- data/LICENSE +2 -0
- data/Manifest.txt +2 -1
- data/README.md +10 -14
- data/Rakefile +5 -5
- data/examples/fts5.rb +152 -0
- data/ext/amalgalite/c/amalgalite.c +26 -0
- data/ext/amalgalite/c/amalgalite_constants.c +1110 -56
- data/ext/amalgalite/c/amalgalite_database.c +80 -70
- data/ext/amalgalite/c/extconf.rb +31 -4
- data/ext/amalgalite/c/gen_constants.rb +313 -153
- data/ext/amalgalite/c/sqlite3.c +103967 -33836
- data/ext/amalgalite/c/sqlite3.h +5438 -1061
- data/ext/amalgalite/c/sqlite3ext.h +148 -12
- data/lib/amalgalite/2.2/amalgalite.so +0 -0
- data/lib/amalgalite/2.3/amalgalite.so +0 -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/aggregate.rb +6 -0
- data/lib/amalgalite/csv_table_importer.rb +1 -1
- data/lib/amalgalite/database.rb +2 -53
- data/lib/amalgalite/profile_tap.rb +2 -2
- data/lib/amalgalite/statement.rb +5 -2
- data/lib/amalgalite/taps/io.rb +5 -2
- data/lib/amalgalite/trace_tap.rb +1 -1
- data/lib/amalgalite/type_maps/default_map.rb +2 -2
- data/lib/amalgalite/type_maps/storage_map.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/default_map_spec.rb +1 -1
- data/spec/integeration_spec.rb +2 -2
- data/spec/json_spec.rb +24 -0
- data/spec/sqlite3/version_spec.rb +15 -9
- data/spec/storage_map_spec.rb +1 -1
- data/tasks/default.rake +3 -10
- data/tasks/extension.rake +4 -4
- data/tasks/this.rb +7 -5
- metadata +33 -25
- data/examples/fts3.rb +0 -144
- data/lib/amalgalite/1.8/amalgalite.so +0 -0
- data/lib/amalgalite/1.9/amalgalite.so +0 -0
- data/lib/amalgalite/2.0/amalgalite.so +0 -0
- data/lib/amalgalite/2.1/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,13 +6,31 @@ 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
|
-
$CFLAGS += " -
|
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"
|
18
|
+
$CFLAGS += " -DSQLITE_ENABLE_FTS5=1"
|
19
|
+
$CFLAGS += " -DSQLITE_ENABLE_GEOPOLY=1"
|
20
|
+
$CFLAGS += " -DSQLITE_ENABLE_JSON1=1"
|
21
|
+
$CFLAGS += " -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1"
|
22
|
+
$CFLAGS += " -DSQLITE_ENABLE_NULL_TRIM=1"
|
23
|
+
$CFLAGS += " -DSQLITE_ENABLE_PREUPDATE_HOOK=1"
|
24
|
+
$CFLAGS ++ " -DSQLITE_EANBLE_QPSG=1"
|
25
|
+
$CFLAGS += " -DSQLITE_ENABLE_RBU=1"
|
26
|
+
$CFLAGS += " -DSQLITE_ENABLE_RTREE=1"
|
27
|
+
$CFLAGS += " -DSQLITE_ENABLE_SESSION=1"
|
28
|
+
$CFLAGS += " -DSQLITE_ENABLE_SNAPSHOT=1"
|
29
|
+
$CFLAGS += " -DSQLITE_ENABLE_STMTVTAB=1"
|
15
30
|
$CFLAGS += " -DSQLITE_ENABLE_STAT4=1"
|
31
|
+
$CFLAGS += " -DSQLITE_ENABLE_UNLOCK_NOTIFY=1"
|
32
|
+
|
33
|
+
$CFLAGS += " -DSQLITE_OMIT_DEPRECATED=1"
|
16
34
|
|
17
35
|
# we compile sqlite the same way that the installation of ruby is compiled.
|
18
36
|
if RbConfig::MAKEFILE_CONFIG['configure_args'].include?( "--enable-pthread" ) then
|
@@ -23,12 +41,21 @@ end
|
|
23
41
|
|
24
42
|
# remove the -g flags if it exists
|
25
43
|
%w[ -ggdb\\d* -g\\d* ].each do |debug|
|
26
|
-
$CFLAGS = $CFLAGS.gsub(
|
27
|
-
RbConfig::MAKEFILE_CONFIG['debugflags'] = RbConfig::MAKEFILE_CONFIG['debugflags'].gsub(
|
44
|
+
$CFLAGS = $CFLAGS.gsub(/\s#{debug}\b/,'')
|
45
|
+
RbConfig::MAKEFILE_CONFIG['debugflags'] = RbConfig::MAKEFILE_CONFIG['debugflags'].gsub(/\s#{debug}\b/,'') if RbConfig::MAKEFILE_CONFIG['debugflags']
|
28
46
|
end
|
29
47
|
|
30
48
|
ignoreable_warnings = %w[ write-strings ]
|
31
|
-
ignore_by_compiler = {
|
49
|
+
ignore_by_compiler = {
|
50
|
+
"clang" => %w[
|
51
|
+
empty-body
|
52
|
+
incompatible-pointer-types-discards-qualifiers
|
53
|
+
shorten-64-to-32
|
54
|
+
sign-compare
|
55
|
+
unused-const-variable
|
56
|
+
unused-variable
|
57
|
+
]
|
58
|
+
}
|
32
59
|
|
33
60
|
if extras = ignore_by_compiler[RbConfig::MAKEFILE_CONFIG["CC"]] then
|
34
61
|
ignoreable_warnings.concat(extras)
|
@@ -1,141 +1,311 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
# readin in the sqlite3.h file and parse out all the #define lines
|
6
|
+
sqlite3_h_fname = File.expand_path(File.join(File.dirname(__FILE__), "sqlite3.h"))
|
7
|
+
|
8
|
+
# special handling for those that are function result codes
|
9
|
+
result_codes = %w[
|
10
|
+
SQLITE_OK
|
11
|
+
SQLITE_ERROR
|
12
|
+
SQLITE_INTERNAL
|
13
|
+
SQLITE_PERM
|
14
|
+
SQLITE_ABORT
|
15
|
+
SQLITE_BUSY
|
16
|
+
SQLITE_LOCKED
|
17
|
+
SQLITE_NOMEM
|
18
|
+
SQLITE_READONLY
|
19
|
+
SQLITE_INTERRUPT
|
20
|
+
SQLITE_IOERR
|
21
|
+
SQLITE_CORRUPT
|
22
|
+
SQLITE_NOTFOUND
|
23
|
+
SQLITE_FULL
|
24
|
+
SQLITE_CANTOPEN
|
25
|
+
SQLITE_PROTOCOL
|
26
|
+
SQLITE_EMPTY
|
27
|
+
SQLITE_SCHEMA
|
28
|
+
SQLITE_TOOBIG
|
29
|
+
SQLITE_CONSTRAINT
|
30
|
+
SQLITE_MISMATCH
|
31
|
+
SQLITE_MISUSE
|
32
|
+
SQLITE_NOLFS
|
33
|
+
SQLITE_AUTH
|
34
|
+
SQLITE_FORMAT
|
35
|
+
SQLITE_RANGE
|
36
|
+
SQLITE_NOTADB
|
37
|
+
SQLITE_NOTICE
|
38
|
+
SQLITE_WARNING
|
39
|
+
SQLITE_ROW
|
40
|
+
SQLITE_DONE
|
41
|
+
SQLITE_ERROR_MISSING_COLLSEQ
|
42
|
+
SQLITE_ERROR_RETRY
|
43
|
+
SQLITE_ERROR_SNAPSHOT
|
44
|
+
SQLITE_IOERR_READ
|
45
|
+
SQLITE_IOERR_SHORT_READ
|
46
|
+
SQLITE_IOERR_WRITE
|
47
|
+
SQLITE_IOERR_FSYNC
|
48
|
+
SQLITE_IOERR_DIR_FSYNC
|
49
|
+
SQLITE_IOERR_TRUNCATE
|
50
|
+
SQLITE_IOERR_FSTAT
|
51
|
+
SQLITE_IOERR_UNLOCK
|
52
|
+
SQLITE_IOERR_RDLOCK
|
53
|
+
SQLITE_IOERR_DELETE
|
54
|
+
SQLITE_IOERR_BLOCKED
|
55
|
+
SQLITE_IOERR_NOMEM
|
56
|
+
SQLITE_IOERR_ACCESS
|
57
|
+
SQLITE_IOERR_CHECKRESERVEDLOCK
|
58
|
+
SQLITE_IOERR_LOCK
|
59
|
+
SQLITE_IOERR_CLOSE
|
60
|
+
SQLITE_IOERR_DIR_CLOSE
|
61
|
+
SQLITE_IOERR_SHMOPEN
|
62
|
+
SQLITE_IOERR_SHMSIZE
|
63
|
+
SQLITE_IOERR_SHMLOCK
|
64
|
+
SQLITE_IOERR_SHMMAP
|
65
|
+
SQLITE_IOERR_SEEK
|
66
|
+
SQLITE_IOERR_DELETE_NOENT
|
67
|
+
SQLITE_IOERR_MMAP
|
68
|
+
SQLITE_IOERR_GETTEMPPATH
|
69
|
+
SQLITE_IOERR_CONVPATH
|
70
|
+
SQLITE_IOERR_VNODE
|
71
|
+
SQLITE_IOERR_AUTH
|
72
|
+
SQLITE_IOERR_BEGIN_ATOMIC
|
73
|
+
SQLITE_IOERR_COMMIT_ATOMIC
|
74
|
+
SQLITE_IOERR_ROLLBACK_ATOMIC
|
75
|
+
SQLITE_IOERR_DATA
|
76
|
+
SQLITE_IOERR_CORRUPTFS
|
77
|
+
SQLITE_LOCKED_SHAREDCACHE
|
78
|
+
SQLITE_LOCKED_VTAB
|
79
|
+
SQLITE_BUSY_RECOVERY
|
80
|
+
SQLITE_BUSY_SNAPSHOT
|
81
|
+
SQLITE_BUSY_TIMEOUT
|
82
|
+
SQLITE_CANTOPEN_NOTEMPDIR
|
83
|
+
SQLITE_CANTOPEN_ISDIR
|
84
|
+
SQLITE_CANTOPEN_FULLPATH
|
85
|
+
SQLITE_CANTOPEN_CONVPATH
|
86
|
+
SQLITE_CANTOPEN_DIRTYWAL
|
87
|
+
SQLITE_CANTOPEN_SYMLINK
|
88
|
+
SQLITE_CORRUPT_VTAB
|
89
|
+
SQLITE_CORRUPT_SEQUENCE
|
90
|
+
SQLITE_CORRUPT_INDEX
|
91
|
+
SQLITE_READONLY_RECOVERY
|
92
|
+
SQLITE_READONLY_CANTLOCK
|
93
|
+
SQLITE_READONLY_ROLLBACK
|
94
|
+
SQLITE_READONLY_DBMOVED
|
95
|
+
SQLITE_READONLY_CANTINIT
|
96
|
+
SQLITE_READONLY_DIRECTORY
|
97
|
+
SQLITE_ABORT_ROLLBACK
|
98
|
+
SQLITE_CONSTRAINT_CHECK
|
99
|
+
SQLITE_CONSTRAINT_COMMITHOOK
|
100
|
+
SQLITE_CONSTRAINT_FOREIGNKEY
|
101
|
+
SQLITE_CONSTRAINT_FUNCTION
|
102
|
+
SQLITE_CONSTRAINT_NOTNULL
|
103
|
+
SQLITE_CONSTRAINT_PRIMARYKEY
|
104
|
+
SQLITE_CONSTRAINT_TRIGGER
|
105
|
+
SQLITE_CONSTRAINT_UNIQUE
|
106
|
+
SQLITE_CONSTRAINT_VTAB
|
107
|
+
SQLITE_CONSTRAINT_ROWID
|
108
|
+
SQLITE_CONSTRAINT_PINNED
|
109
|
+
SQLITE_NOTICE_RECOVER_WAL
|
110
|
+
SQLITE_NOTICE_RECOVER_ROLLBACK
|
111
|
+
SQLITE_WARNING_AUTOINDEX
|
112
|
+
SQLITE_AUTH_USER
|
113
|
+
SQLITE_OK_LOAD_PERMANENTLY
|
114
|
+
SQLITE_OK_SYMLINK
|
115
|
+
]
|
116
|
+
|
117
|
+
deprecated_codes = %w[ SQLITE_GET_LOCKPROXYFILE SQLITE_SET_LOCKPROXYFILE SQLITE_LAST_ERRNO ]
|
118
|
+
version_codes = %w[ SQLITE_VERSION SQLITE_VERSION_NUMBER SQLITE_SOURCE_ID ]
|
119
|
+
rtree_codes = %w[ NOT_WITHIN PARTLY_WITHIN FULLY_WITHIN ]
|
120
|
+
|
121
|
+
authorizer_codes = %w[
|
122
|
+
SQLITE_DENY
|
123
|
+
SQLITE_IGNORE
|
124
|
+
SQLITE_CREATE_INDEX
|
125
|
+
SQLITE_CREATE_TABLE
|
126
|
+
SQLITE_CREATE_TEMP_INDEX
|
127
|
+
SQLITE_CREATE_TEMP_TABLE
|
128
|
+
SQLITE_CREATE_TEMP_TRIGGER
|
129
|
+
SQLITE_CREATE_TEMP_VIEW
|
130
|
+
SQLITE_CREATE_TRIGGER
|
131
|
+
SQLITE_CREATE_VIEW
|
132
|
+
SQLITE_DELETE
|
133
|
+
SQLITE_DROP_INDEX
|
134
|
+
SQLITE_DROP_TABLE
|
135
|
+
SQLITE_DROP_TEMP_INDEX
|
136
|
+
SQLITE_DROP_TEMP_TABLE
|
137
|
+
SQLITE_DROP_TEMP_TRIGGER
|
138
|
+
SQLITE_DROP_TEMP_VIEW
|
139
|
+
SQLITE_DROP_TRIGGER
|
140
|
+
SQLITE_DROP_VIEW
|
141
|
+
SQLITE_INSERT
|
142
|
+
SQLITE_PRAGMA
|
143
|
+
SQLITE_READ
|
144
|
+
SQLITE_SELECT
|
145
|
+
SQLITE_TRANSACTION
|
146
|
+
SQLITE_UPDATE
|
147
|
+
SQLITE_ATTACH
|
148
|
+
SQLITE_DETACH
|
149
|
+
SQLITE_ALTER_TABLE
|
150
|
+
SQLITE_REINDEX
|
151
|
+
SQLITE_ANALYZE
|
152
|
+
SQLITE_CREATE_VTABLE
|
153
|
+
SQLITE_DROP_VTABLE
|
154
|
+
SQLITE_FUNCTION
|
155
|
+
SQLITE_SAVEPOINT
|
156
|
+
SQLITE_COPY
|
157
|
+
SQLITE_RECURSIVE
|
158
|
+
]
|
159
|
+
|
160
|
+
text_encoding_codes = %w[
|
161
|
+
SQLITE_UTF8
|
162
|
+
SQLITE_UTF16LE
|
163
|
+
SQLITE_UTF16BE
|
164
|
+
SQLITE_UTF16
|
165
|
+
SQLITE_ANY
|
166
|
+
SQLITE_UTF16_ALIGNED
|
167
|
+
SQLITE_DETERMINISTIC
|
168
|
+
SQLITE_DIRECTONLY
|
169
|
+
SQLITE_SUBTYPE
|
170
|
+
SQLITE_INNOCUOUS
|
171
|
+
]
|
172
|
+
|
173
|
+
data_type_codes = %w[
|
174
|
+
SQLITE_INTEGER
|
175
|
+
SQLITE_FLOAT
|
176
|
+
SQLITE_BLOB
|
177
|
+
SQLITE_NULL
|
178
|
+
SQLITE3_TEXT
|
179
|
+
]
|
180
|
+
|
181
|
+
fts5_codes = %w[
|
182
|
+
FTS5_TOKENIZE_QUERY
|
183
|
+
FTS5_TOKENIZE_PREFIX
|
184
|
+
FTS5_TOKENIZE_DOCUMENT
|
185
|
+
FTS5_TOKENIZE_AUX
|
186
|
+
FTS5_TOKEN_COLOCATED
|
187
|
+
]
|
188
|
+
|
189
|
+
ignore_codes = [
|
190
|
+
# vtab related
|
191
|
+
"SQLITE_ROLLBACK",
|
192
|
+
"SQLITE_FAIL",
|
193
|
+
"SQLITE_REPLACE",
|
194
|
+
"SQLITE_VTAB_CONSTRAINT_SUPPORT",
|
195
|
+
"SQLITE_VTAB_INNOCUOUS",
|
196
|
+
"SQLITE_VTAB_DIRECTONLY",
|
197
|
+
|
198
|
+
# sqlite destructor callback codes
|
199
|
+
"SQLITE_STATIC",
|
200
|
+
"SQLITE_TRANSIENT",
|
201
|
+
]
|
202
|
+
|
203
|
+
# oddball name
|
204
|
+
module_name_mapping = {
|
135
205
|
|
206
|
+
"DBCONFIG" => "DBConfig",
|
207
|
+
"DBSTATUS" => "DBStatus",
|
208
|
+
"IOCAP" => "IOCap",
|
209
|
+
"SHM" => "SHM",
|
210
|
+
"SCANSTAT" => "ScanStat",
|
211
|
+
"STMTSTATUS" => "StatementStatus",
|
212
|
+
"CHANGESETAPPLY" => "ChangesetApply",
|
213
|
+
"CHANGESETSTART" => "ChangesetStart",
|
214
|
+
"TXN" => "Transaction",
|
136
215
|
}
|
137
216
|
|
217
|
+
defines = []
|
218
|
+
IO.readlines(sqlite3_h_fname).each do |l|
|
219
|
+
result = {
|
220
|
+
"c_define" => nil,
|
221
|
+
"c_value" => nil,
|
222
|
+
"docstring" => nil,
|
223
|
+
|
224
|
+
"is_error_code" => false,
|
225
|
+
|
226
|
+
"r_module" => nil,
|
227
|
+
"r_constant" => nil,
|
228
|
+
}
|
229
|
+
|
230
|
+
if l =~ /beginning-of-error-codes/ .. l =~ /end-of-error-codes/ then
|
231
|
+
result["is_error_code"] = true
|
232
|
+
end
|
233
|
+
|
234
|
+
l.strip!
|
235
|
+
md = l.match(/\A#define\s+(\w+)\s+([^\/]+)\s*(\/\*(.*)\*\/)?\Z/)
|
236
|
+
next unless md
|
237
|
+
|
238
|
+
# Name munging
|
239
|
+
c_define = md[1]
|
240
|
+
|
241
|
+
c_parts = c_define.gsub(/^SQLITE_/,'').split("_")
|
242
|
+
r_module = c_parts.shift
|
243
|
+
r_constant = c_parts.join("_")
|
244
|
+
|
245
|
+
|
246
|
+
# custom module naming so they are human readable
|
247
|
+
r_module = module_name_mapping.fetch(r_module) { |m| r_module.capitalize }
|
248
|
+
|
249
|
+
case c_define
|
250
|
+
when *version_codes
|
251
|
+
next
|
252
|
+
|
253
|
+
when *deprecated_codes
|
254
|
+
next
|
255
|
+
|
256
|
+
when *rtree_codes
|
257
|
+
r_module = "RTree"
|
258
|
+
r_constant = c_define
|
259
|
+
|
260
|
+
when *result_codes
|
261
|
+
r_module = "ResultCode"
|
262
|
+
r_constant = c_define.gsub(/^SQLITE_/,'')
|
263
|
+
|
264
|
+
when *authorizer_codes
|
265
|
+
r_module = "Authorizer"
|
266
|
+
r_constant = c_define.gsub(/^SQLITE_/,'')
|
267
|
+
|
268
|
+
when *text_encoding_codes
|
269
|
+
r_module = "TextEncoding"
|
270
|
+
r_constant = c_define.gsub(/^SQLITE_/,'')
|
271
|
+
|
272
|
+
when *data_type_codes
|
273
|
+
r_module = "DataType"
|
274
|
+
r_constant = c_define.gsub(/^SQLITE(3)?_/,'')
|
275
|
+
|
276
|
+
when *fts5_codes
|
277
|
+
r_module = "FTS5"
|
278
|
+
r_constant = c_define.gsub(/^FTS5_/,'')
|
279
|
+
|
280
|
+
when *ignore_codes
|
281
|
+
next
|
282
|
+
|
283
|
+
when /TESTCTRL/ # sqlite3 codes used in testing
|
284
|
+
next
|
285
|
+
|
286
|
+
when /^__/ # sqlite3 internal items
|
287
|
+
next
|
288
|
+
end
|
289
|
+
|
290
|
+
result["c_define"] = c_define
|
291
|
+
result["c_value"] = md[2].strip
|
292
|
+
if !md[4].nil? && (md[4].strip.length > 0) then
|
293
|
+
result["docstring"] = md[4].strip
|
294
|
+
end
|
295
|
+
result["r_module"] = r_module
|
296
|
+
result["r_constant"] = r_constant
|
297
|
+
|
298
|
+
defines << result
|
299
|
+
end
|
300
|
+
|
301
|
+
#
|
302
|
+
# rework defines into constants
|
303
|
+
#
|
304
|
+
CONSTANTS = defines.group_by{ |d| d["r_module"] }
|
305
|
+
|
138
306
|
fname = File.expand_path(File.join(File.dirname(__FILE__), "amalgalite_constants.c"))
|
307
|
+
|
308
|
+
|
139
309
|
File.open(fname, "w+") do |f|
|
140
310
|
f.puts "/* Generated by gen_constants.rb -- do not edit */"
|
141
311
|
f.puts
|
@@ -157,35 +327,25 @@ File.open(fname, "w+") do |f|
|
|
157
327
|
f.puts ' VALUE mC = rb_define_module_under( mas, "Constants");'
|
158
328
|
|
159
329
|
|
160
|
-
|
161
|
-
IO.readlines("sqlite3.h").each do |l|
|
162
|
-
if l =~ /beginning-of-error-codes/ .. l =~ /end-of-error-codes/ then
|
163
|
-
next if l =~ /of-error-codes/
|
164
|
-
l.strip!
|
165
|
-
md = l.match(/\A#define\s+(\w+)\s+(\d+)\s+\/\*(.*)\*\/\Z/)
|
166
|
-
error_code_lines[md[1]] = { 'value' => md[2].strip, 'meaning' => md[3].strip }
|
167
|
-
end
|
168
|
-
end
|
169
|
-
|
170
|
-
CONSTANTS.keys.sort.each do |klass|
|
171
|
-
const_set = CONSTANTS[klass]
|
330
|
+
CONSTANTS.keys.sort.each do |mod|
|
172
331
|
f.puts " /**"
|
173
|
-
f.puts " * module encapsulating the SQLite3 C extension constants for #{
|
332
|
+
f.puts " * module encapsulating the SQLite3 C extension constants for #{mod}"
|
174
333
|
f.puts " */"
|
175
|
-
f.puts " VALUE mC_#{
|
334
|
+
f.puts " VALUE mC_#{mod} = rb_define_module_under(mC, \"#{mod}\");"
|
176
335
|
f.puts
|
177
336
|
end
|
178
337
|
|
179
|
-
CONSTANTS.keys.sort.each do |
|
180
|
-
const_set = CONSTANTS[
|
181
|
-
const_set.
|
182
|
-
sql_const =
|
338
|
+
CONSTANTS.keys.sort.each do |mod|
|
339
|
+
const_set = CONSTANTS[mod]
|
340
|
+
const_set.sort_by { |c| c["c_define"] }.each do |result|
|
341
|
+
sql_const = result["c_define"]
|
183
342
|
const_doc = " /* no meaningful autogenerated documentation -- constant is self explanatory ?*/"
|
184
|
-
if
|
185
|
-
const_doc = " /* #{
|
343
|
+
if !result["docstring"].nil? then
|
344
|
+
const_doc = " /* #{result['c_value']} -- #{result['docstring']} */"
|
186
345
|
end
|
346
|
+
ruby_constant = result['r_constant']
|
187
347
|
f.puts const_doc
|
188
|
-
f.puts " rb_define_const(mC_#{
|
348
|
+
f.puts " rb_define_const(mC_#{mod}, \"#{ruby_constant}\", INT2FIX(#{sql_const}));"
|
189
349
|
f.puts
|
190
350
|
end
|
191
351
|
end
|