aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/api
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2022-12-05 07:51:25 +0000
committerstephan <stephan@noemail.net>2022-12-05 07:51:25 +0000
commit08fc64ea04d7b8ce458ba13608502159a2727738 (patch)
tree20b0366718de701ef5a0ad016ed3a8f40f719c75 /ext/wasm/api
parent864c3c029b869e5bfc58fcdf35f883e38c2cfa0d (diff)
downloadsqlite-08fc64ea04d7b8ce458ba13608502159a2727738.tar.gz
sqlite-08fc64ea04d7b8ce458ba13608502159a2727738.zip
More work on the JS side of the virtual table APIs.
FossilOrigin-Name: cb9881ec001b0e2faf047e57acfd1722d2b546255a54e0f850f568edfe2df1cd
Diffstat (limited to 'ext/wasm/api')
-rw-r--r--ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api14
-rw-r--r--ext/wasm/api/sqlite3-api-glue.js64
-rw-r--r--ext/wasm/api/sqlite3-api-prologue.js22
-rw-r--r--ext/wasm/api/sqlite3-wasm.c44
4 files changed, 92 insertions, 52 deletions
diff --git a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api
index 096bf4401..12ab94b2d 100644
--- a/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api
+++ b/ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api
@@ -7,6 +7,7 @@ _sqlite3_bind_null
_sqlite3_bind_parameter_count
_sqlite3_bind_parameter_index
_sqlite3_bind_text
+_sqlite3_busy_handler
_sqlite3_busy_timeout
_sqlite3_changes
_sqlite3_changes64
@@ -24,14 +25,19 @@ _sqlite3_column_text
_sqlite3_column_type
_sqlite3_compileoption_get
_sqlite3_compileoption_used
+_sqlite3_complete
_sqlite3_create_function
_sqlite3_create_function_v2
+_sqlite3_create_module
+_sqlite3_create_module_v2
_sqlite3_create_window_function
_sqlite3_data_count
_sqlite3_db_filename
_sqlite3_db_handle
_sqlite3_db_name
+_sqlite3_declare_vtab
_sqlite3_deserialize
+_sqlite3_drop_modules
_sqlite3_errmsg
_sqlite3_error_offset
_sqlite3_errstr
@@ -50,6 +56,7 @@ _sqlite3_malloc64
_sqlite3_msize
_sqlite3_open
_sqlite3_open_v2
+_sqlite3_overload_function
_sqlite3_prepare_v2
_sqlite3_prepare_v3
_sqlite3_randomness
@@ -93,6 +100,13 @@ _sqlite3_value_type
_sqlite3_vfs_find
_sqlite3_vfs_register
_sqlite3_vfs_unregister
+_sqlite3_vtab_distinct
+_sqlite3_vtab_in
+_sqlite3_vtab_in_first
+_sqlite3_vtab_in_next
+_sqlite3_vtab_nochange
+_sqlite3_vtab_on_conflict
+_sqlite3_vtab_rhs_value
_malloc
_free
_realloc
diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js
index 582b0c0a3..c1c91136a 100644
--- a/ext/wasm/api/sqlite3-api-glue.js
+++ b/ext/wasm/api/sqlite3-api-glue.js
@@ -37,20 +37,6 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
});
delete self.Jaccwabyt;
- if(0){
- /* "The problem" is that the following isn't even remotely
- type-safe. OTOH, nothing about WASM pointers is. */
- const argPointer = wasm.xWrap.argAdapter('*');
- wasm.xWrap.argAdapter('StructType', (v)=>{
- if(v && v.constructor && v instanceof StructBinder.StructType){
- v = v.pointer;
- }
- return wasm.isPtr(v)
- ? argPointer(v)
- : toss("Invalid (object) type for StructType-type argument.");
- });
- }
-
{/* Convert Arrays and certain TypedArrays to strings for
'flexible-string'-type arguments */
const xString = wasm.xWrap.argAdapter('string');
@@ -68,15 +54,21 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
`sqlite3_vfs*` via capi.sqlite3_vfs.pointer.
*/
const aPtr = wasm.xWrap.argAdapter('*');
+ const nilType = function(){};
wasm.xWrap.argAdapter('sqlite3_filename', aPtr)
('sqlite3_stmt*', aPtr)
('sqlite3_context*', aPtr)
('sqlite3_value*', aPtr)
('void*', aPtr)
- ('sqlite3*', (v)=>{
- if(sqlite3.oo1 && v instanceof sqlite3.oo1.DB) v = v.pointer;
- return aPtr(v);
- })
+ ('sqlite3*', (v)=>
+ aPtr((v instanceof (sqlite3?.oo1?.DB || nilType))
+ ? v.pointer : v))
+ ('sqlite3_index_info*', (v)=>
+ aPtr((v instanceof (capi.sqlite3_index_info || nilType))
+ ? v.pointer : v))
+ ('sqlite3_module*', (v)=>
+ aPtr((v instanceof (capi.sqlite3_module || nilType))
+ ? v.pointer : v))
/**
`sqlite3_vfs*`:
@@ -87,14 +79,13 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
*/
('sqlite3_vfs*', (v)=>{
if('string'===typeof v){
- const x = capi.sqlite3_vfs_find(v);
/* A NULL sqlite3_vfs pointer will be treated as the default
VFS in many contexts. We specifically do not want that
behavior here. */
- if(!x) sqlite3.SQLite3Error.toss("Unknown sqlite3_vfs name:",v);
- return x;
- }else if(v instanceof sqlite3.capi.sqlite3_vfs) v = v.pointer;
- return aPtr(v);
+ return capi.sqlite3_vfs_find(v)
+ || sqlite3.SQLite3Error.toss("Unknown sqlite3_vfs name:",v);
+ }
+ return aPtr((v instanceof capi.sqlite3_vfs) ? v.pointer : v);
});
wasm.xWrap.resultAdapter('sqlite3*', aPtr)
@@ -127,7 +118,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
: fI64Disabled(e[0]);
}
- /* There's no(?) need to expose bindingSignatures to clients,
+ /* There's no need to expose bindingSignatures to clients,
implicitly making it part of the public interface. */
delete wasm.bindingSignatures;
@@ -141,22 +132,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
return errCode;
};
}
-
}/*xWrap() bindings*/;
/**
- When registering a VFS and its related components it may be
- necessary to ensure that JS keeps a reference to them to keep
- them from getting garbage collected. Simply pass each such value
- to this function and a reference will be held to it for the life
- of the app.
- */
- capi.sqlite3_vfs_register.addReference = function f(...args){
- if(!f._) f._ = [];
- f._.push(...args);
- };
-
- /**
Internal helper to assist in validating call argument counts in
the hand-written sqlite3_xyz() wrappers. We do this only for
consistency with non-special-case wrappings.
@@ -603,10 +581,11 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
wasm.ctype = JSON.parse(wasm.cstringToJs(cJson));
//console.debug('wasm.ctype length =',wasm.cstrlen(cJson));
- const defineGroups = ['access', 'blobFinalizers', 'dataTypes',
+ const defineGroups = ['access', 'authorizer',
+ 'blobFinalizers', 'dataTypes',
'encodings', 'fcntl', 'flock', 'ioCap',
- 'limits',
- 'openFlags', 'prepareFlags', 'resultCodes',
+ 'limits', 'openFlags',
+ 'prepareFlags', 'resultCodes',
'serialize', 'syncFlags', 'trace', 'udfFlags',
'version' ];
if(wasm.bigIntEnabled){
@@ -658,7 +637,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);
+ }/* end vtab-related setup */
}/*end C constant and struct imports*/
const pKvvfs = capi.sqlite3_vfs_find("kvvfs");
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js
index 5ebe7af05..b66497e6b 100644
--- a/ext/wasm/api/sqlite3-api-prologue.js
+++ b/ext/wasm/api/sqlite3-api-prologue.js
@@ -890,6 +890,10 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
the lines of sqlite3_prepare_v3(). The slightly problematic
part is the final argument (text destructor). */
],
+ //["sqlite3_busy_handler","int", "sqlite3*", "*", "*"],
+ // ^^^^ TODO: custom binding which auto-converts JS function arg
+ // to a WASM function, noting that calling it multiple times
+ // would introduce a leak.
["sqlite3_busy_timeout","int", "sqlite3*", "int"],
["sqlite3_close_v2", "int", "sqlite3*"],
["sqlite3_changes", "int", "sqlite3*"],
@@ -904,6 +908,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
["sqlite3_column_type","int", "sqlite3_stmt*", "int"],
["sqlite3_compileoption_get", "string", "int"],
["sqlite3_compileoption_used", "int", "string"],
+ ["sqlite3_complete", "int", "flexible-string"],
/* sqlite3_create_function(), sqlite3_create_function_v2(), and
sqlite3_create_window_function() use hand-written bindings to
simplify handling of their function-type arguments. */
@@ -998,14 +1003,31 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
["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*", "flexible-string"]],
+ ["sqlite3_drop_modules", "int", ["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_total_changes64", "i64", ["sqlite3*"]],
["sqlite3_uri_int64", "i64", ["sqlite3_filename", "string", "i64"]],
["sqlite3_value_int64","i64", "sqlite3_value*"],
+ //EXPERIMENTAL const char *sqlite3_vtab_collation(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", "**"]
];
/**
diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c
index dc5dff62a..96234bca3 100644
--- a/ext/wasm/api/sqlite3-wasm.c
+++ b/ext/wasm/api/sqlite3-wasm.c
@@ -410,13 +410,11 @@ const char * sqlite3_wasm_enum_json(void){
DefInt(SQLITE_ACCESS_READ)/*docs say this is unused*/;
} _DefGroup;
-#if 0
/* TODO? Authorizer... */
DefGroup(authorizer){
DefInt(SQLITE_DENY);
DefInt(SQLITE_IGNORE);
} _DefGroup;
-#endif
DefGroup(blobFinalizers) {
/* SQLITE_STATIC/TRANSIENT need to be handled explicitly as
@@ -709,6 +707,14 @@ const char * sqlite3_wasm_enum_json(void){
DefInt(SQLITE_INDEX_CONSTRAINT_LIMIT);
DefInt(SQLITE_INDEX_CONSTRAINT_OFFSET);
DefInt(SQLITE_INDEX_CONSTRAINT_FUNCTION);
+ DefInt(SQLITE_VTAB_CONSTRAINT_SUPPORT);
+ DefInt(SQLITE_VTAB_INNOCUOUS);
+ DefInt(SQLITE_VTAB_DIRECTONLY);
+ DefInt(SQLITE_ROLLBACK);
+ //DefInt(SQLITE_IGNORE); // Also used by sqlite3_authorizer() callback
+ DefInt(SQLITE_FAIL);
+ //DefInt(SQLITE_ABORT); // Also an error code
+ DefInt(SQLITE_REPLACE);
} _DefGroup;
#undef DefGroup
@@ -867,15 +873,6 @@ const char * sqlite3_wasm_enum_json(void){
M(xShadowName, "i(s)");
} _StructBinder;
#undef CurrentStruct
- /*
- module/vtab todos:
-
- - sqlite3_create_module()
- - sqlite3_create_module_v2()
- - sqlite3_drop_modules()
- - sqlite3_declare_vtab()
- - sqlite3_overload_function()
- */
/**
** Workaround: in order to map the various inner structs from
@@ -1269,6 +1266,31 @@ sqlite3_kvvfs_methods * sqlite3_wasm_kvvfs_methods(void){
return &sqlite3KvvfsMethods;
}
+/*
+** This function is NOT part of the sqlite3 public API. It is strictly
+** for use by the sqlite project's own JS/WASM bindings.
+**
+** This is a proxy for the variadic sqlite3_vtab_config() which passes
+** its argument on, or not, to sqlite3_vtab_config(), depending on the
+** value of its 2nd argument. Returns the result of
+** sqlite3_vtab_config(), or SQLITE_MISUSE if the 2nd arg is not a
+** valid value.
+*/
+SQLITE_WASM_KEEP
+int sqlite3_wasm_vtab_config(sqlite3 *pDb, int op, int arg){
+ switch(op){
+ case SQLITE_VTAB_DIRECTONLY:
+ case SQLITE_VTAB_INNOCUOUS:
+ return sqlite3_vtab_config(pDb, op);
+ case SQLITE_VTAB_CONSTRAINT_SUPPORT:
+ return sqlite3_vtab_config(pDb, op, arg);
+ default:
+ return SQLITE_MISUSE;
+ }
+
+}
+
+
#if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS)
#include <emscripten/wasmfs.h>