1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge the latest trunk changes into the reuse-schema branch.

FossilOrigin-Name: 858163f93893b0f481b27e39f4f7b3f51290606ad96e5f38cea2933c92398ff2
This commit is contained in:
drh
2025-02-03 15:17:31 +00:00
99 changed files with 4198 additions and 2607 deletions

View File

@@ -85,17 +85,18 @@ browser client:
Installs the `sqlite3.vtab` namespace, which contain helpers for use
by downstream code which creates `sqlite3_module` implementations.
- **`sqlite3-vfs-opfs.c-pp.js`**\
is an sqlite3 VFS implementation which supports the Origin-Private
FileSystem (OPFS) as a storage layer to provide persistent storage
for database files in a browser. It requires...
is an sqlite3 VFS implementation which supports the [Origin-Private
FileSystem (OPFS)][OPFS] as a storage layer to provide persistent
storage for database files in a browser. It requires...
- **`sqlite3-opfs-async-proxy.js`**\
is the asynchronous backend part of the OPFS proxy. It speaks
directly to the (async) OPFS API and channels those results back
to its synchronous counterpart. This file, because it must be
started in its own Worker, is not part of the amalgamation.
is the asynchronous backend part of the [OPFS][] proxy. It
speaks directly to the (async) OPFS API and channels those
results back to its synchronous counterpart. This file, because
it must be started in its own Worker, is not part of the
amalgamation.
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**\
is another sqlite3 VFS supporting the OPFS, but uses a completely
different approach that the above-listed one.
is another sqlite3 VFS supporting the [OPFS][], but uses a
completely different approach that the above-listed one.
- **`sqlite3-api-cleanup.js`**\
The previous files do not immediately extend the library. Instead
they add callback functions to be called during its
@@ -152,7 +153,7 @@ into the build-generated `sqlite3.js` along with `sqlite3-api.js`.
flag. This file overwrites the Emscripten-installed
`sqlite3InitModule()` function with one which, after the module is
loaded, also initializes the asynchronous parts of the sqlite3
module. For example, the OPFS VFS support.
module. For example, the [OPFS][] VFS support.
<a id='c-pp'></a>
Preprocessing of Source Files
@@ -164,3 +165,6 @@ builds. The preprocessor application itself is in
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
of such preprocessing are maintained in
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
[OPFS]: https://developer.mozilla.org/en-US/docs/Web/API/File_System_API/Origin_private_file_system

View File

@@ -12,6 +12,7 @@
const toExportForESM =
//#endif
(function(){
//console.warn("this is extern-post-js");
/**
In order to hide the sqlite3InitModule()'s resulting
Emscripten module from downstream clients (and simplify our
@@ -62,6 +63,16 @@ const toExportForESM =
globalThis.sqlite3InitModule = function ff(...args){
//console.warn("Using replaced sqlite3InitModule()",globalThis.location);
return originalInit(...args).then((EmscriptenModule)=>{
//console.warn("originalInit() then() arg =",EmscriptenModule);
//console.warn("initModuleState =",initModuleState);
EmscriptenModule.runSQLite3PostLoadInit(EmscriptenModule);
const s = EmscriptenModule.sqlite3;
s.scriptInfo = initModuleState;
//console.warn("sqlite3.scriptInfo =",s.scriptInfo);
if(ff.__isUnderTest) s.__isUnderTest = true;
const f = s.asyncPostInit;
delete s.asyncPostInit;
const rv = f();
//#if wasmfs
if('undefined'!==typeof WorkerGlobalScope &&
EmscriptenModule['ENVIRONMENT_IS_PTHREAD']){
@@ -74,14 +85,7 @@ const toExportForESM =
return EmscriptenModule;
}
//#endif
//console.warn("sqlite3InitModule() returning sqlite3 object.");
const s = EmscriptenModule.sqlite3;
s.scriptInfo = initModuleState;
//console.warn("sqlite3.scriptInfo =",s.scriptInfo);
if(ff.__isUnderTest) s.__isUnderTest = true;
const f = s.asyncPostInit;
delete s.asyncPostInit;
return f();
return rv;
}).catch((e)=>{
console.error("Exception loading sqlite3 module:",e);
throw e;

View File

@@ -1,4 +1,6 @@
/* The current function scope was opened via post-js-header.js, which
gets prepended to this at build-time. This file closes that
scope. */
})/*postRun.push(...)*/;
//console.warn("This is the end of the Module.runSQLite3PostLoadInit handler.");
}/*Module.runSQLite3PostLoadInit()*/;
//console.warn("This is the end of the setup of the (pending) Module.runSQLite3PostLoadInit");

View File

@@ -7,17 +7,22 @@
installs will be run after the WASM module is loaded, at which
point the sqlite3 JS API bits will get set up.
*/
if(!Module.postRun) Module.postRun = [];
Module.postRun.push(function(Module/*the Emscripten-style module object*/){
Module.runSQLite3PostLoadInit = function(EmscriptenModule/*the Emscripten-style module object*/){
/** ^^^ As don't use Module.postRun, as that runs a different time
depending on whether this file is built with emcc 3.1.x or
4.0.x. This function name is intentionally obnoxiously verbose to
ensure that we don't collide with current and future Emscripten
symbol names. */
'use strict';
//console.warn("This is the start of the Module.postRun handler.");
/* This function will contain at least the following:
- post-js-header.js (this file)
- sqlite3-api-prologue.js => Bootstrapping bits to attach the rest to
- common/whwasmutil.js => Replacements for much of Emscripten's glue
- jaccwaby/jaccwabyt.js => Jaccwabyt (C/JS struct binding)
- jaccwabyt/jaccwabyt.js => Jaccwabyt (C/JS struct binding)
- sqlite3-api-glue.js => glues previous parts together
- sqlite3-api-oo.js => SQLite3 OO API #1
- sqlite3-api-oo1.js => SQLite3 OO API #1
- sqlite3-api-worker1.js => Worker-based API
- sqlite3-vfs-helper.c-pp.js => Utilities for VFS impls
- sqlite3-vtab-helper.c-pp.js => Utilities for virtual table impls

View File

@@ -14,6 +14,9 @@
intended to be appended after all other sqlite3-api-*.js files so
that it can finalize any setup and clean up any global symbols
temporarily used for setting up the API's various subsystems.
In Emscripten builds it's run in the context of a Module.postRun
handler.
*/
'use strict';
if('undefined' !== typeof Module){ // presumably an Emscripten build

View File

@@ -228,11 +228,36 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}),
'*'
]],
/**
2025-02-03: We do not have a way to automatically clean up
destructors which are automatically converted from JS functions
via the final argument to sqlite3_set_auxdata(). Because of
that, it is strongly recommended that clients use
wasm.installFunction() to create such callbacks, then pass that
pointer to sqlite3_set_auxdata(). Relying on automated
conversions here will lead to leaks of JS/WASM proxy functions
because sqlite3_set_auxdata() is frequently called in UDFs.
The sqlite3.oo1.DB class's onclose handlers can be used for this
purpose. For example:
const pAuxDtor = wasm.installFunction('v(p)', function(ptr){
//free ptr
});
myDb.onclose = {
after: ()=>{
wasm.uninstallFunction(pAuxDtor);
}
};
Then pass pAuxDtor as the final argument to appropriate
sqlite3_set_auxdata() calls.
*/
["sqlite3_set_auxdata", undefined, [
"sqlite3_context*", "int", "*",
new wasm.xWrap.FuncPtrAdapter({
name: 'xDestroyAuxData',
signature: 'v(*)',
signature: 'v(p)',
contextKey: (argv, argIndex)=>argv[0/* sqlite3_context* */]
})
]],
@@ -1047,6 +1072,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
'sqlite3_set_authorizer',
'sqlite3_trace_v2',
'sqlite3_update_hook'
/*
We do not yet have a way to clean up automatically-converted
sqlite3_set_auxdata() finalizers.
*/
]) {
const x = wasm.exports[name];
if( !x ){

View File

@@ -12,12 +12,12 @@
This file is intended to be combined at build-time with other
related code, most notably a header and footer which wraps this
whole file into an Emscripten Module.postRun() handler. The sqlite3
JS API has no hard requirements on Emscripten and does not expose
any Emscripten APIs to clients. It is structured such that its build
can be tweaked to include it in arbitrary WASM environments which
can supply the necessary underlying features (e.g. a POSIX file I/O
layer).
whole file into an Emscripten Module.postRun()-style handler. The
sqlite3 JS API has no hard requirements on Emscripten and does not
expose any Emscripten APIs to clients. It is structured such that
its build can be tweaked to include it in arbitrary WASM
environments which can supply the necessary underlying features
(e.g. a POSIX file I/O layer).
Main project home page: https://sqlite.org
@@ -1712,41 +1712,48 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
missing or falsy pointer argument as 0.
*/
capi.sqlite3_db_config = function(pDb, op, ...args){
if(!this.s){
this.s = wasm.xWrap('sqlite3__wasm_db_config_s','int',
['sqlite3*', 'int', 'string:static']
/* MAINDBNAME requires a static string */);
this.pii = wasm.xWrap('sqlite3__wasm_db_config_pii', 'int',
['sqlite3*', 'int', '*','int', 'int']);
this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int',
['sqlite3*', 'int', 'int','*']);
}
switch(op){
case capi.SQLITE_DBCONFIG_ENABLE_FKEY:
case capi.SQLITE_DBCONFIG_ENABLE_TRIGGER:
case capi.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER:
case capi.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION:
case capi.SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE:
case capi.SQLITE_DBCONFIG_ENABLE_QPSG:
case capi.SQLITE_DBCONFIG_TRIGGER_EQP:
case capi.SQLITE_DBCONFIG_RESET_DATABASE:
case capi.SQLITE_DBCONFIG_DEFENSIVE:
case capi.SQLITE_DBCONFIG_WRITABLE_SCHEMA:
case capi.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE:
case capi.SQLITE_DBCONFIG_DQS_DML:
case capi.SQLITE_DBCONFIG_DQS_DDL:
case capi.SQLITE_DBCONFIG_ENABLE_VIEW:
case capi.SQLITE_DBCONFIG_LEGACY_FILE_FORMAT:
case capi.SQLITE_DBCONFIG_TRUSTED_SCHEMA:
case capi.SQLITE_DBCONFIG_STMT_SCANSTATUS:
case capi.SQLITE_DBCONFIG_REVERSE_SCANORDER:
return this.ip(pDb, op, args[0], args[1] || 0);
case capi.SQLITE_DBCONFIG_LOOKASIDE:
return this.pii(pDb, op, args[0], args[1], args[2]);
case capi.SQLITE_DBCONFIG_MAINDBNAME:
return this.s(pDb, op, args[0]);
default:
return capi.SQLITE_MISUSE;
case capi.SQLITE_DBCONFIG_ENABLE_FKEY:
case capi.SQLITE_DBCONFIG_ENABLE_TRIGGER:
case capi.SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER:
case capi.SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION:
case capi.SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE:
case capi.SQLITE_DBCONFIG_ENABLE_QPSG:
case capi.SQLITE_DBCONFIG_TRIGGER_EQP:
case capi.SQLITE_DBCONFIG_RESET_DATABASE:
case capi.SQLITE_DBCONFIG_DEFENSIVE:
case capi.SQLITE_DBCONFIG_WRITABLE_SCHEMA:
case capi.SQLITE_DBCONFIG_LEGACY_ALTER_TABLE:
case capi.SQLITE_DBCONFIG_DQS_DML:
case capi.SQLITE_DBCONFIG_DQS_DDL:
case capi.SQLITE_DBCONFIG_ENABLE_VIEW:
case capi.SQLITE_DBCONFIG_LEGACY_FILE_FORMAT:
case capi.SQLITE_DBCONFIG_TRUSTED_SCHEMA:
case capi.SQLITE_DBCONFIG_STMT_SCANSTATUS:
case capi.SQLITE_DBCONFIG_REVERSE_SCANORDER:
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE:
case capi.SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE:
case capi.SQLITE_DBCONFIG_ENABLE_COMMENTS:
if( !this.ip ){
this.ip = wasm.xWrap('sqlite3__wasm_db_config_ip','int',
['sqlite3*', 'int', 'int', '*']);
}
return this.ip(pDb, op, args[0], args[1] || 0);
case capi.SQLITE_DBCONFIG_LOOKASIDE:
if( !this.pii ){
this.pii = wasm.xWrap('sqlite3__wasm_db_config_pii', 'int',
['sqlite3*', 'int', '*', 'int', 'int']);
}
return this.pii(pDb, op, args[0], args[1], args[2]);
case capi.SQLITE_DBCONFIG_MAINDBNAME:
if(!this.s){
this.s = wasm.xWrap('sqlite3__wasm_db_config_s','int',
['sqlite3*', 'int', 'string:static']
/* MAINDBNAME requires a static string */);
}
return this.s(pDb, op, args[0]);
default:
return capi.SQLITE_MISUSE;
}
}.bind(Object.create(null));

View File

@@ -331,7 +331,6 @@ SQLITE_WASM_EXPORT void sqlite3__wasm_pstack_restore(unsigned char * p){
*/
SQLITE_WASM_EXPORT void * sqlite3__wasm_pstack_alloc(int n){
if( n<=0 ) return 0;
//if( n & 0x7 ) n += 8 - (n & 0x7) /* align to 8-byte boundary */;
n = (n + 7) & ~7 /* align to 8-byte boundary */;
if( PStack.pBegin + n > PStack.pPos /*not enough space left*/
|| PStack.pBegin + n <= PStack.pBegin /*overflow*/ ) return 0;
@@ -597,6 +596,9 @@ const char * sqlite3__wasm_enum_json(void){
DefInt(SQLITE_DBCONFIG_TRUSTED_SCHEMA);
DefInt(SQLITE_DBCONFIG_STMT_SCANSTATUS);
DefInt(SQLITE_DBCONFIG_REVERSE_SCANORDER);
DefInt(SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE);
DefInt(SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE);
DefInt(SQLITE_DBCONFIG_ENABLE_COMMENTS);
DefInt(SQLITE_DBCONFIG_MAX);
} _DefGroup;
@@ -1630,6 +1632,9 @@ int sqlite3__wasm_db_config_ip(sqlite3 *pDb, int op, int arg1, int* pArg2){
case SQLITE_DBCONFIG_TRUSTED_SCHEMA:
case SQLITE_DBCONFIG_STMT_SCANSTATUS:
case SQLITE_DBCONFIG_REVERSE_SCANORDER:
case SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE:
case SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE:
case SQLITE_DBCONFIG_ENABLE_COMMENTS:
return sqlite3_db_config(pDb, op, arg1, pArg2);
default: return SQLITE_MISUSE;
}