mirror of
https://github.com/sqlite/sqlite.git
synced 2026-01-06 08:01:16 +03:00
Expose a JS-friendly subset of sqlite3_config() to JS, with the notable caveats that (1) setting up the JS bindings requires starting the library, making sqlite3_config() illegal to call and (2) calling sqlite3_shutdown() in order to make it legal to call sqlite3_config() may undo certain JS-side library initialization. Move sqlite3_(de)serialize() into the int64-mode-only bindings because of their int64 args.
FossilOrigin-Name: 62e0c931ac952219f68e22d64e20836781bf330b4581e4662266172a97c9289b
This commit is contained in:
@@ -98,11 +98,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],
|
||||
["sqlite3_db_name", "string", "sqlite3*", "int"],
|
||||
["sqlite3_db_status", "int", "sqlite3*", "int", "*", "*", "int"],
|
||||
["sqlite3_deserialize", "int", "sqlite3*", "string", "*", "i64", "i64", "int"]
|
||||
/* Careful! Short version: de/serialize() are problematic because they
|
||||
might use a different allocator than the user for managing the
|
||||
deserialized block. de/serialize() are ONLY safe to use with
|
||||
sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. */,
|
||||
["sqlite3_errcode", "int", "sqlite3*"],
|
||||
["sqlite3_errmsg", "string", "sqlite3*"],
|
||||
["sqlite3_error_offset", "int", "sqlite3*"],
|
||||
@@ -161,9 +156,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_result_subtype", undefined, "sqlite3_value*", "int"],
|
||||
["sqlite3_result_text", undefined, "sqlite3_context*", "string", "int", "*"],
|
||||
["sqlite3_result_zeroblob", undefined, "sqlite3_context*", "int"],
|
||||
["sqlite3_serialize","*", "sqlite3*", "string", "*", "int"],
|
||||
/* sqlite3_set_authorizer() requires a hand-written binding for
|
||||
string conversions, so is defined elsewhere. */
|
||||
["sqlite3_set_auxdata", undefined, "sqlite3_context*", "int", "*", "*"/* => v(*) */],
|
||||
["sqlite3_shutdown", undefined],
|
||||
["sqlite3_sourceid", "string"],
|
||||
@@ -238,6 +230,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_create_module_v2", "int",
|
||||
["sqlite3*","string","sqlite3_module*","*","*"]],
|
||||
["sqlite3_declare_vtab", "int", ["sqlite3*", "string:flexible"]],
|
||||
["sqlite3_deserialize", "int", "sqlite3*", "string", "*", "i64", "i64", "int"]
|
||||
/* Careful! Short version: de/serialize() are problematic because they
|
||||
might use a different allocator than the user for managing the
|
||||
deserialized block. de/serialize() are ONLY safe to use with
|
||||
sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. */,
|
||||
["sqlite3_drop_modules", "int", ["sqlite3*", "**"]],
|
||||
["sqlite3_last_insert_rowid", "i64", ["sqlite3*"]],
|
||||
["sqlite3_malloc64", "*","i64"],
|
||||
@@ -246,6 +243,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
["sqlite3_realloc64", "*","*", "i64"],
|
||||
["sqlite3_result_int64", undefined, "*", "i64"],
|
||||
["sqlite3_result_zeroblob64", "int", "*", "i64"],
|
||||
["sqlite3_serialize","*", "sqlite3*", "string", "*", "int"],
|
||||
/* sqlite3_set_authorizer() requires a hand-written binding for
|
||||
string conversions, so is defined elsewhere. */
|
||||
["sqlite3_set_last_insert_rowid", undefined, ["sqlite3*", "i64"]],
|
||||
["sqlite3_status64", "int", "int", "*", "*", "int"],
|
||||
["sqlite3_total_changes64", "i64", ["sqlite3*"]],
|
||||
@@ -851,6 +851,52 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
};
|
||||
}/* sqlite3_set_authorizer() */
|
||||
|
||||
{/* sqlite3_config() */
|
||||
/**
|
||||
Wraps a small subset of the C API's sqlite3_config() options.
|
||||
Unsupported options trigger the return of capi.SQLITE_NOTFOUND.
|
||||
Passing fewer than 2 arguments triggers return of
|
||||
capi.SQLITE_MISUSE.
|
||||
*/
|
||||
capi.sqlite3_config = function(op, ...args){
|
||||
if(arguments.length<2) return capi.SQLITE_MISUSE;
|
||||
switch(op){
|
||||
case capi.SQLITE_CONFIG_COVERING_INDEX_SCAN: // 20 /* int */
|
||||
case capi.SQLITE_CONFIG_MEMSTATUS:// 9 /* boolean */
|
||||
case capi.SQLITE_CONFIG_SMALL_MALLOC: // 27 /* boolean */
|
||||
case capi.SQLITE_CONFIG_SORTERREF_SIZE: // 28 /* int nByte */
|
||||
case capi.SQLITE_CONFIG_STMTJRNL_SPILL: // 26 /* int nByte */
|
||||
case capi.SQLITE_CONFIG_URI:// 17 /* int */
|
||||
return wasm.exports.sqlite3_wasm_config_i(op, args[0]);
|
||||
case capi.SQLITE_CONFIG_LOOKASIDE: // 13 /* int int */
|
||||
return wasm.exports.sqlite3_wasm_config_ii(op, args[0], args[1]);
|
||||
case capi.SQLITE_CONFIG_MEMDB_MAXSIZE: // 29 /* sqlite3_int64 */
|
||||
return wasm.exports.sqlite3_wasm_config_j(op, args[0]);
|
||||
case capi.SQLITE_CONFIG_GETMALLOC: // 5 /* sqlite3_mem_methods* */
|
||||
case capi.SQLITE_CONFIG_GETMUTEX: // 11 /* sqlite3_mutex_methods* */
|
||||
case capi.SQLITE_CONFIG_GETPCACHE2: // 19 /* sqlite3_pcache_methods2* */
|
||||
case capi.SQLITE_CONFIG_GETPCACHE: // 15 /* no-op */
|
||||
case capi.SQLITE_CONFIG_HEAP: // 8 /* void*, int nByte, int min */
|
||||
case capi.SQLITE_CONFIG_LOG: // 16 /* xFunc, void* */
|
||||
case capi.SQLITE_CONFIG_MALLOC:// 4 /* sqlite3_mem_methods* */
|
||||
case capi.SQLITE_CONFIG_MMAP_SIZE: // 22 /* sqlite3_int64, sqlite3_int64 */
|
||||
case capi.SQLITE_CONFIG_MULTITHREAD: // 2 /* nil */
|
||||
case capi.SQLITE_CONFIG_MUTEX: // 10 /* sqlite3_mutex_methods* */
|
||||
case capi.SQLITE_CONFIG_PAGECACHE: // 7 /* void*, int sz, int N */
|
||||
case capi.SQLITE_CONFIG_PCACHE2: // 18 /* sqlite3_pcache_methods2* */
|
||||
case capi.SQLITE_CONFIG_PCACHE: // 14 /* no-op */
|
||||
case capi.SQLITE_CONFIG_PCACHE_HDRSZ: // 24 /* int *psz */
|
||||
case capi.SQLITE_CONFIG_PMASZ: // 25 /* unsigned int szPma */
|
||||
case capi.SQLITE_CONFIG_SERIALIZED: // 3 /* nil */
|
||||
case capi.SQLITE_CONFIG_SINGLETHREAD: // 1 /* nil */:
|
||||
case capi.SQLITE_CONFIG_SQLLOG: // 21 /* xSqllog, void* */
|
||||
case capi.SQLITE_CONFIG_WIN32_HEAPSIZE: // 23 /* int nByte */
|
||||
default:
|
||||
return capi.SQLITE_NOTFOUND;
|
||||
}
|
||||
};
|
||||
}/* sqlite3_config() */
|
||||
|
||||
{/* Import C-level constants and structs... */
|
||||
const cJson = wasm.xCall('sqlite3_wasm_enum_json');
|
||||
if(!cJson){
|
||||
@@ -860,7 +906,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
wasm.ctype = JSON.parse(wasm.cstrToJs(cJson));
|
||||
//console.debug('wasm.ctype length =',wasm.cstrlen(cJson));
|
||||
const defineGroups = ['access', 'authorizer',
|
||||
'blobFinalizers', 'dataTypes',
|
||||
'blobFinalizers', 'config', 'dataTypes',
|
||||
'dbConfig', 'dbStatus',
|
||||
'encodings', 'fcntl', 'flock', 'ioCap',
|
||||
'limits', 'openFlags',
|
||||
|
||||
@@ -455,6 +455,38 @@ const char * sqlite3_wasm_enum_json(void){
|
||||
out("\"SQLITE_STATIC\":0, \"SQLITE_TRANSIENT\":-1");
|
||||
} _DefGroup;
|
||||
|
||||
DefGroup(config){
|
||||
DefInt(SQLITE_CONFIG_SINGLETHREAD);
|
||||
DefInt(SQLITE_CONFIG_MULTITHREAD);
|
||||
DefInt(SQLITE_CONFIG_SERIALIZED);
|
||||
DefInt(SQLITE_CONFIG_MALLOC);
|
||||
DefInt(SQLITE_CONFIG_GETMALLOC);
|
||||
DefInt(SQLITE_CONFIG_SCRATCH);
|
||||
DefInt(SQLITE_CONFIG_PAGECACHE);
|
||||
DefInt(SQLITE_CONFIG_HEAP);
|
||||
DefInt(SQLITE_CONFIG_MEMSTATUS);
|
||||
DefInt(SQLITE_CONFIG_MUTEX);
|
||||
DefInt(SQLITE_CONFIG_GETMUTEX);
|
||||
/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
|
||||
DefInt(SQLITE_CONFIG_LOOKASIDE);
|
||||
DefInt(SQLITE_CONFIG_PCACHE);
|
||||
DefInt(SQLITE_CONFIG_GETPCACHE);
|
||||
DefInt(SQLITE_CONFIG_LOG);
|
||||
DefInt(SQLITE_CONFIG_URI);
|
||||
DefInt(SQLITE_CONFIG_PCACHE2);
|
||||
DefInt(SQLITE_CONFIG_GETPCACHE2);
|
||||
DefInt(SQLITE_CONFIG_COVERING_INDEX_SCAN);
|
||||
DefInt(SQLITE_CONFIG_SQLLOG);
|
||||
DefInt(SQLITE_CONFIG_MMAP_SIZE);
|
||||
DefInt(SQLITE_CONFIG_WIN32_HEAPSIZE);
|
||||
DefInt(SQLITE_CONFIG_PCACHE_HDRSZ);
|
||||
DefInt(SQLITE_CONFIG_PMASZ);
|
||||
DefInt(SQLITE_CONFIG_STMTJRNL_SPILL);
|
||||
DefInt(SQLITE_CONFIG_SMALL_MALLOC);
|
||||
DefInt(SQLITE_CONFIG_SORTERREF_SIZE);
|
||||
DefInt(SQLITE_CONFIG_MEMDB_MAXSIZE);
|
||||
} _DefGroup;
|
||||
|
||||
DefGroup(dataTypes) {
|
||||
DefInt(SQLITE_INTEGER);
|
||||
DefInt(SQLITE_FLOAT);
|
||||
@@ -1491,6 +1523,42 @@ int sqlite3_wasm_db_config_s(sqlite3 *pDb, int op, const char *zArg){
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** This function is NOT part of the sqlite3 public API. It is strictly
|
||||
** for use by the sqlite project's own JS/WASM bindings.
|
||||
**
|
||||
** Binding for combinations of sqlite3_config() arguments which take
|
||||
** a single integer argument.
|
||||
*/
|
||||
SQLITE_WASM_KEEP
|
||||
int sqlite3_wasm_config_i(int op, int arg){
|
||||
return sqlite3_config(op, arg);
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is NOT part of the sqlite3 public API. It is strictly
|
||||
** for use by the sqlite project's own JS/WASM bindings.
|
||||
**
|
||||
** Binding for combinations of sqlite3_config() arguments which take
|
||||
** two int arguments.
|
||||
*/
|
||||
SQLITE_WASM_KEEP
|
||||
int sqlite3_wasm_config_ii(int op, int arg1, int arg2){
|
||||
return sqlite3_config(op, arg1, arg2);
|
||||
}
|
||||
|
||||
/*
|
||||
** This function is NOT part of the sqlite3 public API. It is strictly
|
||||
** for use by the sqlite project's own JS/WASM bindings.
|
||||
**
|
||||
** Binding for combinations of sqlite3_config() arguments which take
|
||||
** a single i64 argument.
|
||||
*/
|
||||
SQLITE_WASM_KEEP
|
||||
int sqlite3_wasm_config_j(int op, sqlite3_int64 arg){
|
||||
return sqlite3_config(op, arg);
|
||||
}
|
||||
|
||||
#if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS)
|
||||
#include <emscripten/wasmfs.h>
|
||||
|
||||
|
||||
@@ -344,6 +344,38 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
T.g('Basic sanity checks')
|
||||
.t({
|
||||
name:'sqlite3_config()',
|
||||
test:function(sqlite3){
|
||||
for(const k of [
|
||||
'SQLITE_CONFIG_GETMALLOC', 'SQLITE_CONFIG_URI'
|
||||
]){
|
||||
T.assert(capi[k] > 0);
|
||||
}
|
||||
T.assert(capi.SQLITE_MISUSE===capi.sqlite3_config(
|
||||
capi.SQLITE_CONFIG_URI, 1
|
||||
), "MISUSE because the library has already been initialized.");
|
||||
T.assert(capi.SQLITE_MISUSE === capi.sqlite3_config(
|
||||
// not enough args
|
||||
capi.SQLITE_CONFIG_GETMALLOC
|
||||
));
|
||||
T.assert(capi.SQLITE_NOTFOUND === capi.sqlite3_config(
|
||||
// unhandled-in-JS config option
|
||||
capi.SQLITE_CONFIG_GETMALLOC, 1
|
||||
));
|
||||
if(0){
|
||||
log("We cannot _fully_ test sqlite3_config() after the library",
|
||||
"has been initialized (which it necessarily has been to",
|
||||
"set up various bindings) and we cannot shut it down ",
|
||||
"without losing the VFS registrations.");
|
||||
T.assert(0 === capi.sqlite3_config(
|
||||
capi.SQLITE_CONFIG_URI, 1
|
||||
));
|
||||
}
|
||||
}
|
||||
})/*sqlite3_config()*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
.t({
|
||||
name: "JS wasm-side allocator",
|
||||
test: function(sqlite3){
|
||||
@@ -422,6 +454,7 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
assert(0===capi.sqlite3_strlike("%.txt", "foo.txt", 0)).
|
||||
assert(0!==capi.sqlite3_strlike("%.txt", "foo.xtx", 0));
|
||||
})
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
;/*end of basic sanity checks*/
|
||||
|
||||
|
||||
Reference in New Issue
Block a user