aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/api/sqlite3-api-prologue.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm/api/sqlite3-api-prologue.js')
-rw-r--r--ext/wasm/api/sqlite3-api-prologue.js113
1 files changed, 89 insertions, 24 deletions
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js
index 59533815f..fd66eccfd 100644
--- a/ext/wasm/api/sqlite3-api-prologue.js
+++ b/ext/wasm/api/sqlite3-api-prologue.js
@@ -285,29 +285,94 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
*/
const capi = {
/**
- When using sqlite3_open_v2() it is important to keep the following
- in mind:
-
- https://www.sqlite.org/c3ref/open.html
-
- - The flags for use with its 3rd argument are installed in this
- object using their C-side names, e.g. SQLITE_OPEN_CREATE.
-
- - If the combination of flags passed to it are invalid,
- behavior is undefined. Thus is is never okay to call this
- with fewer than 3 arguments, as JS will default the
- missing arguments to `undefined`, which will result in a
- flag value of 0. Most of the available SQLITE_OPEN_xxx
- flags are meaningless in the WASM build, e.g. the mutext-
- and cache-related flags, but they are retained in this
- API for consistency's sake.
-
- - The final argument to this function specifies the VFS to use,
- which is largely (but not entirely!) meaningless in the WASM
- environment. It may be null, undefined, or 0 to denote the
- default.
+ sqlite3_create_function_v2() differs from its native
+ counterpart only in the following ways:
+
+ 1) The fourth argument (`eTextRep`) argument must not specify
+ any encoding other than sqlite.SQLITE_UTF8. The JS API does not
+ currently support any other encoding and likely never
+ will. This function does not replace that argument on its own
+ because it may contain other flags.
+
+ 2) Any of the four final arguments may be either WASM pointers
+ (assumed to be function pointers) or JS Functions. In the
+ latter case, each gets bound to WASM using
+ sqlite3.capi.wasm.installFunction() and that wrapper is passed
+ on to the native implementation.
+
+ The semantics of JS functions are:
+
+ xFunc: is passed `(arrayOfValues)`. Its return value becomes
+ the new SQL function's result.
+
+ xStep: is passed `(arrayOfValues)`. Its return value is
+ ignored.
+
+ xFinal: is passed no arguments. Its return value becomes the
+ new aggragate SQL function's result.
+
+ xDestroy: is passed `(void*)`. Its return value is ignored. The
+ pointer passed to it is the one from the 5th argument to
+ sqlite3_create_function_v2().
+
+ Note that JS callback implementations have different call
+ signatures than their native counterparts (namely, they do not
+ get passed an `sqlite3_context*` argument) because practice has
+ shown that this is almost always more convenient and desirable
+ in JS code. Clients which need access to the full range of
+ native arguments will have to create a WASM-bound function
+ themselves (using wasm.installFunction() or equivalent) and
+ pass that function's WASM pointer to this function, rather than
+ passing a JS function. Be warned, however, that working with
+ UDFs at that level from JS is quite tedious.
+
+ For xFunc(), xStep(), and xFinal():
+
+ - When called from SQL, arguments to the UDF, and its result,
+ will be converted between JS and SQL with as much fidelity as
+ is feasible, triggering an exception if a type conversion
+ cannot be determined. Some freedom is afforded to numeric
+ conversions due to friction between the JS and C worlds:
+ integers which are larger than 32 bits will be treated as
+ doubles. TODO: use BigInt support if enabled. That feature
+ was added after this functionality was implemented.
+
+ If any JS-side functions throw, those exceptions are
+ intercepted and converted to database-side errors with
+ the exception of xFinal(): any exception from it is
+ ignored, possibly generating a console.error() message.
+ Destructors must not throw.
+
+ Once installed, there is currently no way to uninstall the
+ bound methods from WASM. They can be uninstalled from the
+ database as documented in the C API, but this wrapper currently
+ has no infrastructure in place to also free the WASM-bound JS
+ wrappers, effectively resulting in a memory leak if the client
+ uninstalls the UDF. Improving that is a potential TODO, but
+ removing client-installed UDFs is rare in practice.
+
+ Maintenance reminder: the ability to add new
+ WASM-accessible functions to the runtime requires that the
+ WASM build is compiled with emcc's `-sALLOW_TABLE_GROWTH`
+ flag.
*/
- sqlite3_open_v2: function(filename,dbPtrPtr,flags,vfsStr){}/*installed later*/,
+ sqlite3_create_function_v2: function(
+ pDb, funcName, nArg, eTextRep, pApp,
+ xFunc, //function(arrayOfValues)
+ xStep, //function(arrayOfValues)
+ xFinal, //function()
+ xDestroy //function(void*)
+ ){/*installed later*/},
+ /**
+ Equivalent to passing the same arguments to
+ sqlite3_create_function_v2(), with 0 as the final argument.
+ */
+ sqlite3_create_function:function(
+ pDb, funcName, nArg, eTextRep, pApp,
+ xFunc, //function(arrayOfValues)
+ xStep, //function(arrayOfValues)
+ xFinal //function()
+ ){/*installed later*/},
/**
The sqlite3_prepare_v3() binding handles two different uses
with differing JS/WASM semantics:
@@ -642,8 +707,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
["sqlite3_compileoption_get", "string", "int"],
["sqlite3_compileoption_used", "int", "string"],
- ["sqlite3_create_function_v2", "int",
- "sqlite3*", "string", "int", "int", "*", "*", "*", "*", "*"],
+ /* sqlite3_create_function_v2() is handled separate to simplify conversion
+ of its callback argument */
["sqlite3_data_count", "int", "sqlite3_stmt*"],
["sqlite3_db_filename", "string", "sqlite3*", "string"],
["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],