aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/api/sqlite3-api-glue.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm/api/sqlite3-api-glue.js')
-rw-r--r--ext/wasm/api/sqlite3-api-glue.js808
1 files changed, 592 insertions, 216 deletions
diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js
index e98393df6..7b5fa1181 100644
--- a/ext/wasm/api/sqlite3-api-glue.js
+++ b/ext/wasm/api/sqlite3-api-glue.js
@@ -24,6 +24,282 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
self.WhWasmUtilInstaller(wasm);
delete self.WhWasmUtilInstaller;
+ {
+ /**
+ Find a mapping for SQLITE_WASM_DEALLOC, which the API
+ guarantees is a WASM pointer to the same underlying function as
+ wasm.dealloc() (noting that wasm.dealloc() is permitted to be a
+ JS wrapper around the WASM function). There is unfortunately no
+ O(1) algorithm for finding this pointer: we have to walk the
+ WASM indirect function table to find it. However, experience
+ indicates that that particular function is always very close to
+ the front of the table (it's been entry #3 in all relevant
+ tests).
+ */
+ const dealloc = wasm.exports[sqlite3.config.deallocExportName];
+ const nFunc = wasm.functionTable().length;
+ let i;
+ for(i = 0; i < nFunc; ++i){
+ const e = wasm.functionEntry(i);
+ if(dealloc === e){
+ capi.SQLITE_WASM_DEALLOC = i;
+ break;
+ }
+ }
+ if(dealloc !== wasm.functionEntry(capi.SQLITE_WASM_DEALLOC)){
+ toss("Internal error: cannot find function pointer for SQLITE_WASM_DEALLOC.");
+ }
+ }
+
+ /**
+ Signatures for the WASM-exported C-side functions. Each entry
+ is an array with 2+ elements:
+
+ [ "c-side name",
+ "result type" (wasm.xWrap() syntax),
+ [arg types in xWrap() syntax]
+ // ^^^ this needn't strictly be an array: it can be subsequent
+ // elements instead: [x,y,z] is equivalent to x,y,z
+ ]
+
+ Note that support for the API-specific data types in the
+ result/argument type strings gets plugged in at a later phase in
+ the API initialization process.
+ */
+ wasm.bindingSignatures = [
+ // Please keep these sorted by function name!
+ ["sqlite3_aggregate_context","void*", "sqlite3_context*", "int"],
+ /* sqlite3_bind_blob() and sqlite3_bind_text() have hand-written
+ bindings to permit more flexible inputs. */
+ ["sqlite3_bind_double","int", "sqlite3_stmt*", "int", "f64"],
+ ["sqlite3_bind_int","int", "sqlite3_stmt*", "int", "int"],
+ ["sqlite3_bind_null",undefined, "sqlite3_stmt*", "int"],
+ ["sqlite3_bind_parameter_count", "int", "sqlite3_stmt*"],
+ ["sqlite3_bind_parameter_index","int", "sqlite3_stmt*", "string"],
+ ["sqlite3_bind_pointer", "int",
+ "sqlite3_stmt*", "int", "*", "string:static", "*"],
+ ["sqlite3_busy_handler","int", [
+ "sqlite3*",
+ new wasm.xWrap.FuncPtrAdapter({
+ signature: 'i(pi)',
+ contextKey: (argIndex,argv)=>'sqlite3@'+argv[0]
+ }),
+ "*"
+ ]],
+ ["sqlite3_busy_timeout","int", "sqlite3*", "int"],
+ ["sqlite3_close_v2", "int", "sqlite3*"],
+ ["sqlite3_changes", "int", "sqlite3*"],
+ ["sqlite3_clear_bindings","int", "sqlite3_stmt*"],
+ ["sqlite3_collation_needed", "int", "sqlite3*", "*", "*"/*=>v(ppis)*/],
+ ["sqlite3_column_blob","*", "sqlite3_stmt*", "int"],
+ ["sqlite3_column_bytes","int", "sqlite3_stmt*", "int"],
+ ["sqlite3_column_count", "int", "sqlite3_stmt*"],
+ ["sqlite3_column_double","f64", "sqlite3_stmt*", "int"],
+ ["sqlite3_column_int","int", "sqlite3_stmt*", "int"],
+ ["sqlite3_column_name","string", "sqlite3_stmt*", "int"],
+ ["sqlite3_column_text","string", "sqlite3_stmt*", "int"],
+ ["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
+ ["sqlite3_column_value","sqlite3_value*", "sqlite3_stmt*", "int"],
+ ["sqlite3_compileoption_get", "string", "int"],
+ ["sqlite3_compileoption_used", "int", "string"],
+ ["sqlite3_complete", "int", "string:flexible"],
+ /* sqlite3_create_function(), sqlite3_create_function_v2(), and
+ sqlite3_create_window_function() use hand-written bindings to
+ simplify handling of their function-type arguments. */
+ /* sqlite3_create_collation() and sqlite3_create_collation_v2()
+ use hand-written bindings to simplify passing of the callback
+ function.
+ ["sqlite3_create_collation", "int",
+ "sqlite3*", "string", "int",//SQLITE_UTF8 is the only legal value
+ "*", "*"],
+ ["sqlite3_create_collation_v2", "int",
+ "sqlite3*", "string", "int",//SQLITE_UTF8 is the only legal value
+ "*", "*", "*"],
+ */
+ ["sqlite3_data_count", "int", "sqlite3_stmt*"],
+ ["sqlite3_db_filename", "string", "sqlite3*", "string"],
+ ["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],
+ ["sqlite3_db_name", "string", "sqlite3*", "int"],
+ ["sqlite3_db_status", "int", "sqlite3*", "int", "*", "*", "int"],
+ ["sqlite3_errcode", "int", "sqlite3*"],
+ ["sqlite3_errmsg", "string", "sqlite3*"],
+ ["sqlite3_error_offset", "int", "sqlite3*"],
+ ["sqlite3_errstr", "string", "int"],
+ /*["sqlite3_exec", "int", "sqlite3*", "string", "*", "*", "**"
+ Handled seperately to perform translation of the callback
+ into a WASM-usable one. ],*/
+ ["sqlite3_expanded_sql", "string", "sqlite3_stmt*"],
+ ["sqlite3_extended_errcode", "int", "sqlite3*"],
+ ["sqlite3_extended_result_codes", "int", "sqlite3*", "int"],
+ ["sqlite3_file_control", "int", "sqlite3*", "string", "int", "*"],
+ ["sqlite3_finalize", "int", "sqlite3_stmt*"],
+ ["sqlite3_free", undefined,"*"],
+ ["sqlite3_get_auxdata", "*", "sqlite3_context*", "int"],
+ ["sqlite3_initialize", undefined],
+ /*["sqlite3_interrupt", undefined, "sqlite3*"
+ ^^^ we cannot actually currently support this because JS is
+ single-threaded and we don't have a portable way to access a DB
+ from 2 SharedWorkers concurrently. ],*/
+ ["sqlite3_keyword_count", "int"],
+ ["sqlite3_keyword_name", "int", ["int", "**", "*"]],
+ ["sqlite3_keyword_check", "int", ["string", "int"]],
+ ["sqlite3_libversion", "string"],
+ ["sqlite3_libversion_number", "int"],
+ ["sqlite3_limit", "int", ["sqlite3*", "int", "int"]],
+ ["sqlite3_malloc", "*","int"],
+ ["sqlite3_open", "int", "string", "*"],
+ ["sqlite3_open_v2", "int", "string", "*", "int", "string"],
+ /* sqlite3_prepare_v2() and sqlite3_prepare_v3() are handled
+ separately due to us requiring two different sets of semantics
+ for those, depending on how their SQL argument is provided. */
+ /* sqlite3_randomness() uses a hand-written wrapper to extend
+ the range of supported argument types. */
+ [
+ "sqlite3_progress_handler", undefined, [
+ "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({
+ name: 'xProgressHandler',
+ signature: 'i(p)',
+ bindScope: 'context',
+ contextKey: (argIndex,argv)=>'sqlite3@'+argv[0]
+ }), "*"
+ ]
+ ],
+ ["sqlite3_realloc", "*","*","int"],
+ ["sqlite3_reset", "int", "sqlite3_stmt*"],
+ ["sqlite3_result_blob", undefined, "sqlite3_context*", "*", "int", "*"],
+ ["sqlite3_result_double", undefined, "sqlite3_context*", "f64"],
+ ["sqlite3_result_error", undefined, "sqlite3_context*", "string", "int"],
+ ["sqlite3_result_error_code", undefined, "sqlite3_context*", "int"],
+ ["sqlite3_result_error_nomem", undefined, "sqlite3_context*"],
+ ["sqlite3_result_error_toobig", undefined, "sqlite3_context*"],
+ ["sqlite3_result_int", undefined, "sqlite3_context*", "int"],
+ ["sqlite3_result_null", undefined, "sqlite3_context*"],
+ ["sqlite3_result_pointer", undefined,
+ "sqlite3_context*", "*", "string:static", "*"],
+ ["sqlite3_result_subtype", undefined, "sqlite3_value*", "int"],
+ ["sqlite3_result_text", undefined, "sqlite3_context*", "string", "int", "*"],
+ ["sqlite3_result_zeroblob", undefined, "sqlite3_context*", "int"],
+ ["sqlite3_set_auxdata", undefined, "sqlite3_context*", "int", "*", "*"/* => v(*) */],
+ ["sqlite3_shutdown", undefined],
+ ["sqlite3_sourceid", "string"],
+ ["sqlite3_sql", "string", "sqlite3_stmt*"],
+ ["sqlite3_status", "int", "int", "*", "*", "int"],
+ ["sqlite3_step", "int", "sqlite3_stmt*"],
+ ["sqlite3_stmt_isexplain", "int", ["sqlite3_stmt*"]],
+ ["sqlite3_stmt_readonly", "int", ["sqlite3_stmt*"]],
+ ["sqlite3_stmt_status", "int", "sqlite3_stmt*", "int", "int"],
+ ["sqlite3_strglob", "int", "string","string"],
+ ["sqlite3_stricmp", "int", "string", "string"],
+ ["sqlite3_strlike", "int", "string", "string","int"],
+ ["sqlite3_strnicmp", "int", "string", "string", "int"],
+ ["sqlite3_table_column_metadata", "int",
+ "sqlite3*", "string", "string", "string",
+ "**", "**", "*", "*", "*"],
+ ["sqlite3_total_changes", "int", "sqlite3*"],
+ ["sqlite3_trace_v2", "int", "sqlite3*", "int",
+ new wasm.xWrap.FuncPtrAdapter({
+ name: 'sqlite3_trace_v2::callback',
+ signature: 'i(ippp)',
+ contextKey: (argIndex, argv)=>'sqlite3@'+argv[0]
+ }), "*"],
+ ["sqlite3_txn_state", "int", ["sqlite3*","string"]],
+ /* Note that sqlite3_uri_...() have very specific requirements for
+ their first C-string arguments, so we cannot perform any value
+ conversion on those. */
+ ["sqlite3_uri_boolean", "int", "sqlite3_filename", "string", "int"],
+ ["sqlite3_uri_key", "string", "sqlite3_filename", "int"],
+ ["sqlite3_uri_parameter", "string", "sqlite3_filename", "string"],
+ ["sqlite3_user_data","void*", "sqlite3_context*"],
+ ["sqlite3_value_blob", "*", "sqlite3_value*"],
+ ["sqlite3_value_bytes","int", "sqlite3_value*"],
+ ["sqlite3_value_double","f64", "sqlite3_value*"],
+ ["sqlite3_value_dup", "sqlite3_value*", "sqlite3_value*"],
+ ["sqlite3_value_free", undefined, "sqlite3_value*"],
+ ["sqlite3_value_frombind", "int", "sqlite3_value*"],
+ ["sqlite3_value_int","int", "sqlite3_value*"],
+ ["sqlite3_value_nochange", "int", "sqlite3_value*"],
+ ["sqlite3_value_numeric_type", "int", "sqlite3_value*"],
+ ["sqlite3_value_pointer", "*", "sqlite3_value*", "string:static"],
+ ["sqlite3_value_subtype", "int", "sqlite3_value*"],
+ ["sqlite3_value_text", "string", "sqlite3_value*"],
+ ["sqlite3_value_type", "int", "sqlite3_value*"],
+ ["sqlite3_vfs_find", "*", "string"],
+ ["sqlite3_vfs_register", "int", "sqlite3_vfs*", "int"],
+ ["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
+ ]/*wasm.bindingSignatures*/;
+
+ if(false && wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
+ /* ^^^ "the problem" is that this is an option feature and the
+ build-time function-export list does not currently take
+ optional features into account. */
+ wasm.bindingSignatures.push(["sqlite3_normalized_sql", "string", "sqlite3_stmt*"]);
+ }
+
+ /**
+ Functions which require BigInt (int64) support are separated from
+ the others because we need to conditionally bind them or apply
+ dummy impls, depending on the capabilities of the environment.
+
+ Note that not all of these functions directly require int64
+ but are only for use with APIs which require int64. For example,
+ the vtab-related functions.
+ */
+ wasm.bindingSignatures.int64 = [
+ ["sqlite3_bind_int64","int", ["sqlite3_stmt*", "int", "i64"]],
+ ["sqlite3_changes64","i64", ["sqlite3*"]],
+ ["sqlite3_column_int64","i64", ["sqlite3_stmt*", "int"]],
+ ["sqlite3_create_module", "int",
+ ["sqlite3*","string","sqlite3_module*","*"]],
+ ["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"],
+ ["sqlite3_msize", "i64", "*"],
+ ["sqlite3_overload_function", "int", ["sqlite3*","string","int"]],
+ ["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*"]],
+ ["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]],
+ ["sqlite3_value_int64","i64", "sqlite3_value*"],
+ ["sqlite3_vtab_collation","string","sqlite3_index_info*","int"],
+ ["sqlite3_vtab_distinct","int", "sqlite3_index_info*"],
+ ["sqlite3_vtab_in","int", "sqlite3_index_info*", "int", "int"],
+ ["sqlite3_vtab_in_first", "int", "sqlite3_value*", "**"],
+ ["sqlite3_vtab_in_next", "int", "sqlite3_value*", "**"],
+ /*["sqlite3_vtab_config" is variadic and requires a hand-written
+ proxy.] */
+ ["sqlite3_vtab_nochange","int", "sqlite3_context*"],
+ ["sqlite3_vtab_on_conflict","int", "sqlite3*"],
+ ["sqlite3_vtab_rhs_value","int", "sqlite3_index_info*", "int", "**"]
+ ];
+
+ /**
+ Functions which are intended solely for API-internal use by the
+ WASM components, not client code. These get installed into
+ sqlite3.wasm. Some of them get exposed to clients via variants
+ named sqlite3_js_...().
+ */
+ wasm.bindingSignatures.wasm = [
+ ["sqlite3_wasm_db_reset", "int", "sqlite3*"],
+ ["sqlite3_wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"],
+ ["sqlite3_wasm_vfs_create_file", "int",
+ "sqlite3_vfs*","string","*", "int"],
+ ["sqlite3_wasm_vfs_unlink", "int", "sqlite3_vfs*","string"]
+ ];
+
/**
Install JS<->C struct bindings for the non-opaque struct types we
need... */
@@ -39,9 +315,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
{/* Convert Arrays and certain TypedArrays to strings for
'string:flexible'-type arguments */
- const xString = wasm.xWrap.argAdapter('string');
+ const __xString = wasm.xWrap.argAdapter('string');
wasm.xWrap.argAdapter(
- 'string:flexible', (v)=>xString(util.flexibleString(v))
+ 'string:flexible', (v)=>__xString(util.flexibleString(v))
);
/**
@@ -71,12 +347,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
if(wasm.isPtr(v)) return v;
v = ''+v;
let rc = this[v];
- return rc || (rc = this[v] = wasm.allocCString(v));
+ return rc || (this[v] = wasm.allocCString(v));
}.bind(Object.create(null))
);
}/* special-case string-type argument conversions */
-
- if(1){// WhWasmUtil.xWrap() bindings...
+
+ if(1){// wasm.xWrap() bindings...
/**
Add some descriptive xWrap() aliases for '*' intended to (A)
initially improve readability/correctness of capi.signatures
@@ -116,19 +392,22 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
VFS in many contexts. We specifically do not want that
behavior here. */
return capi.sqlite3_vfs_find(v)
- || sqlite3.SQLite3Error.toss("Unknown sqlite3_vfs name:",v);
+ || sqlite3.SQLite3Error.toss(
+ capi.SQLITE_NOTFOUND,
+ "Unknown sqlite3_vfs name:", v
+ );
}
return aPtr((v instanceof (capi.sqlite3_vfs || nilType))
? v.pointer : v);
});
- const rPtr = wasm.xWrap.resultAdapter('*');
- wasm.xWrap.resultAdapter('sqlite3*', rPtr)
- ('sqlite3_context*', rPtr)
- ('sqlite3_stmt*', rPtr)
- ('sqlite3_value*', rPtr)
- ('sqlite3_vfs*', rPtr)
- ('void*', rPtr);
+ const __xRcPtr = wasm.xWrap.resultAdapter('*');
+ wasm.xWrap.resultAdapter('sqlite3*', __xRcPtr)
+ ('sqlite3_context*', __xRcPtr)
+ ('sqlite3_stmt*', __xRcPtr)
+ ('sqlite3_value*', __xRcPtr)
+ ('sqlite3_vfs*', __xRcPtr)
+ ('void*', __xRcPtr);
/**
Populate api object with sqlite3_...() by binding the "raw" wasm
@@ -142,10 +421,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
/* For C API functions which cannot work properly unless
- wasm.bigIntEnabled is true, install a bogus impl which
- throws if called when bigIntEnabled is false. */
+ wasm.bigIntEnabled is true, install a bogus impl which throws
+ if called when bigIntEnabled is false. The alternative would be
+ to elide these functions altogether, which seems likely to
+ cause more confusion. */
const fI64Disabled = function(fname){
- return ()=>toss(fname+"() disabled due to lack",
+ return ()=>toss(fname+"() is unavailable due to lack",
"of BigInt support in this build.");
};
for(const e of wasm.bindingSignatures.int64){
@@ -166,9 +447,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
Sets the given db's error state. Accepts:
- (sqlite3*, int code, string msg)
- - (sqlite3*, Error [,string msg])
+ - (sqlite3*, Error e [,string msg = ''+e])
- If passed a WasmAllocError, the message is ingored and the
+ If passed a WasmAllocError, the message is ignored and the
result code is SQLITE_NOMEM. If passed any other Error type,
the result code defaults to SQLITE_ERROR unless the Error
object has a resultCode property, in which case that is used
@@ -183,7 +464,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
resultCode = capi.SQLITE_NOMEM;
message = 0 /*avoid allocating message string*/;
}else if(resultCode instanceof Error){
- message = message || resultCode.message;
+ message = message || ''+resultCode;
resultCode = (resultCode.resultCode || capi.SQLITE_ERROR);
}
return __db_err(pDb, resultCode, message);
@@ -207,22 +488,58 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
(1===n?"":'s')+".");
};
- if(1){/* Bindings for sqlite3_create_collation() */
+ /** Code duplication reducer for functions which take an encoding
+ argument and require SQLITE_UTF8. Sets the db error code to
+ SQLITE_FORMAT and returns that code. */
+ const __errEncoding = (pDb)=>{
+ return util.sqlite3_wasm_db_error(
+ pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding."
+ );
+ };
+ if(1){/* Bindings for sqlite3_create_collation[_v2]() */
+ const __collationContextKey = (argIndex,argv)=>{
+ return 'argv['+argIndex+']:sqlite3@'+argv[0]+
+ ':'+wasm.cstrToJs(argv[1]).toLowerCase()
+ };
const __ccv2 = wasm.xWrap(
'sqlite3_create_collation_v2', 'int',
- 'sqlite3*','string','int','*','*','*'
- /* int(*xCompare)(void*,int,const void*,int,const void*) */
- /* void(*xDestroy(void*) */);
+ 'sqlite3*','string','int','*',
+ new wasm.xWrap.FuncPtrAdapter({
+ /* int(*xCompare)(void*,int,const void*,int,const void*) */
+ name: 'sqlite3_create_collation_v2::xCompare',
+ signature: 'i(pipip)',
+ bindScope: 'context',
+ contextKey: __collationContextKey
+ }),
+ new wasm.xWrap.FuncPtrAdapter({
+ /* void(*xDestroy(void*) */
+ name: 'sqlite3_create_collation_v2::xDestroy',
+ signature: 'v(p)',
+ bindScope: 'context',
+ contextKey: __collationContextKey
+ })
+ );
/**
Works exactly like C's sqlite3_create_collation_v2() except that:
- 1) It permits its two function arguments to be JS functions,
- for which it will install WASM-bound proxies.
+ 1) It returns capi.SQLITE_FORMAT if the 3rd argument contains
+ any encoding-related value other than capi.SQLITE_UTF8. No
+ other encodings are supported. As a special case, if the
+ bottom 4 bits of that argument are 0, SQLITE_UTF8 is
+ assumed.
- 2) It returns capi.SQLITE_FORMAT if the 3rd argument is not
- capi.SQLITE_UTF8. No other encodings are supported.
+ 2) It accepts JS functions for its function-pointer arguments,
+ for which it will install WASM-bound proxies. The bindings
+ are "permanent," in that they will stay in the WASM environment
+ until it shuts down unless the client calls this again with the
+ same collation name and a value of 0 or null for the
+ the function pointer(s).
+
+ For consistency with the C API, it requires the same number of
+ arguments. It returns capi.SQLITE_MISUSE if passed any other
+ argument count.
Returns 0 on success, non-0 on error, in which case the error
state of pDb (of type `sqlite3*` or argument-convertible to it)
@@ -230,24 +547,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
*/
capi.sqlite3_create_collation_v2 = function(pDb,zName,eTextRep,pArg,xCompare,xDestroy){
if(6!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_create_collation_v2', 6);
- else if(capi.SQLITE_UTF8!==eTextRep){
- return util.sqlite3_wasm_db_error(
- pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding."
- );
+ else if( 0 === (eTextRep & 0xf) ){
+ eTextRep |= capi.SQLITE_UTF8;
+ }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
+ return __errEncoding(pDb);
}
let rc, pfCompare, pfDestroy;
- try{
- if(xCompare instanceof Function){
- pfCompare = wasm.installFunction(xCompare, 'i(pipip)');
- }
- if(xDestroy instanceof Function){
- pfDestroy = wasm.installFunction(xDestroy, 'v(p)');
- }
- rc = __ccv2(pDb, zName, eTextRep, pArg,
- pfCompare || xCompare, pfDestroy || xDestroy);
+ try{
+ rc = __ccv2(pDb, zName, eTextRep, pArg, xCompare, xDestroy);
}catch(e){
- if(pfCompare) wasm.uninstallFunction(pfCompare);
- if(pfDestroy) wasm.uninstallFunction(pfDestroy);
rc = util.sqlite3_wasm_db_error(pDb, e);
}
return rc;
@@ -257,19 +565,22 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
return (5===arguments.length)
? capi.sqlite3_create_collation_v2(pDb,zName,eTextRep,pArg,xCompare,0)
: __dbArgcMismatch(pDb, 'sqlite3_create_collation', 5);
- }
-
+ };
}/*sqlite3_create_collation() and friends*/
if(1){/* Special-case handling of sqlite3_exec() */
const __exec = wasm.xWrap("sqlite3_exec", "int",
- ["sqlite3*", "string:flexible", "*", "*", "**"]);
+ ["sqlite3*", "string:flexible",
+ new wasm.xWrap.FuncPtrAdapter({
+ signature: 'i(pipp)',
+ bindScope: 'transient'
+ }), "*", "**"]);
/* Documented in the api object's initializer. */
capi.sqlite3_exec = function f(pDb, sql, callback, pVoid, pErrMsg){
if(f.length!==arguments.length){
return __dbArgcMismatch(pDb,"sqlite3_exec",f.length);
- }else if('function' !== typeof callback){
+ }else if(!(callback instanceof Function)){
return __exec(pDb, sql, callback, pVoid, pErrMsg);
}
/* Wrap the callback in a WASM-bound function and convert the callback's
@@ -294,15 +605,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
return rc;
};
- let pFunc, rc;
+ let rc;
try{
- pFunc = wasm.installFunction("ipipp", cbwrap);
- rc = __exec(pDb, sql, pFunc, pVoid, pErrMsg);
+ rc = __exec(pDb, sql, cbwrap, pVoid, pErrMsg);
}catch(e){
rc = util.sqlite3_wasm_db_error(pDb, capi.SQLITE_ERROR,
- "Error running exec(): "+e.message);
- }finally{
- if(pFunc) wasm.uninstallFunction(pFunc);
+ "Error running exec(): "+e);
}
return rc;
};
@@ -310,12 +618,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
if(1){/* Special-case handling of sqlite3_create_function_v2()
and sqlite3_create_window_function() */
+ /* Maintenance reminder: FuncPtrAdapter is not expressive enough
+ to be able to perform these mappings. */
const sqlite3CreateFunction = wasm.xWrap(
"sqlite3_create_function_v2", "int",
["sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
"int"/*eTextRep*/, "*"/*pApp*/,
"*"/*xStep*/,"*"/*xFinal*/, "*"/*xValue*/, "*"/*xDestroy*/]
);
+
const sqlite3CreateWindowFunction = wasm.xWrap(
"sqlite3_create_window_function", "int",
["sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
@@ -324,102 +635,31 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
"*"/*xInverse*/, "*"/*xDestroy*/]
);
- const __udfSetResult = function(pCtx, val){
- //console.warn("udfSetResult",typeof val, val);
- switch(typeof val) {
- case 'undefined':
- /* Assume that the client already called sqlite3_result_xxx(). */
- break;
- case 'boolean':
- capi.sqlite3_result_int(pCtx, val ? 1 : 0);
- break;
- case 'bigint':
- if(wasm.bigIntEnabled){
- if(util.bigIntFits64(val)) capi.sqlite3_result_int64(pCtx, val);
- else toss3("BigInt value",val.toString(),"is too BigInt for int64.");
- }else if(util.bigIntFits32(val)){
- capi.sqlite3_result_int(pCtx, Number(val));
- }else if(util.bigIntFitsDouble(val)){
- capi.sqlite3_result_double(pCtx, Number(val));
- }else{
- toss3("BigInt value",val.toString(),"is too BigInt.");
- }
- break;
- case 'number': {
- (util.isInt32(val)
- ? capi.sqlite3_result_int
- : capi.sqlite3_result_double)(pCtx, val);
- break;
- }
- case 'string':
- capi.sqlite3_result_text(pCtx, val, -1, capi.SQLITE_TRANSIENT);
- break;
- case 'object':
- if(null===val/*yes, typeof null === 'object'*/) {
- capi.sqlite3_result_null(pCtx);
- break;
- }else if(util.isBindableTypedArray(val)){
- const pBlob = wasm.allocFromTypedArray(val);
- capi.sqlite3_result_blob(
- pCtx, pBlob, val.byteLength,
- wasm.exports[sqlite3.config.deallocExportName]
- );
- break;
- }
- // else fall through
- default:
- toss3("Don't not how to handle this UDF result value:",(typeof val), val);
- };
- }/*__udfSetResult()*/;
-
- const __udfConvertArgs = function(argc, pArgv){
- let i;
- const tgt = [];
- for(i = 0; i < argc; ++i){
- /**
- Curiously: despite ostensibly requiring 8-byte
- alignment, the pArgv array is parcelled into chunks of
- 4 bytes (1 pointer each). The values those point to
- have 8-byte alignment but the individual argv entries
- do not.
- */
- tgt.push(capi.sqlite3_value_to_js(
- wasm.peekPtr(pArgv + (wasm.ptrSizeof * i))
- ));
- }
- return tgt;
- }/*__udfConvertArgs()*/;
-
- const __udfSetError = (pCtx, e)=>{
- if(e instanceof sqlite3.WasmAllocError){
- capi.sqlite3_result_error_nomem(pCtx);
- }else{
- const msg = ('string'===typeof e) ? e : e.message;
- capi.sqlite3_result_error(pCtx, msg, -1);
- }
- };
-
const __xFunc = function(callback){
return function(pCtx, argc, pArgv){
- try{ __udfSetResult(pCtx, callback(pCtx, ...__udfConvertArgs(argc, pArgv))) }
- catch(e){
+ try{
+ capi.sqlite3_result_js(
+ pCtx,
+ callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv))
+ );
+ }catch(e){
//console.error('xFunc() caught:',e);
- __udfSetError(pCtx, e);
+ capi.sqlite3_result_error_js(pCtx, e);
}
};
};
const __xInverseAndStep = function(callback){
return function(pCtx, argc, pArgv){
- try{ callback(pCtx, ...__udfConvertArgs(argc, pArgv)) }
- catch(e){ __udfSetError(pCtx, e) }
+ try{ callback(pCtx, ...capi.sqlite3_values_to_js(argc, pArgv)) }
+ catch(e){ capi.sqlite3_result_error_js(pCtx, e) }
};
};
const __xFinalAndValue = function(callback){
return function(pCtx){
- try{ __udfSetResult(pCtx, callback(pCtx)) }
- catch(e){ __udfSetError(pCtx, e) }
+ try{ capi.sqlite3_result_js(pCtx, callback(pCtx)) }
+ catch(e){ capi.sqlite3_result_error_js(pCtx, e) }
};
};
@@ -439,13 +679,13 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
xDestroy: {sig:'v(p)', f:__xDestroy}
});
- const __xWrapFuncs = function(theFuncs, tgtUninst){
+ /* Internal helper for sqlite3_create_function() and friends. */
+ const __xWrapFuncs = function(theKeys, theFuncs, tgtUninst){
const rc = []
- let k;
- for(k in theFuncs){
+ for(const k of theKeys){
let fArg = theFuncs[k];
if('function'===typeof fArg){
- const w = __xMap[k];
+ const w = __xMap[k] || toss3("Internal error in __xWrapFuncs: invalid key:",k);
fArg = wasm.installFunction(w.sig, w.f(fArg));
tgtUninst.push(fArg);
}
@@ -462,14 +702,19 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
xFinal, //void (*xFinal)(sqlite3_context*)
xDestroy //void (*xDestroy)(void*)
){
- if(f.length!==arguments.length){
+ if( f.length!==arguments.length ){
return __dbArgcMismatch(pDb,"sqlite3_create_function_v2",f.length);
+ }else if( 0 === (eTextRep & 0xf) ){
+ eTextRep |= capi.SQLITE_UTF8;
+ }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
+ return __errEncoding(pDb);
}
/* Wrap the callbacks in a WASM-bound functions... */
const uninstall = [/*funcs to uninstall on error*/];
let rc;
try{
- const funcArgs = __xWrapFuncs({xFunc, xStep, xFinal, xDestroy},
+ const funcArgs = __xWrapFuncs(['xFunc','xStep','xFinal','xDestroy'],
+ {xFunc, xStep, xFinal, xDestroy},
uninstall);
rc = sqlite3CreateFunction(pDb, funcName, nArg, eTextRep,
pApp, ...funcArgs);
@@ -503,14 +748,19 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
xInverse,//void (*xStep)(sqlite3_context*,int,sqlite3_value**)
xDestroy //void (*xDestroy)(void*)
){
- if(f.length!==arguments.length){
+ if( f.length!==arguments.length ){
return __dbArgcMismatch(pDb,"sqlite3_create_window_function",f.length);
+ }else if( 0 === (eTextRep & 0xf) ){
+ eTextRep |= capi.SQLITE_UTF8;
+ }else if( capi.SQLITE_UTF8 !== (eTextRep & 0xf) ){
+ return __errEncoding(pDb);
}
/* Wrap the callbacks in a WASM-bound functions... */
const uninstall = [/*funcs to uninstall on error*/];
let rc;
try{
- const funcArgs = __xWrapFuncs({xStep, xFinal, xValue, xInverse, xDestroy},
+ const funcArgs = __xWrapFuncs(['xStep','xFinal','xValue','xInverse','xDestroy'],
+ {xStep, xFinal, xValue, xInverse, xDestroy},
uninstall);
rc = sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
pApp, ...funcArgs);
@@ -525,66 +775,34 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
return rc;
};
/**
- A helper for UDFs implemented in JS and bound to WASM by the
- client. Given a JS value, udfSetResult(pCtx,X) calls one of the
- sqlite3_result_xyz(pCtx,...) routines, depending on X's data
- type:
-
- - `null`: sqlite3_result_null()
- - `boolean`: sqlite3_result_int()
- - `number`: sqlite3_result_int() or sqlite3_result_double()
- - `string`: sqlite3_result_text()
- - Uint8Array or Int8Array: sqlite3_result_blob()
- - `undefined`: indicates that the UDF called one of the
- `sqlite3_result_xyz()` routines on its own, making this
- function a no-op. Results are _undefined_ if this function is
- passed the `undefined` value but did _not_ call one of the
- `sqlite3_result_xyz()` routines.
-
- Anything else triggers sqlite3_result_error().
+ A _deprecated_ alias for capi.sqlite3_result_js() which
+ predates the addition of that function in the public API.
*/
capi.sqlite3_create_function_v2.udfSetResult =
capi.sqlite3_create_function.udfSetResult =
- capi.sqlite3_create_window_function.udfSetResult = __udfSetResult;
+ capi.sqlite3_create_window_function.udfSetResult = capi.sqlite3_result_js;
/**
- A helper for UDFs implemented in JS and bound to WASM by the
- client. When passed the
- (argc,argv) values from the UDF-related functions which receive
- them (xFunc, xStep, xInverse), it creates a JS array
- representing those arguments, converting each to JS in a manner
- appropriate to its data type: numeric, text, blob
- (Uint8Array), or null.
-
- Results are undefined if it's passed anything other than those
- two arguments from those specific contexts.
-
- Thus an argc of 4 will result in a length-4 array containing
- the converted values from the corresponding argv.
-
- The conversion will throw only on allocation error or an internal
- error.
+ A _deprecated_ alias for capi.sqlite3_values_to_js() which
+ predates the addition of that function in the public API.
*/
capi.sqlite3_create_function_v2.udfConvertArgs =
capi.sqlite3_create_function.udfConvertArgs =
- capi.sqlite3_create_window_function.udfConvertArgs = __udfConvertArgs;
+ capi.sqlite3_create_window_function.udfConvertArgs = capi.sqlite3_values_to_js;
/**
- A helper for UDFs implemented in JS and bound to WASM by the
- client. It expects to be a passed `(sqlite3_context*, Error)`
- (an exception object or message string). And it sets the
- current UDF's result to sqlite3_result_error_nomem() or
- sqlite3_result_error(), depending on whether the 2nd argument
- is a sqlite3.WasmAllocError object or not.
+ A _deprecated_ alias for capi.sqlite3_result_error_js() which
+ predates the addition of that function in the public API.
*/
capi.sqlite3_create_function_v2.udfSetError =
capi.sqlite3_create_function.udfSetError =
- capi.sqlite3_create_window_function.udfSetError = __udfSetError;
+ capi.sqlite3_create_window_function.udfSetError = capi.sqlite3_result_error_js;
}/*sqlite3_create_function_v2() and sqlite3_create_window_function() proxies*/;
if(1){/* Special-case handling of sqlite3_prepare_v2() and
sqlite3_prepare_v3() */
+
/**
Helper for string:flexible conversions which require a
byte-length counterpart argument. Passed a value and its
@@ -608,32 +826,33 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
/**
Scope-local holder of the two impls of sqlite3_prepare_v2/v3().
*/
- const __prepare = Object.create(null);
- /**
- This binding expects a JS string as its 2nd argument and
- null as its final argument. In order to compile multiple
- statements from a single string, the "full" impl (see
- below) must be used.
- */
- __prepare.basic = wasm.xWrap('sqlite3_prepare_v3',
- "int", ["sqlite3*", "string",
- "int"/*ignored for this impl!*/,
- "int", "**",
- "**"/*MUST be 0 or null or undefined!*/]);
- /**
- Impl which requires that the 2nd argument be a pointer
- to the SQL string, instead of being converted to a
- string. This variant is necessary for cases where we
- require a non-NULL value for the final argument
- (exec()'ing multiple statements from one input
- string). For simpler cases, where only the first
- statement in the SQL string is required, the wrapper
- named sqlite3_prepare_v2() is sufficient and easier to
- use because it doesn't require dealing with pointers.
- */
- __prepare.full = wasm.xWrap('sqlite3_prepare_v3',
- "int", ["sqlite3*", "*", "int", "int",
- "**", "**"]);
+ const __prepare = {
+ /**
+ This binding expects a JS string as its 2nd argument and
+ null as its final argument. In order to compile multiple
+ statements from a single string, the "full" impl (see
+ below) must be used.
+ */
+ basic: wasm.xWrap('sqlite3_prepare_v3',
+ "int", ["sqlite3*", "string",
+ "int"/*ignored for this impl!*/,
+ "int", "**",
+ "**"/*MUST be 0 or null or undefined!*/]),
+ /**
+ Impl which requires that the 2nd argument be a pointer
+ to the SQL string, instead of being converted to a
+ string. This variant is necessary for cases where we
+ require a non-NULL value for the final argument
+ (exec()'ing multiple statements from one input
+ string). For simpler cases, where only the first
+ statement in the SQL string is required, the wrapper
+ named sqlite3_prepare_v2() is sufficient and easier to
+ use because it doesn't require dealing with pointers.
+ */
+ full: wasm.xWrap('sqlite3_prepare_v3',
+ "int", ["sqlite3*", "*", "int", "int",
+ "**", "**"])
+ };
/* Documented in the capi object's initializer. */
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
@@ -658,7 +877,163 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
? capi.sqlite3_prepare_v3(pDb, sql, sqlLen, 0, ppStmt, pzTail)
: __dbArgcMismatch(pDb,"sqlite3_prepare_v2",f.length);
};
- }/*sqlite3_prepare_v2/v3()*/;
+
+ }/*sqlite3_prepare_v2/v3()*/
+
+ {/*sqlite3_bind_text/blob()*/
+ const __bindText = wasm.xWrap("sqlite3_bind_text", "int", [
+ "sqlite3_stmt*", "int", "string", "int", "*"
+ ]);
+ const __bindBlob = wasm.xWrap("sqlite3_bind_blob", "int", [
+ "sqlite3_stmt*", "int", "*", "int", "*"
+ ]);
+
+ /** Documented in the capi object's initializer. */
+ capi.sqlite3_bind_text = function f(pStmt, iCol, text, nText, xDestroy){
+ if(f.length!==arguments.length){
+ return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt),
+ "sqlite3_bind_text", f.length);
+ }else if(wasm.isPtr(text) || null===text){
+ return __bindText(pStmt, iCol, text, nText, xDestroy);
+ }else if(text instanceof ArrayBuffer){
+ text = new Uint8Array(text);
+ }else if(Array.isArray(pMem)){
+ text = pMem.join('');
+ }
+ let p, n;
+ try{
+ if(util.isSQLableTypedArray(text)){
+ p = wasm.allocFromTypedArray(text);
+ n = text.byteLength;
+ }else if('string'===typeof text){
+ [p, n] = wasm.allocCString(text);
+ }else{
+ return util.sqlite3_wasm_db_error(
+ capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE,
+ "Invalid 3rd argument type for sqlite3_bind_text()."
+ );
+ }
+ return __bindText(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC);
+ }catch(e){
+ wasm.dealloc(p);
+ return util.sqlite3_wasm_db_error(
+ capi.sqlite3_db_handle(pStmt), e
+ );
+ }
+ }/*sqlite3_bind_text()*/;
+
+ /** Documented in the capi object's initializer. */
+ capi.sqlite3_bind_blob = function f(pStmt, iCol, pMem, nMem, xDestroy){
+ if(f.length!==arguments.length){
+ return __dbArgcMismatch(capi.sqlite3_db_handle(pStmt),
+ "sqlite3_bind_blob", f.length);
+ }else if(wasm.isPtr(pMem) || null===pMem){
+ return __bindBlob(pStmt, iCol, pMem, nMem, xDestroy);
+ }else if(pMem instanceof ArrayBuffer){
+ pMem = new Uint8Array(pMem);
+ }else if(Array.isArray(pMem)){
+ pMem = pMem.join('');
+ }
+ let p, n;
+ try{
+ if(util.isBindableTypedArray(pMem)){
+ p = wasm.allocFromTypedArray(pMem);
+ n = nMem>=0 ? nMem : pMem.byteLength;
+ }else if('string'===typeof pMem){
+ [p, n] = wasm.allocCString(pMem);
+ }else{
+ return util.sqlite3_wasm_db_error(
+ capi.sqlite3_db_handle(pStmt), capi.SQLITE_MISUSE,
+ "Invalid 3rd argument type for sqlite3_bind_blob()."
+ );
+ }
+ return __bindBlob(pStmt, iCol, p, n, capi.SQLITE_WASM_DEALLOC);
+ }catch(e){
+ wasm.dealloc(p);
+ return util.sqlite3_wasm_db_error(
+ capi.sqlite3_db_handle(pStmt), e
+ );
+ }
+ }/*sqlite3_bind_blob()*/;
+
+ }/*sqlite3_bind_text/blob()*/
+
+ {/* sqlite3_set_authorizer() */
+ const __ssa = wasm.xWrap("sqlite3_set_authorizer", 'int', [
+ "sqlite3*",
+ new wasm.xWrap.FuncPtrAdapter({
+ name: "sqlite3_set_authorizer::xAuth",
+ signature: "i(pi"+"ssss)",
+ contextKey: (argIndex, argv)=>argv[0/*(sqlite3*)*/]
+ }),
+ "*"
+ ]);
+ capi.sqlite3_set_authorizer = function(pDb, xAuth, pUserData){
+ if(3!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_set_authorizer', 3);
+ if(xAuth instanceof Function){
+ const xProxy = xAuth;
+ /* Create a proxy which will receive the C-strings from WASM
+ and convert them to JS strings for the client-supplied
+ function. */
+ xAuth = function(pV, iCode, s0, s1, s2, s3){
+ try{
+ s0 = s0 && wasm.cstrToJs(s0); s1 = s1 && wasm.cstrToJs(s1);
+ s2 = s2 && wasm.cstrToJs(s2); s3 = s3 && wasm.cstrToJs(s3);
+ return xProxy(pV, iCode, s0, s1, s2, s3) || 0;
+ }catch(e){
+ return util.sqlite3_wasm_db_error(pDb, e);
+ }
+ };
+ }
+ return __ssa(pDb, xAuth, pUserData);
+ };
+ }/* 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');
@@ -669,14 +1044,14 @@ 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',
'prepareFlags', 'resultCodes',
'serialize', 'sqlite3Status',
'stmtStatus', 'syncFlags',
- 'trace', 'udfFlags',
+ 'trace', 'txnState', 'udfFlags',
'version' ];
if(wasm.bigIntEnabled){
defineGroups.push('vtab');
@@ -727,9 +1102,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
capi.sqlite3_index_info[k] = capi[k];
delete capi[k];
}
- capi.sqlite3_vtab_config =
- (pDb, op, arg=0)=>wasm.exports.sqlite3_wasm_vtab_config(
- wasm.xWrap.argAdapter('sqlite3*')(pDb), op, arg);
+ capi.sqlite3_vtab_config = wasm.xWrap(
+ 'sqlite3_wasm_vtab_config','int',[
+ 'sqlite3*', 'int', 'int']
+ );
}/* end vtab-related setup */
}/*end C constant and struct imports*/