# of the makefile, some of which are relatively expensive to calculate
# on each run (that is, they can take a human-visible amount of time).
#
-# .gen.make is also home to make-side vars which are needed for
-# generating makefile code via shell code.
+# Sidebar: three attempts have been made to move much of the
+# $(eval)-generated makefile code into make-make.sh but the result is
+# even less legible/maintainable than make-side $(eval).
ifeq (0,$(MAKING_CLEAN))
.gen.make: $(MAKEFILE) $(sqlite3.c)
rm -f $@
$(info Development build. Use 'release' or 'snapshot' target for a smaller release build.)
endif
+########################################################################
+# minimal=1 disables all "extraneous" stuff from sqlite3-wasm.c, the
+# goal being to create a WASM file with only the core APIs.
+ifeq (1,$(minimal))
+ wasm-bare-bones := 1
+else
+ wasm-bare-bones := 0
+endif
+undefine minimal
+
# Common options for building sqlite3-wasm.c and speedtest1.c.
# Explicit ENABLEs...
-SQLITE_OPT = \
+SQLITE_OPT.common := \
+ -DSQLITE_THREADSAFE=0 \
+ -DSQLITE_TEMP_STORE=2 \
+ -DSQLITE_ENABLE_MATH_FUNCTIONS \
+ -DSQLITE_OS_KV_OPTIONAL=1 \
+ '-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \
+ -DSQLITE_USE_URI=1 \
+ -DSQLITE_C=$(sqlite3.c) \
+ -DSQLITE_OMIT_DEPRECATED \
+ -DSQLITE_OMIT_UTF16 \
+ -DSQLITE_OMIT_LOAD_EXTENSION \
+ -DSQLITE_OMIT_SHARED_CACHE
+# ^^^ These particular OMITs are hard-coded in sqlite3-wasm.c and
+# removing them from this list will serve only to break the speedtest1
+# builds.
+
+# Currently always needed but TODO is paring tester1.c-pp.js down
+# to be able to run without this:
+SQLITE_OPT.common += -DSQLITE_WASM_ENABLE_C_TESTS
+
+SQLITE_OPT.full-featured := \
-DSQLITE_ENABLE_BYTECODE_VTAB \
-DSQLITE_ENABLE_DBPAGE_VTAB \
-DSQLITE_ENABLE_DBSTAT_VTAB \
-DSQLITE_ENABLE_STMTVTAB \
-DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
-# Explicit OMITs...
-SQLITE_OPT += \
- -DSQLITE_OMIT_LOAD_EXTENSION \
- -DSQLITE_OMIT_DEPRECATED \
- -DSQLITE_OMIT_UTF16 \
- -DSQLITE_OMIT_SHARED_CACHE
-
-# Misc. build-time config options...
-SQLITE_OPT += \
- -DSQLITE_THREADSAFE=0 \
- -DSQLITE_TEMP_STORE=2 \
- -DSQLITE_OS_KV_OPTIONAL=1 \
- '-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \
- -DSQLITE_USE_URI=1 \
- -DSQLITE_WASM_ENABLE_C_TESTS \
- -DSQLITE_C=$(sqlite3.c)
+ifeq (0,$(wasm-bare-bones))
+ # The so-called canonical build is full-featured:
+ SQLITE_OPT := \
+ $(SQLITE_OPT.common) \
+ $(SQLITE_OPT.full-featured)
+else
+ # The so-called bare-bones build is exactly that:
+ SQLITE_OPT := \
+ $(SQLITE_OPT.common) \
+ -DSQLITE_WASM_BARE_BONES
+ # SQLITE_WASM_BARE_BONES tells sqlite3-wasm.c to explicitly omit
+ # a bunch of stuff, in the interest of keeping the wasm file size
+ # down. As of this writing it equates to:
+ #
+ # -USQLITE_ENABLE_DBPAGE_VTAB
+ # -USQLITE_ENABLE_DBSTAT_VTAB
+ # -USQLITE_ENABLE_EXPLAIN_COMMENTS
+ # -USQLITE_ENABLE_FTS5
+ # -USQLITE_ENABLE_OFFSET_SQL_FUNC
+ # -USQLITE_ENABLE_PREUPDATE_HOOK
+ # -USQLITE_ENABLE_RTREE
+ # -USQLITE_ENABLE_SESSION
+ # -USQLITE_ENABLE_STMTVTAB
+ # -DSQLITE_OMIT_AUTHORIZATION
+ # -DSQLITE_OMIT_GET_TABLE
+ # -DSQLITE_OMIT_INCRBLOB
+ # -DSQLITE_OMIT_INTROSPECTION_PRAGMAS
+ # -DSQLITE_OMIT_JSON
+ # -DSQLITE_OMIT_PROGRESS_CALLBACK
+ # -DSQLITE_OMIT_WAL
+ #
+ # There are others we want here but which require explicit OMIT when
+ # creating their amalgamation, and that step is TODO:
+ #
+ # -DSQLITE_OMIT_EXPLAIN
+ # -DSQLITE_OMIT_TRIGGER
+ # -DSQLITE_OMIT_VIRTUALTABLE
+ # -DSQLITE_OMIT_WINDOWFUNC
+endif
#SQLITE_OPT += -DSQLITE_DEBUG
# Enabling SQLITE_DEBUG will break sqlite3_wasm_vfs_create_file()
# in client code.
########################################################################
-# minimal=1 disables all "extraneous" stuff from sqlite3-wasm.c, the
-# goal being to create a WASM file with only the core APIs.
-ifeq (1,$(minimal))
- SQLITE_OPT += -DSQLITE_WASM_MINIMAL
- # SQLITE_WASM_MINIMAL tells sqlite3-wasm.c to explicitly omit
- # a bunch of stuff, in the interest of keeping the wasm file size
- # down.
- wasm-minimal := 1
-else
- wasm-minimal := 0
-endif
-undefine minimal
+# The following flags are hard-coded into sqlite3-wasm.c and cannot be
+# modified via the build process:
+#
+# SQLITE_ENABLE_API_ARMOR
+# SQLITE_OMIT_LOAD_EXTENSION
+# SQLITE_OMIT_DEPRECATED
+# SQLITE_OMIT_UTF16
+# SQLITE_OMIT_SHARED_CACHE
+########################################################################
+
########################################################################
# Adding custom C code via sqlite3_wasm_extra_init.c:
ifeq (1,$(SQLITE_C_IS_SEE))
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-see
endif
-ifeq (0,$(wasm-minimal))
+ifeq (0,$(wasm-bare-bones))
EXPORTED_FUNCTIONS.api.in += $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
else
$(info ========================================)
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.c-pp.js
# sqlite3-vfs-helper = helper APIs for VFSes:
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js
-ifeq (0,$(wasm-minimal))
+ifeq (0,$(wasm-bare-bones))
# sqlite3-vtab-helper = helper APIs for VTABLEs:
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
endif
$(emcc.speedtest1.common) \
$(emcc.flags.speedtest1-vanilla) $(pre-post-speedtest1-vanilla.flags) \
$(SQLITE_OPT) \
- -USQLITE_WASM_MINIMAL \
+ -USQLITE_WASM_BARE_BONES \
-USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \
$(speedtest1.exit-runtime0) \
-o $@ $(speedtest1.cfiles) -lm
_sqlite3_create_collation_v2
_sqlite3_create_function
_sqlite3_create_function_v2
-_sqlite3_create_window_function
_sqlite3_data_count
_sqlite3_db_filename
_sqlite3_db_handle
_sqlite3_overload_function
_sqlite3_prepare_v2
_sqlite3_prepare_v3
-_sqlite3_progress_handler
_sqlite3_randomness
_sqlite3_realloc
_sqlite3_realloc64
+_sqlite3_create_window_function
+_sqlite3_progress_handler
_sqlite3_set_authorizer
_sqlite3_preupdate_blobwrite
_sqlite3_preupdate_count
["sqlite3_compileoption_used", "int", "string"],
["sqlite3_complete", "int", "string:flexible"],
["sqlite3_context_db_handle", "sqlite3*", "sqlite3_context*"],
-
+ /* sqlite3_create_collation() and sqlite3_create_collation_v2()
+ use hand-written bindings to simplify passing of the callback
+ function. */
/* 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*"],
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: (argv,argIndex)=>argv[0/* sqlite3* */]
- }), "*"
- ]],
["sqlite3_realloc", "*","*","int"],
["sqlite3_reset", "int", "sqlite3_stmt*"],
/* sqlite3_reset_auto_extension() has a hand-written binding. */
["sqlite3_vfs_unregister", "int", "sqlite3_vfs*"]
]/*wasm.bindingSignatures*/;
+ if( !!wasm.exports.sqlite3_progress_handler ){
+ wasm.bindingSignatures.push(
+ ["sqlite3_progress_handler", undefined, [
+ "sqlite3*", "int", new wasm.xWrap.FuncPtrAdapter({
+ name: 'xProgressHandler',
+ signature: 'i(p)',
+ bindScope: 'context',
+ contextKey: (argv,argIndex)=>argv[0/* sqlite3* */]
+ }), "*"
+ ]]
+ );
+ }
+
if( !!wasm.exports.sqlite3_stmt_explain ){
wasm.bindingSignatures.push(
["sqlite3_stmt_explain", "int", "sqlite3_stmt*", "int"],
/** 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. */
+ SQLITE_FORMAT, installs a descriptive error message,
+ and returns SQLITE_FORMAT. */
const __errEncoding = (pDb)=>{
return util.sqlite3__wasm_db_error(
pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding."
this._addUDF(pDb, name, arity, m.udf);
};
- __dbCleanupMap.addWindowFunc = function(pDb, name, arity){
- const m = __dbCleanupMap(pDb, 1);
- if(!m.wudf) m.wudf = new Map;
- this._addUDF(pDb, name, arity, m.wudf);
- };
+ if( wasm.exports.sqlite3_create_window_function ){
+ __dbCleanupMap.addWindowFunc = function(pDb, name, arity){
+ const m = __dbCleanupMap(pDb, 1);
+ if(!m.wudf) m.wudf = new Map;
+ this._addUDF(pDb, name, arity, m.wudf);
+ };
+ }
/**
Intended to be called _only_ from sqlite3_close_v2(),
]
);
- const __sqlite3CreateWindowFunction = wasm.xWrap(
- "sqlite3_create_window_function", "int", [
- "sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
- "int"/*eTextRep*/, "*"/*pApp*/,
- new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}),
- new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}),
- new wasm.xWrap.FuncPtrAdapter({name: 'xValue', ...__cfProxy.xFinalAndValue}),
- new wasm.xWrap.FuncPtrAdapter({name: 'xInverse', ...__cfProxy.xInverseAndStep}),
- new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy})
- ]
- );
+ const __sqlite3CreateWindowFunction =
+ wasm.exports.sqlite3_create_window_function
+ ? wasm.xWrap(
+ "sqlite3_create_window_function", "int", [
+ "sqlite3*", "string"/*funcName*/, "int"/*nArg*/,
+ "int"/*eTextRep*/, "*"/*pApp*/,
+ new wasm.xWrap.FuncPtrAdapter({name: 'xStep', ...__cfProxy.xInverseAndStep}),
+ new wasm.xWrap.FuncPtrAdapter({name: 'xFinal', ...__cfProxy.xFinalAndValue}),
+ new wasm.xWrap.FuncPtrAdapter({name: 'xValue', ...__cfProxy.xFinalAndValue}),
+ new wasm.xWrap.FuncPtrAdapter({name: 'xInverse', ...__cfProxy.xInverseAndStep}),
+ new wasm.xWrap.FuncPtrAdapter({name: 'xDestroy', ...__cfProxy.xDestroy})
+ ]
+ )
+ : undefined;
/* Documented in the api object's initializer. */
capi.sqlite3_create_function_v2 = function f(
};
/* Documented in the api object's initializer. */
- capi.sqlite3_create_window_function = function f(
- pDb, funcName, nArg, eTextRep, pApp,
- xStep, //void (*xStep)(sqlite3_context*,int,sqlite3_value**)
- xFinal, //void (*xFinal)(sqlite3_context*)
- xValue, //void (*xValue)(sqlite3_context*)
- xInverse,//void (*xInverse)(sqlite3_context*,int,sqlite3_value**)
- xDestroy //void (*xDestroy)(void*)
- ){
- 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);
- }
- try{
- const rc = __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
- pApp, xStep, xFinal, xValue,
- xInverse, xDestroy);
- if(0===rc && (xStep instanceof Function
- || xFinal instanceof Function
- || xValue instanceof Function
- || xInverse instanceof Function
- || xDestroy instanceof Function)){
- __dbCleanupMap.addWindowFunc(pDb, funcName, nArg);
+ if( __sqlite3CreateWindowFunction ){
+ capi.sqlite3_create_window_function = function f(
+ pDb, funcName, nArg, eTextRep, pApp,
+ xStep, //void (*xStep)(sqlite3_context*,int,sqlite3_value**)
+ xFinal, //void (*xFinal)(sqlite3_context*)
+ xValue, //void (*xValue)(sqlite3_context*)
+ xInverse,//void (*xInverse)(sqlite3_context*,int,sqlite3_value**)
+ xDestroy //void (*xDestroy)(void*)
+ ){
+ 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);
}
- return rc;
- }catch(e){
- console.error("sqlite3_create_window_function() setup threw:",e);
- return util.sqlite3__wasm_db_error(pDb, e, "Creation of UDF threw: "+e);
- }
- };
+ try{
+ const rc = __sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
+ pApp, xStep, xFinal, xValue,
+ xInverse, xDestroy);
+ if(0===rc && (xStep instanceof Function
+ || xFinal instanceof Function
+ || xValue instanceof Function
+ || xInverse instanceof Function
+ || xDestroy instanceof Function)){
+ __dbCleanupMap.addWindowFunc(pDb, funcName, nArg);
+ }
+ return rc;
+ }catch(e){
+ console.error("sqlite3_create_window_function() setup threw:",e);
+ return util.sqlite3__wasm_db_error(pDb, e, "Creation of UDF threw: "+e);
+ }
+ };
+ }else{
+ delete capi.sqlite3_create_window_function;
+ }
/**
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_function.udfSetResult = capi.sqlite3_result_js;
+ if(capi.sqlite3_create_window_function){
capi.sqlite3_create_window_function.udfSetResult = capi.sqlite3_result_js;
+ }
/**
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_function.udfConvertArgs = capi.sqlite3_values_to_js;
+ if(capi.sqlite3_create_window_function){
capi.sqlite3_create_window_function.udfConvertArgs = capi.sqlite3_values_to_js;
+ }
/**
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_function.udfSetError = capi.sqlite3_result_error_js;
+ if(capi.sqlite3_create_window_function){
capi.sqlite3_create_window_function.udfSetError = capi.sqlite3_result_error_js;
+ }
}/*sqlite3_create_function_v2() and sqlite3_create_window_function() proxies*/;
/**********************************************************************/
/* SQLITE_O... */
-#ifndef SQLITE_OMIT_DEPRECATED
-# define SQLITE_OMIT_DEPRECATED 1
-#endif
-#ifndef SQLITE_OMIT_LOAD_EXTENSION
-# define SQLITE_OMIT_LOAD_EXTENSION 1
-#endif
-#ifndef SQLITE_OMIT_SHARED_CACHE
-# define SQLITE_OMIT_SHARED_CACHE 1
-#endif
-#ifndef SQLITE_OMIT_UTF16
-# define SQLITE_OMIT_UTF16 1
-#endif
-#ifndef SQLITE_OS_KV_OPTIONAL
-# define SQLITE_OS_KV_OPTIONAL 1
-#endif
+#undef SQLITE_OMIT_DEPRECATED
+#define SQLITE_OMIT_DEPRECATED 1
+#undef SQLITE_OMIT_LOAD_EXTENSION
+#define SQLITE_OMIT_LOAD_EXTENSION 1
+#undef SQLITE_OMIT_SHARED_CACHE
+#define SQLITE_OMIT_SHARED_CACHE 1
+#undef SQLITE_OMIT_UTF16
+#define SQLITE_OMIT_UTF16 1
+#undef SQLITE_OS_KV_OPTIONAL
+#define SQLITE_OS_KV_OPTIONAL 1
/**********************************************************************/
/* SQLITE_S... */
#endif
/*
-** If SQLITE_WASM_MINIMAL is defined, undefine most of the ENABLE
+** If SQLITE_WASM_BARE_BONES is defined, undefine most of the ENABLE
** macros.
*/
-#ifdef SQLITE_WASM_MINIMAL
-# undef SQLITE_ENABLE_DBPAGE_VTAB
-# undef SQLITE_ENABLE_DBSTAT_VTAB
-# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
-# undef SQLITE_ENABLE_FTS5
-# undef SQLITE_ENABLE_OFFSET_SQL_FUNC
-# undef SQLITE_ENABLE_PREUPDATE_HOOK
-# undef SQLITE_ENABLE_RTREE
-# undef SQLITE_ENABLE_SESSION
-# undef SQLITE_ENABLE_STMTVTAB
-# undef SQLITE_OMIT_AUTHORIZATION
+#ifdef SQLITE_WASM_BARE_BONES
+# undef SQLITE_ENABLE_DBPAGE_VTAB
+# undef SQLITE_ENABLE_DBSTAT_VTAB
+# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
+# undef SQLITE_ENABLE_FTS5
+# undef SQLITE_ENABLE_OFFSET_SQL_FUNC
+# undef SQLITE_ENABLE_PREUPDATE_HOOK
+# undef SQLITE_ENABLE_RTREE
+# undef SQLITE_ENABLE_SESSION
+# undef SQLITE_ENABLE_STMTVTAB
+# undef SQLITE_OMIT_AUTHORIZATION
# define SQLITE_OMIT_AUTHORIZATION
-/*Reminder re. custom sqlite3.c:
+# undef SQLITE_OMIT_GET_TABLE
+# define SQLITE_OMIT_GET_TABLE
+# undef SQLITE_OMIT_INCRBLOB
+# define SQLITE_OMIT_INCRBLOB
+# undef SQLITE_OMIT_INTROSPECTION_PRAGMAS
+# define SQLITE_OMIT_INTROSPECTION_PRAGMAS
+# undef SQLITE_OMIT_JSON
+# define SQLITE_OMIT_JSON
+# undef SQLITE_OMIT_PROGRESS_CALLBACK
+# define SQLITE_OMIT_PROGRESS_CALLBACK
+# undef SQLITE_OMIT_WAL
+# define SQLITE_OMIT_WAL
+/*
+ The following OMITs do not work with the standard amalgamation, so
+ require a custom build:
fossil clean -x
./configure
- OPTS='-DSQLITE_OMIT_VIRTUALTABLE -DSQLITE_OMIT_EXPLAIN -DSQLITE_OMIT_TRIGGER' make -e sqlite3
-*/
-/*Requires a custom sqlite3.c
-# undef SQLITE_OMIT_TRIGGER
-# define SQLITE_OMIT_TRIGGER
-*/
-/*TODO (requires build tweaks)
-# undef SQLITE_OMIT_WINDOWFUNC
-# define SQLITE_OMIT_WINDOWFUNC
-*/
-/*Requires a custom sqlite3.c
+ OPTS='...' make -e sqlite3
+
+ where ... has a -D... for each of the following OMIT flags:
+
# undef SQLITE_OMIT_EXPLAIN
# define SQLITE_OMIT_EXPLAIN
-*/
-/*Requires a custom sqlite3.c
+
+# undef SQLITE_OMIT_TRIGGER
+# define SQLITE_OMIT_TRIGGER
+
# undef SQLITE_OMIT_VIRTUALTABLE
# define SQLITE_OMIT_VIRTUALTABLE
+
+# undef SQLITE_OMIT_WINDOWFUNC
+# define SQLITE_OMIT_WINDOWFUNC
+
+ As of this writing (2024-07-25), such a build fails in various ways
+ for as-yet-unknown reasons.
*/
-# undef SQLITE_OMIT_JSON
-# define SQLITE_OMIT_JSON
#endif
-#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_MINIMAL)
+#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_WASM_BARE_BONES)
# define SQLITE_WASM_HAS_VTAB 1
#else
# define SQLITE_WASM_HAS_VTAB 0
#undef INC__STRINGIFY
#undef SQLITE_C
-#if defined(__EMSCRIPTEN__)
-# include <emscripten/console.h>
-#endif
-
#if 0
/*
** An EXPERIMENT in implementing a stack-based allocator analog to
}
#if defined(__EMSCRIPTEN__) && defined(SQLITE_ENABLE_WASMFS)
+#include <emscripten/console.h>
#include <emscripten/wasmfs.h>
/*
#undef SQLITE_WASM_EXPORT
#undef SQLITE_WASM_HAS_VTAB
-#undef SQLITE_WASM_MINIMAL
+#undef SQLITE_WASM_BARE_BONES
#undef SQLITE_WASM_ENABLE_C_TESTS
$(emcc.exportedRuntimeMethods) \
-sEXPORTED_FUNCTIONS=@$(abspath $(EXPORTED_FUNCTIONS.fiddle)) \
-sEXPORTED_RUNTIME_METHODS=FS,wasmMemory \
- $(SQLITE_OPT) $(SHELL_OPT) \
- -USQLITE_WASM_MINIMAL \
+ $(SQLITE_OPT.full-featured) \
+ $(SQLITE_OPT.common) \
+ $(SHELL_OPT) \
+ -USQLITE_WASM_BARE_BONES \
-DSQLITE_SHELL_FIDDLE
-# -D_POSIX_C_SOURCE is needed for strdup() with emcc
# Flags specifically for debug builds of fiddle. Performance suffers
# greatly in debug builds.
fiddle.EXPORTED_FUNCTIONS.in := \
EXPORTED_FUNCTIONS.fiddle.in \
- $(EXPORTED_FUNCTIONS.api)
+ $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-core \
+ $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-extras
$(EXPORTED_FUNCTIONS.fiddle): $(fiddle.EXPORTED_FUNCTIONS.in) $(MAKEFILE.fiddle)
sort -u $(fiddle.EXPORTED_FUNCTIONS.in) > $@
}/*WhWasmUtil*/)
////////////////////////////////////////////////////////////////////
- .t('sqlite3.StructBinder (jaccwabyt🐇)', function(sqlite3){
- const S = sqlite3, W = S.wasm;
- const MyStructDef = {
- sizeof: 16,
- members: {
- p4: {offset: 0, sizeof: 4, signature: "i"},
- pP: {offset: 4, sizeof: 4, signature: "P"},
- ro: {offset: 8, sizeof: 4, signature: "i", readOnly: true},
- cstr: {offset: 12, sizeof: 4, signature: "s"}
+ .t({
+ name: 'sqlite3.StructBinder (jaccwabyt🐇)',
+ predicate: (sqlite3)=>!!sqlite3.wasm.exports.sqlite3__wasm_test_struct
+ || "Built without SQLITE_WASM_ENABLE_C_TESTS",
+ test: function(sqlite3){
+ const S = sqlite3, W = S.wasm;
+ const MyStructDef = {
+ sizeof: 16,
+ members: {
+ p4: {offset: 0, sizeof: 4, signature: "i"},
+ pP: {offset: 4, sizeof: 4, signature: "P"},
+ ro: {offset: 8, sizeof: 4, signature: "i", readOnly: true},
+ cstr: {offset: 12, sizeof: 4, signature: "s"}
+ }
+ };
+ if(W.bigIntEnabled){
+ const m = MyStructDef;
+ m.members.p8 = {offset: m.sizeof, sizeof: 8, signature: "j"};
+ m.sizeof += m.members.p8.sizeof;
}
- };
- if(W.bigIntEnabled){
- const m = MyStructDef;
- m.members.p8 = {offset: m.sizeof, sizeof: 8, signature: "j"};
- m.sizeof += m.members.p8.sizeof;
- }
- const StructType = S.StructBinder.StructType;
- const K = S.StructBinder('my_struct',MyStructDef);
- T.mustThrowMatching(()=>K(), /via 'new'/).
- mustThrowMatching(()=>new K('hi'), /^Invalid pointer/);
- const k1 = new K(), k2 = new K();
- try {
- T.assert(k1.constructor === K).
- assert(K.isA(k1)).
- assert(k1 instanceof K).
- assert(K.prototype.lookupMember('p4').key === '$p4').
- assert(K.prototype.lookupMember('$p4').name === 'p4').
- mustThrowMatching(()=>K.prototype.lookupMember('nope'), /not a mapped/).
- assert(undefined === K.prototype.lookupMember('nope',false)).
- assert(k1 instanceof StructType).
- assert(StructType.isA(k1)).
- mustThrowMatching(()=>k1.$ro = 1, /read-only/);
- Object.keys(MyStructDef.members).forEach(function(key){
- key = K.memberKey(key);
- T.assert(0 == k1[key],
- "Expecting allocation to zero the memory "+
- "for "+key+" but got: "+k1[key]+
- " from "+k1.memoryDump());
- });
- T.assert('number' === typeof k1.pointer).
- mustThrowMatching(()=>k1.pointer = 1, /pointer/);
- k1.$p4 = 1; k1.$pP = 2;
- T.assert(1 === k1.$p4).assert(2 === k1.$pP);
- if(MyStructDef.members.$p8){
- k1.$p8 = 1/*must not throw despite not being a BigInt*/;
- k1.$p8 = BigInt(Number.MAX_SAFE_INTEGER * 2);
- T.assert(BigInt(2 * Number.MAX_SAFE_INTEGER) === k1.$p8);
+ const StructType = S.StructBinder.StructType;
+ const K = S.StructBinder('my_struct',MyStructDef);
+ T.mustThrowMatching(()=>K(), /via 'new'/).
+ mustThrowMatching(()=>new K('hi'), /^Invalid pointer/);
+ const k1 = new K(), k2 = new K();
+ try {
+ T.assert(k1.constructor === K).
+ assert(K.isA(k1)).
+ assert(k1 instanceof K).
+ assert(K.prototype.lookupMember('p4').key === '$p4').
+ assert(K.prototype.lookupMember('$p4').name === 'p4').
+ mustThrowMatching(()=>K.prototype.lookupMember('nope'), /not a mapped/).
+ assert(undefined === K.prototype.lookupMember('nope',false)).
+ assert(k1 instanceof StructType).
+ assert(StructType.isA(k1)).
+ mustThrowMatching(()=>k1.$ro = 1, /read-only/);
+ Object.keys(MyStructDef.members).forEach(function(key){
+ key = K.memberKey(key);
+ T.assert(0 == k1[key],
+ "Expecting allocation to zero the memory "+
+ "for "+key+" but got: "+k1[key]+
+ " from "+k1.memoryDump());
+ });
+ T.assert('number' === typeof k1.pointer).
+ mustThrowMatching(()=>k1.pointer = 1, /pointer/);
+ k1.$p4 = 1; k1.$pP = 2;
+ T.assert(1 === k1.$p4).assert(2 === k1.$pP);
+ if(MyStructDef.members.$p8){
+ k1.$p8 = 1/*must not throw despite not being a BigInt*/;
+ k1.$p8 = BigInt(Number.MAX_SAFE_INTEGER * 2);
+ T.assert(BigInt(2 * Number.MAX_SAFE_INTEGER) === k1.$p8);
+ }
+ T.assert(!k1.ondispose);
+ k1.setMemberCString('cstr', "A C-string.");
+ T.assert(Array.isArray(k1.ondispose)).
+ assert(k1.ondispose[0] === k1.$cstr).
+ assert('number' === typeof k1.$cstr).
+ assert('A C-string.' === k1.memberToJsString('cstr'));
+ k1.$pP = k2;
+ T.assert(k1.$pP === k2.pointer);
+ k1.$pP = null/*null is special-cased to 0.*/;
+ T.assert(0===k1.$pP);
+ let ptr = k1.pointer;
+ k1.dispose();
+ T.assert(undefined === k1.pointer).
+ mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
+ }finally{
+ k1.dispose();
+ k2.dispose();
}
- T.assert(!k1.ondispose);
- k1.setMemberCString('cstr', "A C-string.");
- T.assert(Array.isArray(k1.ondispose)).
- assert(k1.ondispose[0] === k1.$cstr).
- assert('number' === typeof k1.$cstr).
- assert('A C-string.' === k1.memberToJsString('cstr'));
- k1.$pP = k2;
- T.assert(k1.$pP === k2.pointer);
- k1.$pP = null/*null is special-cased to 0.*/;
- T.assert(0===k1.$pP);
- let ptr = k1.pointer;
- k1.dispose();
- T.assert(undefined === k1.pointer).
- mustThrowMatching(()=>{k1.$pP=1}, /disposed instance/);
- }finally{
- k1.dispose();
- k2.dispose();
- }
- if(!W.bigIntEnabled){
- log("Skipping WasmTestStruct tests: BigInt not enabled.");
- return;
- }
+ if(!W.bigIntEnabled){
+ log("Skipping WasmTestStruct tests: BigInt not enabled.");
+ return;
+ }
- const WTStructDesc =
- W.ctype.structs.filter((e)=>'WasmTestStruct'===e.name)[0];
- const autoResolvePtr = true /* EXPERIMENTAL */;
- if(autoResolvePtr){
- WTStructDesc.members.ppV.signature = 'P';
- }
- const WTStruct = S.StructBinder(WTStructDesc);
- //log(WTStruct.structName, WTStruct.structInfo);
- const wts = new WTStruct();
- //log("WTStruct.prototype keys:",Object.keys(WTStruct.prototype));
- try{
- T.assert(wts.constructor === WTStruct).
- assert(WTStruct.memberKeys().indexOf('$ppV')>=0).
- assert(wts.memberKeys().indexOf('$v8')>=0).
- assert(!K.isA(wts)).
- assert(WTStruct.isA(wts)).
- assert(wts instanceof WTStruct).
- assert(wts instanceof StructType).
- assert(StructType.isA(wts)).
- assert(wts.pointer>0).assert(0===wts.$v4).assert(0n===wts.$v8).
- assert(0===wts.$ppV).assert(0===wts.$xFunc);
- const testFunc =
- W.xGet('sqlite3__wasm_test_struct'/*name gets mangled in -O3 builds!*/);
- let counter = 0;
- //log("wts.pointer =",wts.pointer);
- const wtsFunc = function(arg){
- /*log("This from a JS function called from C, "+
+ const WTStructDesc =
+ W.ctype.structs.filter((e)=>'WasmTestStruct'===e.name)[0];
+ const autoResolvePtr = true /* EXPERIMENTAL */;
+ if(autoResolvePtr){
+ WTStructDesc.members.ppV.signature = 'P';
+ }
+ const WTStruct = S.StructBinder(WTStructDesc);
+ //log(WTStruct.structName, WTStruct.structInfo);
+ const wts = new WTStruct();
+ //log("WTStruct.prototype keys:",Object.keys(WTStruct.prototype));
+ try{
+ T.assert(wts.constructor === WTStruct).
+ assert(WTStruct.memberKeys().indexOf('$ppV')>=0).
+ assert(wts.memberKeys().indexOf('$v8')>=0).
+ assert(!K.isA(wts)).
+ assert(WTStruct.isA(wts)).
+ assert(wts instanceof WTStruct).
+ assert(wts instanceof StructType).
+ assert(StructType.isA(wts)).
+ assert(wts.pointer>0).assert(0===wts.$v4).assert(0n===wts.$v8).
+ assert(0===wts.$ppV).assert(0===wts.$xFunc);
+ const testFunc =
+ W.xGet('sqlite3__wasm_test_struct'/*name gets mangled in -O3 builds!*/);
+ let counter = 0;
+ //log("wts.pointer =",wts.pointer);
+ const wtsFunc = function(arg){
+ /*log("This from a JS function called from C, "+
"which itself was called from JS. arg =",arg);*/
- ++counter;
- if(3===counter){
- tossQuietly("Testing exception propagation.");
+ ++counter;
+ if(3===counter){
+ tossQuietly("Testing exception propagation.");
+ }
}
+ wts.$v4 = 10; wts.$v8 = 20;
+ wts.$xFunc = W.installFunction(wtsFunc, wts.memberSignature('xFunc'))
+ T.assert(0===counter).assert(10 === wts.$v4).assert(20n === wts.$v8)
+ .assert(0 === wts.$ppV).assert('number' === typeof wts.$xFunc)
+ .assert(0 === wts.$cstr)
+ .assert(wts.memberIsString('$cstr'))
+ .assert(!wts.memberIsString('$v4'))
+ .assert(null === wts.memberToJsString('$cstr'))
+ .assert(W.functionEntry(wts.$xFunc) instanceof Function);
+ /* It might seem silly to assert that the values match
+ what we just set, but recall that all of those property
+ reads and writes are, via property interceptors,
+ actually marshaling their data to/from a raw memory
+ buffer, so merely reading them back is actually part of
+ testing the struct-wrapping API. */
+
+ testFunc(wts.pointer);
+ //log("wts.pointer, wts.$ppV",wts.pointer, wts.$ppV);
+ T.assert(1===counter).assert(20 === wts.$v4).assert(40n === wts.$v8)
+ .assert(wts.$ppV === wts.pointer)
+ .assert('string' === typeof wts.memberToJsString('cstr'))
+ .assert(wts.memberToJsString('cstr') === wts.memberToJsString('$cstr'))
+ .mustThrowMatching(()=>wts.memberToJsString('xFunc'),
+ /Invalid member type signature for C-string/)
+ ;
+ testFunc(wts.pointer);
+ T.assert(2===counter).assert(40 === wts.$v4).assert(80n === wts.$v8)
+ .assert(wts.$ppV === wts.pointer);
+ /** The 3rd call to wtsFunc throw from JS, which is called
+ from C, which is called from JS. Let's ensure that
+ that exception propagates back here... */
+ T.mustThrowMatching(()=>testFunc(wts.pointer),/^Testing/);
+ W.uninstallFunction(wts.$xFunc);
+ wts.$xFunc = 0;
+ wts.$ppV = 0;
+ T.assert(!wts.$ppV);
+ //WTStruct.debugFlags(0x03);
+ wts.$ppV = wts;
+ T.assert(wts.pointer === wts.$ppV)
+ wts.setMemberCString('cstr', "A C-string.");
+ T.assert(Array.isArray(wts.ondispose)).
+ assert(wts.ondispose[0] === wts.$cstr).
+ assert('A C-string.' === wts.memberToJsString('cstr'));
+ const ptr = wts.pointer;
+ wts.dispose();
+ T.assert(ptr).assert(undefined === wts.pointer);
+ }finally{
+ wts.dispose();
}
- wts.$v4 = 10; wts.$v8 = 20;
- wts.$xFunc = W.installFunction(wtsFunc, wts.memberSignature('xFunc'))
- T.assert(0===counter).assert(10 === wts.$v4).assert(20n === wts.$v8)
- .assert(0 === wts.$ppV).assert('number' === typeof wts.$xFunc)
- .assert(0 === wts.$cstr)
- .assert(wts.memberIsString('$cstr'))
- .assert(!wts.memberIsString('$v4'))
- .assert(null === wts.memberToJsString('$cstr'))
- .assert(W.functionEntry(wts.$xFunc) instanceof Function);
- /* It might seem silly to assert that the values match
- what we just set, but recall that all of those property
- reads and writes are, via property interceptors,
- actually marshaling their data to/from a raw memory
- buffer, so merely reading them back is actually part of
- testing the struct-wrapping API. */
-
- testFunc(wts.pointer);
- //log("wts.pointer, wts.$ppV",wts.pointer, wts.$ppV);
- T.assert(1===counter).assert(20 === wts.$v4).assert(40n === wts.$v8)
- .assert(wts.$ppV === wts.pointer)
- .assert('string' === typeof wts.memberToJsString('cstr'))
- .assert(wts.memberToJsString('cstr') === wts.memberToJsString('$cstr'))
- .mustThrowMatching(()=>wts.memberToJsString('xFunc'),
- /Invalid member type signature for C-string/)
- ;
- testFunc(wts.pointer);
- T.assert(2===counter).assert(40 === wts.$v4).assert(80n === wts.$v8)
- .assert(wts.$ppV === wts.pointer);
- /** The 3rd call to wtsFunc throw from JS, which is called
- from C, which is called from JS. Let's ensure that
- that exception propagates back here... */
- T.mustThrowMatching(()=>testFunc(wts.pointer),/^Testing/);
- W.uninstallFunction(wts.$xFunc);
- wts.$xFunc = 0;
- wts.$ppV = 0;
- T.assert(!wts.$ppV);
- //WTStruct.debugFlags(0x03);
- wts.$ppV = wts;
- T.assert(wts.pointer === wts.$ppV)
- wts.setMemberCString('cstr', "A C-string.");
- T.assert(Array.isArray(wts.ondispose)).
- assert(wts.ondispose[0] === wts.$cstr).
- assert('A C-string.' === wts.memberToJsString('cstr'));
- const ptr = wts.pointer;
- wts.dispose();
- T.assert(ptr).assert(undefined === wts.pointer);
- }finally{
- wts.dispose();
- }
- if(1){ // ondispose of other struct instances
- const s1 = new WTStruct, s2 = new WTStruct, s3 = new WTStruct;
- T.assert(s1.lookupMember instanceof Function)
- .assert(s1.addOnDispose instanceof Function);
- s1.addOnDispose(s2,"testing variadic args");
- T.assert(2===s1.ondispose.length);
- s2.addOnDispose(s3);
- s1.dispose();
- T.assert(!s2.pointer,"Expecting s2 to be ondispose'd by s1.");
- T.assert(!s3.pointer,"Expecting s3 to be ondispose'd by s2.");
+ if(1){ // ondispose of other struct instances
+ const s1 = new WTStruct, s2 = new WTStruct, s3 = new WTStruct;
+ T.assert(s1.lookupMember instanceof Function)
+ .assert(s1.addOnDispose instanceof Function);
+ s1.addOnDispose(s2,"testing variadic args");
+ T.assert(2===s1.ondispose.length);
+ s2.addOnDispose(s3);
+ s1.dispose();
+ T.assert(!s2.pointer,"Expecting s2 to be ondispose'd by s1.");
+ T.assert(!s3.pointer,"Expecting s3 to be ondispose'd by s2.");
+ }
}
}/*StructBinder*/)
////////////////////////////////////////////////////////////////////////
T.g('sqlite3.oo1')
- .t('Create db', function(sqlite3){
- const dbFile = '/tester1.db';
- sqlite3.util.sqlite3__wasm_vfs_unlink(0, dbFile);
- const db = this.db = new sqlite3.oo1.DB(dbFile, 0 ? 'ct' : 'c');
- db.onclose = {
- disposeAfter: [],
- disposeBefore: [
- (db)=>{
- //console.debug("db.onclose.before dropping modules");
- //sqlite3.capi.sqlite3_drop_modules(db.pointer, 0);
- }
- ],
- before: function(db){
- while(this.disposeBefore.length){
- const v = this.disposeBefore.shift();
- console.debug("db.onclose.before cleaning up:",v);
- if(wasm.isPtr(v)) wasm.dealloc(v);
- else if(v instanceof sqlite3.StructBinder.StructType){
- v.dispose();
- }else if(v instanceof Function){
- try{ v(db) } catch(e){
- console.warn("beforeDispose() callback threw:",e);
+ .t({
+ name:'Create db',
+ //predicate: (sqlite3)=>
+ test: function(sqlite3){
+ const dbFile = '/tester1.db';
+ sqlite3.util.sqlite3__wasm_vfs_unlink(0, dbFile);
+ const db = this.db = new sqlite3.oo1.DB(dbFile, 0 ? 'ct' : 'c');
+ db.onclose = {
+ disposeAfter: [],
+ disposeBefore: [
+ (db)=>{
+ //console.debug("db.onclose.before dropping modules");
+ //sqlite3.capi.sqlite3_drop_modules(db.pointer, 0);
+ }
+ ],
+ before: function(db){
+ while(this.disposeBefore.length){
+ const v = this.disposeBefore.shift();
+ console.debug("db.onclose.before cleaning up:",v);
+ if(wasm.isPtr(v)) wasm.dealloc(v);
+ else if(v instanceof sqlite3.StructBinder.StructType){
+ v.dispose();
+ }else if(v instanceof Function){
+ try{ v(db) } catch(e){
+ console.warn("beforeDispose() callback threw:",e);
+ }
}
}
- }
- },
- after: function(){
- while(this.disposeAfter.length){
- const v = this.disposeAfter.shift();
- console.debug("db.onclose.after cleaning up:",v);
- if(wasm.isPtr(v)) wasm.dealloc(v);
- else if(v instanceof sqlite3.StructBinder.StructType){
- v.dispose();
- }else if(v instanceof Function){
- try{v()} catch(e){/*ignored*/}
+ },
+ after: function(){
+ while(this.disposeAfter.length){
+ const v = this.disposeAfter.shift();
+ console.debug("db.onclose.after cleaning up:",v);
+ if(wasm.isPtr(v)) wasm.dealloc(v);
+ else if(v instanceof sqlite3.StructBinder.StructType){
+ v.dispose();
+ }else if(v instanceof Function){
+ try{v()} catch(e){/*ignored*/}
+ }
}
}
- }
- };
-
- T.assert(wasm.isPtr(db.pointer))
- .mustThrowMatching(()=>db.pointer=1, /read-only/)
- .assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1))
- .assert('main'===db.dbName(0))
- .assert('string' === typeof db.dbVfsName())
- .assert(db.pointer === wasm.xWrap.testConvertArg('sqlite3*',db));
- // Custom db error message handling via sqlite3_prepare_v2/v3()
- let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
- T.assert(capi.SQLITE_MISUSE === rc)
- .assert(0 === capi.sqlite3_errmsg(db.pointer).indexOf("Invalid SQL"))
- .assert(dbFile === db.dbFilename())
- .assert(!db.dbFilename('nope'));
- //Sanity check DB.checkRc()...
- let ex;
- try{db.checkRc(rc)}
- catch(e){ex = e}
- T.assert(ex instanceof sqlite3.SQLite3Error)
- .assert(capi.SQLITE_MISUSE===ex.resultCode)
- .assert(0===ex.message.indexOf("SQLITE_MISUSE: sqlite3 result code"))
- .assert(ex.message.indexOf("Invalid SQL")>0);
- T.assert(db === db.checkRc(0))
- .assert(db === sqlite3.oo1.DB.checkRc(db,0))
- .assert(null === sqlite3.oo1.DB.checkRc(null,0));
+ };
- this.progressHandlerCount = 0;
- capi.sqlite3_progress_handler(db, 5, (p)=>{
- ++this.progressHandlerCount;
- return 0;
- }, 0);
+ T.assert(wasm.isPtr(db.pointer))
+ .mustThrowMatching(()=>db.pointer=1, /read-only/)
+ .assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1))
+ .assert('main'===db.dbName(0))
+ .assert('string' === typeof db.dbVfsName())
+ .assert(db.pointer === wasm.xWrap.testConvertArg('sqlite3*',db));
+ // Custom db error message handling via sqlite3_prepare_v2/v3()
+ let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
+ T.assert(capi.SQLITE_MISUSE === rc)
+ .assert(0 === capi.sqlite3_errmsg(db.pointer).indexOf("Invalid SQL"))
+ .assert(dbFile === db.dbFilename())
+ .assert(!db.dbFilename('nope'));
+ //Sanity check DB.checkRc()...
+ let ex;
+ try{db.checkRc(rc)}
+ catch(e){ex = e}
+ T.assert(ex instanceof sqlite3.SQLite3Error)
+ .assert(capi.SQLITE_MISUSE===ex.resultCode)
+ .assert(0===ex.message.indexOf("SQLITE_MISUSE: sqlite3 result code"))
+ .assert(ex.message.indexOf("Invalid SQL")>0);
+ T.assert(db === db.checkRc(0))
+ .assert(db === sqlite3.oo1.DB.checkRc(db,0))
+ .assert(null === sqlite3.oo1.DB.checkRc(null,0));
+
+ this.progressHandlerCount = 0;
+ if( wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK') ){
+ T.assert( !capi.sqlite3_progress_handler );
+ }else{
+ T.assert( capi.sqlite3_progress_handler );
+ capi.sqlite3_progress_handler(db, 5, (p)=>{
+ ++this.progressHandlerCount;
+ return 0;
+ }, 0);
+ }
+ }
})
////////////////////////////////////////////////////////////////////
.t('sqlite3_db_config() and sqlite3_db_status()', function(sqlite3){
new TextEncoder('utf-8').encode("select 3 as a")
);
//debug("statement =",st);
- this.progressHandlerCount = 0;
+ T.assert( !this.progressHandlerCount );
let rc;
try {
T.assert(wasm.isPtr(st.pointer))
st, capi.SQLITE_STMTSTATUS_RUN, 0
) > 0);
- T.assert(this.progressHandlerCount > 0,
+ T.assert(this.progressHandlerCount>0
+ || wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK'),
"Expecting progress callback.").
assert(0===capi.sqlite3_strglob("*.txt", "foo.txt")).
assert(0!==capi.sqlite3_strglob("*.txt", "foo.xtx")).
.assert(2 === list.length)
.assert('string'===typeof list[1])
.assert(3===db.changes())
- .assert(this.progressHandlerCount > 0,
+ .assert(this.progressHandlerCount > 0
+ || wasm.compileOptionUsed('OMIT_PROGRESS_CALLBACK'),
"Expecting progress callback.")
if(wasm.bigIntEnabled){
T.assert(3n===db.changes(false,true));
////////////////////////////////////////////////////////////////////
.t({
name: 'Window UDFs',
- //predicate: ()=>false,
+ predicate: (sqlite3)=>!!sqlite3.wasm.exports.sqlite3_create_window_function
+ /*!sqlite3.wasm.compileOptionUsed('OMIT_WINDOWFUNC')*/
+ || "Missing window functions",
test: function(){
/* Example window function, table, and results taken from:
https://sqlite.org/windowfunctions.html#udfwinfunc */
]);
T.assert(2 === u1.getFileCount() /* one is the journal file */)
.assert(3 === db.selectValue('select count(*) from t'))
- .assert('wal'===db.selectValue('pragma journal_mode'));
+ .assert(
+ 'wal'===db.selectValue('pragma journal_mode')
+ || wasm.compileOptionUsed('OMIT_WAL')
+ );
db.close();
T.assert(1 === u1.getFileCount());
db = new u2.OpfsSAHPoolDb(dbName);
-C More\swork\son\sthe\sminimal-mode\swasm\sbuild\s(now\s603kb\suncompressed).\sRemove\sthe\shard-coded\sfeature-enable\sflags\sfrom\ssqlite3-wasm.c\sand\srely\son\sthe\sbuild\sto\sprovide\sthem.\sSome\swasm\sbuild\scleanup,\sbut\sattempts\sto\scompletely\soverhaul\sit\shave\sbeen\sthwarted\sby\smy\sinability\sto\smake\sscript-generated\smakefile\scode\smore\slegible/maintainable\sthan\sthe\scurrent\seval\sspaghetti.
-D 2024-07-25T14:00:26.899
+C Strip\sprogress\shandlers\sand\swindow\sfunctions\sfrom\sthe\swasm\sbare-bones\s(formerly\s'minimal')\sJS\sbits,\snoting\sthat\swe\scan't\syet\suse\sOMIT_WINDOWFUNC\s(for\sthe\sC\sparts)\swithout\sa\scustom\samalgamation.\sCurrently\sat\s604kb.
+D 2024-07-25T16:21:19.087
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/userauth/user-auth.txt ca7e9ee82ca4e1c1744295f8184dd70edfae1992865d26c64303f539eb6c084c
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
-F ext/wasm/GNUmakefile c89b6d0e7f969de03cfcbd5d5f64985ee9ba823a7be6b150fb9c2976c7adb0d6
+F ext/wasm/GNUmakefile 1857ad71bfdc780019639f49dc054fee491b4ddba2669898b8acfd4ffba50030
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638
F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
-F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core 38f85e6ec5f9c776087bc38aef9ef35eeb7e54942ddb1dd04e9ac0122958b741
-F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras 2a8c9f7d865cc6e5661b2cd40a45e963a1f8070a88def6ead4c40d4fa0c91998
+F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-core 2bcbbfe3b95c043ed6037e2708a2ee078d212dd1612c364f93588d8dc97300fe
+F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-extras fe40d6d758646e38f8b15f709044951e10884214f5453d35502100179c388c13
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73
F ext/wasm/api/post-js-header.js 04dc12c3edd666b64a1b4ef3b6690c88dcc653f26451fd4734472d8e29c1c122
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
-F ext/wasm/api/sqlite3-api-glue.c-pp.js 12f6f3840afdf8ff7a4374dc1a96a26bcc369e17853e0fe917c38f4d66c6e2d8
+F ext/wasm/api/sqlite3-api-glue.c-pp.js fb6dbfe692cc23000a65a4cd95a1a47ed5eb592dc9d8b55363b3c2952a787244
F ext/wasm/api/sqlite3-api-oo1.c-pp.js f3a8e2004c6625d17946c11f2fb32008be78bc5207bf746fc77d59848813225f
F ext/wasm/api/sqlite3-api-prologue.js 6f1257e04885632ed9f44d43aba200b86e0bc16709ffdba29abbbeb1bc8e8b76
F ext/wasm/api/sqlite3-api-worker1.c-pp.js 5cc22a3c0d52828cb32aad8691488719f47d27567e63e8bc8b832d74371c352d
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js e529a99b7d5a088284821e2902b20d3404b561126969876997d5a73a656c9199
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e99e3d99f736937914527070f00ab13e9391d3f1cef884ab99a64cbcbee8d675
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js e809739d71e8b35dfe1b55d24d91f02d04239e6aef7ca1ea92a15a29e704f616
-F ext/wasm/api/sqlite3-wasm.c 79335b70d4d404b33fb485a4f65422a1ded0977c38e3b1a0cd8e26b49d3c9fba
+F ext/wasm/api/sqlite3-wasm.c 83f5e9f998e9fa4261eb84e9f092210e3ffe03895119f5ded0429eb34ab9d2be
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 46f303ba8ddd1b2f0a391798837beddfa72e8c897038c8047eda49ce7d5ed46b
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
F ext/wasm/batch-runner-sahpool.html e9a38fdeb36a13eac7b50241dfe7ae066fe3f51f5c0b0151e7baee5fce0d07a7
F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef
F ext/wasm/dist.make 653e212c1e84aa3be168d62a10616ccea45ee9585b0192745d2706707a5248ce
F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
-F ext/wasm/fiddle.make 2406b02473878a99fb6a2eaff0923277017adc45eb041b2afb2d7707bf7b375c
+F ext/wasm/fiddle.make b3b118516ed581cdf2c16de8eb1672427320e67ff19d710a09c891e895883644
F ext/wasm/fiddle/fiddle-worker.js 850e66fce39b89d59e161d1abac43a181a4caa89ddeea162765d660277cd84ce
F ext/wasm/fiddle/fiddle.js b444a5646a9aac9f3fc06c53d78af5e1912eb235d69a8e6010723e4eb0e9d4a1
F ext/wasm/fiddle/index.html 739e0b75bc592679665d25e2f7649d2b8b2db678f3b41a772a8720b609b8482d
F ext/wasm/test-opfs-vfs.js 1618670e466f424aa289859fe0ec8ded223e42e9e69b5c851f809baaaca1a00c
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
-F ext/wasm/tester1.c-pp.js 7d0eba1496286338770133356488b4415de7970f4ee2c08f7f587bb18d8b6b0b
+F ext/wasm/tester1.c-pp.js eb56110cd1959fc72c4001decc066ac7978912304e08aa402ca76527007cea5a
F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e
F ext/wasm/tests/opfs/concurrency/test.js d08889a5bb6e61937d0b8cbb78c9efbefbf65ad09f510589c779b7cc6a803a88
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P ed746b3dd3248b68cb91de50ac5ba5fd3a7c2fcbde76324e86b88edbfecd896b
-R acaefae7f2493e8276236de40774aafc
+P b029c4067943e366a9b25b8303136fab10822bd771ea4658ac4cd716ff4a0d8f
+R 4aba6600c1b56bb40f0e32cfcacb9fbe
U stephan
-Z 2f4bcd240a0ced338bed244e56f0f58c
+Z c6f1d9cf14c3543f4f2774a34de2bf76
# Remove this line to create a well-formed Fossil manifest.
-b029c4067943e366a9b25b8303136fab10822bd771ea4658ac4cd716ff4a0d8f
+ec02e9237e1ef81c4196fa630822cb109eab926143ad09593a24273eb0668601