mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Minor cleanups, reorgs, and doc updates for the JS APIs. Renamed sqlite3(-api)-worker.js to sqlite3(-api)-worker1.js, for symmetry with sqlite3-api-oo1.js.
FossilOrigin-Name: f5059ee6f9fc55a381cbf08a30dfb9a5636c0b44341e42f4e9f12a3b109b5507
This commit is contained in:
@ -128,7 +128,7 @@ sqlite3-api.jses := \
|
|||||||
$(dir.jacc)/jaccwabyt.js \
|
$(dir.jacc)/jaccwabyt.js \
|
||||||
$(dir.api)/sqlite3-api-glue.js \
|
$(dir.api)/sqlite3-api-glue.js \
|
||||||
$(dir.api)/sqlite3-api-oo1.js \
|
$(dir.api)/sqlite3-api-oo1.js \
|
||||||
$(dir.api)/sqlite3-api-worker.js
|
$(dir.api)/sqlite3-api-worker1.js
|
||||||
#sqlite3-api.jses += $(dir.api)/sqlite3-api-opfs.js
|
#sqlite3-api.jses += $(dir.api)/sqlite3-api-opfs.js
|
||||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
|
sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
|
||||||
|
|
||||||
|
@ -60,17 +60,17 @@ browser client:
|
|||||||
high-level sqlite3 JS wrappers and should feel relatively familiar
|
high-level sqlite3 JS wrappers and should feel relatively familiar
|
||||||
to anyone familiar with such APIs. That said, it is not a "required
|
to anyone familiar with such APIs. That said, it is not a "required
|
||||||
component" and can be elided from builds which do not want it.
|
component" and can be elided from builds which do not want it.
|
||||||
- `sqlite3-api-worker.js`\
|
- `sqlite3-api-worker1.js`\
|
||||||
A Worker-thread-based API which uses OO API #1 to provide an
|
A Worker-thread-based API which uses OO API #1 to provide an
|
||||||
interface to a database which can be driven from the main Window
|
interface to a database which can be driven from the main Window
|
||||||
thread via the Worker message-passing interface. Like OO API #1,
|
thread via the Worker message-passing interface. Like OO API #1,
|
||||||
this is an optional component, offering one of any number of
|
this is an optional component, offering one of any number of
|
||||||
potential implementations for such an API.
|
potential implementations for such an API.
|
||||||
- `sqlite3-worker.js`\
|
- `sqlite3-worker1.js`\
|
||||||
Is not part of the amalgamated sources and is intended to be
|
Is not part of the amalgamated sources and is intended to be
|
||||||
loaded by a client Worker thread. It loads the sqlite3 module
|
loaded by a client Worker thread. It loads the sqlite3 module
|
||||||
and runs the Worker API which is implemented in
|
and runs the Worker #1 API which is implemented in
|
||||||
`sqlite3-api-worker.js`.
|
`sqlite3-api-worker1.js`.
|
||||||
- `sqlite3-api-opfs.js`\
|
- `sqlite3-api-opfs.js`\
|
||||||
is an in-development/experimental sqlite3 VFS wrapper, the goal of
|
is an in-development/experimental sqlite3 VFS wrapper, the goal of
|
||||||
which being to use Google Chrome's Origin-Private FileSystem (OPFS)
|
which being to use Google Chrome's Origin-Private FileSystem (OPFS)
|
||||||
|
@ -128,7 +128,7 @@
|
|||||||
*/
|
*/
|
||||||
__prepare.basic = wasm.xWrap('sqlite3_prepare_v3',
|
__prepare.basic = wasm.xWrap('sqlite3_prepare_v3',
|
||||||
"int", ["sqlite3*", "string",
|
"int", ["sqlite3*", "string",
|
||||||
"int"/*MUST always be negative*/,
|
"int"/*ignored for this impl!*/,
|
||||||
"int", "**",
|
"int", "**",
|
||||||
"**"/*MUST be 0 or null or undefined!*/]);
|
"**"/*MUST be 0 or null or undefined!*/]);
|
||||||
/**
|
/**
|
||||||
@ -148,19 +148,10 @@
|
|||||||
|
|
||||||
/* Documented in the api object's initializer. */
|
/* Documented in the api object's initializer. */
|
||||||
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
|
capi.sqlite3_prepare_v3 = function f(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail){
|
||||||
/* 2022-07-08: xWrap() 'string' arg handling may be able do this
|
|
||||||
special-case handling for us. It needs to be tested. Or maybe
|
|
||||||
not: we always want to treat pzTail as null when passed a
|
|
||||||
non-pointer SQL string and the argument adapters don't have
|
|
||||||
enough state to know that. Maybe they could/should, by passing
|
|
||||||
the currently-collected args as an array as the 2nd arg to the
|
|
||||||
argument adapters? Or maybe we collect all args in an array,
|
|
||||||
pass that to an optional post-args-collected callback, and give
|
|
||||||
it a chance to manipulate the args before we pass them on? */
|
|
||||||
if(util.isSQLableTypedArray(sql)) sql = util.typedArrayToString(sql);
|
if(util.isSQLableTypedArray(sql)) sql = util.typedArrayToString(sql);
|
||||||
switch(typeof sql){
|
switch(typeof sql){
|
||||||
case 'string': return __prepare.basic(pDb, sql, -1, prepFlags, ppStmt, null);
|
case 'string': return __prepare.basic(pDb, sql, -1, prepFlags, ppStmt, null);
|
||||||
case 'number': return __prepare.full(pDb, sql, sqlLen||-1, prepFlags, ppStmt, pzTail);
|
case 'number': return __prepare.full(pDb, sql, sqlLen, prepFlags, ppStmt, pzTail);
|
||||||
default:
|
default:
|
||||||
return util.sqlite3_wasm_db_error(
|
return util.sqlite3_wasm_db_error(
|
||||||
pDb, capi.SQLITE_MISUSE,
|
pDb, capi.SQLITE_MISUSE,
|
||||||
|
@ -322,15 +322,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
Similar to this.filename but will return NULL for
|
Similar to this.filename but will return NULL for special names
|
||||||
special names like ":memory:". Not of much use until
|
like ":memory:". Not of much use until we have filesystem
|
||||||
we have filesystem support. Throws if the DB has
|
support. Throws if the DB has been closed. If passed an
|
||||||
been closed. If passed an argument it then it will return
|
argument it then it will return the filename of the ATTACHEd db
|
||||||
the filename of the ATTACHEd db with that name, else it assumes
|
with that name, else it assumes a name of `main`.
|
||||||
a name of `main`.
|
|
||||||
*/
|
*/
|
||||||
fileName: function(dbName){
|
fileName: function(dbName='main'){
|
||||||
return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName||"main");
|
return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName);
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
Returns true if this db instance has a name which resolves to a
|
Returns true if this db instance has a name which resolves to a
|
||||||
@ -759,7 +758,7 @@
|
|||||||
capi.sqlite3_result_null(pCx);
|
capi.sqlite3_result_null(pCx);
|
||||||
break;
|
break;
|
||||||
}else if(util.isBindableTypedArray(val)){
|
}else if(util.isBindableTypedArray(val)){
|
||||||
const pBlob = capi.wasm.mallocFromTypedArray(val);
|
const pBlob = capi.wasm.allocFromTypedArray(val);
|
||||||
capi.sqlite3_result_blob(pCx, pBlob, val.byteLength,
|
capi.sqlite3_result_blob(pCx, pBlob, val.byteLength,
|
||||||
capi.SQLITE_TRANSIENT);
|
capi.SQLITE_TRANSIENT);
|
||||||
capi.wasm.dealloc(pBlob);
|
capi.wasm.dealloc(pBlob);
|
||||||
@ -1072,7 +1071,7 @@
|
|||||||
capi.wasm.scopedAllocPop(stack);
|
capi.wasm.scopedAllocPop(stack);
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
const pBlob = capi.wasm.mallocFromTypedArray(val);
|
const pBlob = capi.wasm.allocFromTypedArray(val);
|
||||||
try{
|
try{
|
||||||
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
||||||
capi.SQLITE_TRANSIENT);
|
capi.SQLITE_TRANSIENT);
|
||||||
|
@ -172,36 +172,6 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
counterparts.
|
counterparts.
|
||||||
*/
|
*/
|
||||||
const capi = {
|
const capi = {
|
||||||
/**
|
|
||||||
An Error subclass which is thrown by this object's alloc() method
|
|
||||||
on OOM.
|
|
||||||
*/
|
|
||||||
WasmAllocError: WasmAllocError,
|
|
||||||
/**
|
|
||||||
The API's one single point of access to the WASM-side memory
|
|
||||||
allocator. Works like malloc(3) (and is likely bound to
|
|
||||||
malloc()) but throws an WasmAllocError if allocation fails. It is
|
|
||||||
important that any code which might pass through the sqlite3 C
|
|
||||||
API NOT throw and must instead return SQLITE_NOMEM (or
|
|
||||||
equivalent, depending on the context).
|
|
||||||
|
|
||||||
That said, very few cases in the API can result in
|
|
||||||
client-defined functions propagating exceptions via the C-style
|
|
||||||
API. Most notably, this applies ot User-defined SQL Functions
|
|
||||||
(UDFs) registered via sqlite3_create_function_v2(). For that
|
|
||||||
specific case it is recommended that all UDF creation be
|
|
||||||
funneled through a utility function and that a wrapper function
|
|
||||||
be added around the UDF which catches any exception and sets
|
|
||||||
the error state to OOM. (The overall complexity of registering
|
|
||||||
UDFs essentially requires a helper for doing so!)
|
|
||||||
*/
|
|
||||||
alloc: undefined/*installed later*/,
|
|
||||||
/**
|
|
||||||
The API's one single point of access to the WASM-side memory
|
|
||||||
deallocator. Works like free(3) (and is likely bound to
|
|
||||||
free()).
|
|
||||||
*/
|
|
||||||
dealloc: undefined/*installed later*/,
|
|
||||||
/**
|
/**
|
||||||
When using sqlite3_open_v2() it is important to keep the following
|
When using sqlite3_open_v2() it is important to keep the following
|
||||||
in mind:
|
in mind:
|
||||||
@ -365,6 +335,33 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
|| toss("API config object requires a WebAssembly.Memory object",
|
|| toss("API config object requires a WebAssembly.Memory object",
|
||||||
"in either config.exports.memory (exported)",
|
"in either config.exports.memory (exported)",
|
||||||
"or config.memory (imported)."),
|
"or config.memory (imported)."),
|
||||||
|
|
||||||
|
/**
|
||||||
|
The API's one single point of access to the WASM-side memory
|
||||||
|
allocator. Works like malloc(3) (and is likely bound to
|
||||||
|
malloc()) but throws an WasmAllocError if allocation fails. It is
|
||||||
|
important that any code which might pass through the sqlite3 C
|
||||||
|
API NOT throw and must instead return SQLITE_NOMEM (or
|
||||||
|
equivalent, depending on the context).
|
||||||
|
|
||||||
|
That said, very few cases in the API can result in
|
||||||
|
client-defined functions propagating exceptions via the C-style
|
||||||
|
API. Most notably, this applies ot User-defined SQL Functions
|
||||||
|
(UDFs) registered via sqlite3_create_function_v2(). For that
|
||||||
|
specific case it is recommended that all UDF creation be
|
||||||
|
funneled through a utility function and that a wrapper function
|
||||||
|
be added around the UDF which catches any exception and sets
|
||||||
|
the error state to OOM. (The overall complexity of registering
|
||||||
|
UDFs essentially requires a helper for doing so!)
|
||||||
|
*/
|
||||||
|
alloc: undefined/*installed later*/,
|
||||||
|
/**
|
||||||
|
The API's one single point of access to the WASM-side memory
|
||||||
|
deallocator. Works like free(3) (and is likely bound to
|
||||||
|
free()).
|
||||||
|
*/
|
||||||
|
dealloc: undefined/*installed later*/
|
||||||
|
|
||||||
/* Many more wasm-related APIs get installed later on. */
|
/* Many more wasm-related APIs get installed later on. */
|
||||||
}/*wasm*/
|
}/*wasm*/
|
||||||
}/*capi*/;
|
}/*capi*/;
|
||||||
@ -387,7 +384,7 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
Int8Array types and will throw if srcTypedArray is of
|
Int8Array types and will throw if srcTypedArray is of
|
||||||
any other type.
|
any other type.
|
||||||
*/
|
*/
|
||||||
capi.wasm.mallocFromTypedArray = function(srcTypedArray){
|
capi.wasm.allocFromTypedArray = function(srcTypedArray){
|
||||||
affirmBindableTypedArray(srcTypedArray);
|
affirmBindableTypedArray(srcTypedArray);
|
||||||
const pRet = this.alloc(srcTypedArray.byteLength || 1);
|
const pRet = this.alloc(srcTypedArray.byteLength || 1);
|
||||||
this.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
|
this.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
|
||||||
@ -400,11 +397,13 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
const f = capi.wasm.exports[key];
|
const f = capi.wasm.exports[key];
|
||||||
if(!(f instanceof Function)) toss("Missing required exports[",key,"] function.");
|
if(!(f instanceof Function)) toss("Missing required exports[",key,"] function.");
|
||||||
}
|
}
|
||||||
|
|
||||||
capi.wasm.alloc = function(n){
|
capi.wasm.alloc = function(n){
|
||||||
const m = this.exports[keyAlloc](n);
|
const m = this.exports[keyAlloc](n);
|
||||||
if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
|
if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
|
||||||
return m;
|
return m;
|
||||||
}.bind(capi.wasm)
|
}.bind(capi.wasm)
|
||||||
|
|
||||||
capi.wasm.dealloc = (m)=>capi.wasm.exports[keyDealloc](m);
|
capi.wasm.dealloc = (m)=>capi.wasm.exports[keyDealloc](m);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -554,7 +553,8 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
["sqlite3_value_text", "string", "*"],
|
["sqlite3_value_text", "string", "*"],
|
||||||
["sqlite3_value_type", "int", "*"],
|
["sqlite3_value_type", "int", "*"],
|
||||||
["sqlite3_vfs_find", "*", "string"],
|
["sqlite3_vfs_find", "*", "string"],
|
||||||
["sqlite3_vfs_register", "int", "*", "int"]
|
["sqlite3_vfs_register", "int", "*", "int"],
|
||||||
|
["sqlite3_wasm_vfs_unlink", "int", "string"]
|
||||||
]/*capi.wasm.bindingSignatures*/;
|
]/*capi.wasm.bindingSignatures*/;
|
||||||
|
|
||||||
if(false && capi.wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
|
if(false && capi.wasm.compileOptionUsed('SQLITE_ENABLE_NORMALIZE')){
|
||||||
@ -583,18 +583,26 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
|
|
||||||
If the wasm environment has a persistent storage directory,
|
If the wasm environment has a persistent storage directory,
|
||||||
its path is returned by this function. If it does not then
|
its path is returned by this function. If it does not then
|
||||||
it returns one of:
|
it returns "" (noting that "" is a falsy value).
|
||||||
|
|
||||||
- `undefined` if initIfNeeded is false and this function has
|
The first time this is called, this function inspects the current
|
||||||
never been called before.
|
environment to determine whether persistence filesystem support
|
||||||
|
is available and, if it is, enables it (if needed).
|
||||||
|
|
||||||
- `""` if no persistent storage is available.
|
TODOs and caveats:
|
||||||
|
|
||||||
Note that in both cases the return value is falsy.
|
- The directory name (mount point) for persistent storage is
|
||||||
|
currently hard-coded. It needs to be configurable.
|
||||||
|
|
||||||
|
- If persistent storage is available at the root of the virtual
|
||||||
|
filesystem, this interface cannot currently distinguish that
|
||||||
|
from the lack of persistence. That case cannot currently (with
|
||||||
|
WASMFS/OPFS) happen, but it is conceivably possible in future
|
||||||
|
environments or non-browser runtimes (none of which are yet
|
||||||
|
supported targets).
|
||||||
*/
|
*/
|
||||||
capi.sqlite3_web_persistent_dir = function(initIfNeeded=true){
|
capi.sqlite3_web_persistent_dir = function(){
|
||||||
if(undefined !== __persistentDir) return __persistentDir;
|
if(undefined !== __persistentDir) return __persistentDir;
|
||||||
else if(!initIfNeeded) return;
|
|
||||||
// If we have no OPFS, there is no persistent dir
|
// If we have no OPFS, there is no persistent dir
|
||||||
if(!self.FileSystemHandle || !self.FileSystemDirectoryHandle
|
if(!self.FileSystemHandle || !self.FileSystemDirectoryHandle
|
||||||
|| !self.FileSystemFileHandle){
|
|| !self.FileSystemFileHandle){
|
||||||
@ -625,8 +633,22 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
}
|
}
|
||||||
}.bind(capi);
|
}.bind(capi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns true if sqlite3.capi.sqlite3_web_persistent_dir() is a
|
||||||
|
non-empty string and the given name has that string as its
|
||||||
|
prefix, else returns false.
|
||||||
|
*/
|
||||||
|
capi.sqlite3_web_filename_is_persistent = function(name){
|
||||||
|
const p = this.sqlite3_web_persistent_dir();
|
||||||
|
return (p && name) ? name.startsWith(p) : false;
|
||||||
|
}.bind(capi);
|
||||||
|
|
||||||
/* The remainder of the API will be set up in later steps. */
|
/* The remainder of the API will be set up in later steps. */
|
||||||
return {
|
return {
|
||||||
|
/**
|
||||||
|
An Error subclass which is thrown by this.wasm.alloc() on OOM.
|
||||||
|
*/
|
||||||
|
WasmAllocError: WasmAllocError,
|
||||||
capi,
|
capi,
|
||||||
postInit: [
|
postInit: [
|
||||||
/* some pieces of the API may install functions into this array,
|
/* some pieces of the API may install functions into this array,
|
||||||
@ -635,8 +657,6 @@ self.sqlite3ApiBootstrap = function(config){
|
|||||||
the current global object and sqlite3 is the object returned
|
the current global object and sqlite3 is the object returned
|
||||||
from sqlite3ApiBootstrap(). This array will be removed at the
|
from sqlite3ApiBootstrap(). This array will be removed at the
|
||||||
end of the API setup process. */],
|
end of the API setup process. */],
|
||||||
/** Config is needed downstream for gluing pieces together. It
|
|
||||||
will be removed at the end of the API setup process. */
|
|
||||||
config
|
config
|
||||||
};
|
};
|
||||||
}/*sqlite3ApiBootstrap()*/;
|
}/*sqlite3ApiBootstrap()*/;
|
||||||
|
@ -10,26 +10,40 @@
|
|||||||
|
|
||||||
***********************************************************************
|
***********************************************************************
|
||||||
|
|
||||||
This file implements a Worker-based wrapper around SQLite3 OO API
|
This file implements the initializer for the sqlite3 "Worker API
|
||||||
#1.
|
#1", a very basic DB access API intended to be scripted from a main
|
||||||
|
window thread via Worker-style messages. Because of limitations in
|
||||||
|
that type of communication, this API is minimalistic and only
|
||||||
|
capable of serving relatively basic DB requests (e.g. it cannot
|
||||||
|
process nested query loops concurrently).
|
||||||
|
|
||||||
|
This file requires that the core C-style sqlite3 API and OO API #1
|
||||||
|
have been loaded.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function implements a Worker-based wrapper around SQLite3 OO
|
||||||
|
API #1, colloquially known as "Worker API #1".
|
||||||
|
|
||||||
In order to permit this API to be loaded in worker threads without
|
In order to permit this API to be loaded in worker threads without
|
||||||
automatically registering onmessage handlers, initializing the
|
automatically registering onmessage handlers, initializing the
|
||||||
worker API requires calling initWorkerAPI(). If this function
|
worker API requires calling initWorker1API(). If this function
|
||||||
is called from a non-worker thread then it throws an exception.
|
is called from a non-worker thread then it throws an exception.
|
||||||
|
|
||||||
When initialized, it installs message listeners to receive messages
|
When initialized, it installs message listeners to receive Worker
|
||||||
from the main thread and then it posts a message in the form:
|
messages and then it posts a message in the form:
|
||||||
|
|
||||||
```
|
```
|
||||||
{type:'sqlite3-api',data:'worker-ready'}
|
{type:'sqlite3-api',data:'worker1-ready'}
|
||||||
```
|
```
|
||||||
|
|
||||||
This file requires that the core C-style sqlite3 API and OO API #1
|
to let the client know that it has been initialized. Clients may
|
||||||
have been loaded and that self.sqlite3 contains both,
|
optionally depend on this function not returning until
|
||||||
as documented for those APIs.
|
initialization is complete, as the initialization is synchronous.
|
||||||
|
In some contexts, however, listening for the above message is
|
||||||
|
a better fit.
|
||||||
*/
|
*/
|
||||||
self.sqlite3.initWorkerAPI = function(){
|
self.sqlite3.initWorker1API = function(){
|
||||||
'use strict';
|
'use strict';
|
||||||
/**
|
/**
|
||||||
UNDER CONSTRUCTION
|
UNDER CONSTRUCTION
|
||||||
@ -39,39 +53,12 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
cannot pass callback functions between the window thread and a
|
cannot pass callback functions between the window thread and a
|
||||||
worker thread, so we have to receive all db results via
|
worker thread, so we have to receive all db results via
|
||||||
asynchronous message-passing. That requires an asychronous API
|
asynchronous message-passing. That requires an asychronous API
|
||||||
with a distinctly different shape that the main OO API.
|
with a distinctly different shape than OO API #1.
|
||||||
|
|
||||||
Certain important considerations here include:
|
TODOs include, but are not necessarily limited to:
|
||||||
|
|
||||||
- Support only one db connection or multiple? The former is far
|
- Support for handling multiple DBs via this interface is under
|
||||||
easier, but there's always going to be a user out there who wants
|
development.
|
||||||
to juggle six database handles at once. Do we add that complexity
|
|
||||||
or tell such users to write their own code using the provided
|
|
||||||
lower-level APIs?
|
|
||||||
|
|
||||||
- Fetching multiple results: do we pass them on as a series of
|
|
||||||
messages, with start/end messages on either end, or do we collect
|
|
||||||
all results and bundle them back in a single message? The former
|
|
||||||
is, generically speaking, more memory-efficient but the latter
|
|
||||||
far easier to implement in this environment. The latter is
|
|
||||||
untennable for large data sets. Despite a web page hypothetically
|
|
||||||
being a relatively limited environment, there will always be
|
|
||||||
those users who feel that they should/need to be able to work
|
|
||||||
with multi-hundred-meg (or larger) blobs, and passing around
|
|
||||||
arrays of those may quickly exhaust the JS engine's memory.
|
|
||||||
|
|
||||||
TODOs include, but are not limited to:
|
|
||||||
|
|
||||||
- The ability to manage multiple DB handles. This can
|
|
||||||
potentially be done via a simple mapping of DB.filename or
|
|
||||||
DB.pointer (`sqlite3*` handle) to DB objects. The open()
|
|
||||||
interface would need to provide an ID (probably DB.pointer) back
|
|
||||||
to the user which can optionally be passed as an argument to
|
|
||||||
the other APIs (they'd default to the first-opened DB, for
|
|
||||||
ease of use). Client-side usability of this feature would
|
|
||||||
benefit from making another wrapper class (or a singleton)
|
|
||||||
available to the main thread, with that object proxying all(?)
|
|
||||||
communication with the worker.
|
|
||||||
|
|
||||||
- Revisit how virtual files are managed. We currently delete DBs
|
- Revisit how virtual files are managed. We currently delete DBs
|
||||||
from the virtual filesystem when we close them, for the sake of
|
from the virtual filesystem when we close them, for the sake of
|
||||||
@ -79,6 +66,8 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
require that we give up that habit. Similarly, fully supporting
|
require that we give up that habit. Similarly, fully supporting
|
||||||
ATTACH, where a user can upload multiple DBs and ATTACH them,
|
ATTACH, where a user can upload multiple DBs and ATTACH them,
|
||||||
also requires the that we manage the VFS entries better.
|
also requires the that we manage the VFS entries better.
|
||||||
|
Related: we most definitely do not want to delete persistent DBs
|
||||||
|
(e.g. stored on OPFS) when they're closed.
|
||||||
*/
|
*/
|
||||||
const toss = (...args)=>{throw new Error(args.join(' '))};
|
const toss = (...args)=>{throw new Error(args.join(' '))};
|
||||||
if('function' !== typeof importScripts){
|
if('function' !== typeof importScripts){
|
||||||
@ -116,8 +105,7 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
// same filename and close/reopen it (or just pass it back as is?).
|
// same filename and close/reopen it (or just pass it back as is?).
|
||||||
if(!arg && this.defaultDb) return this.defaultDb;
|
if(!arg && this.defaultDb) return this.defaultDb;
|
||||||
//???if(this.defaultDb) this.defaultDb.close();
|
//???if(this.defaultDb) this.defaultDb.close();
|
||||||
let db;
|
const db = (Array.isArray(arg) ? new DB(...arg) : new DB(arg));
|
||||||
db = (Array.isArray(arg) ? new DB(...arg) : new DB(arg));
|
|
||||||
this.dbs[getDbId(db)] = db;
|
this.dbs[getDbId(db)] = db;
|
||||||
if(!this.defaultDb) this.defaultDb = db;
|
if(!this.defaultDb) this.defaultDb = db;
|
||||||
return db;
|
return db;
|
||||||
@ -125,13 +113,17 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
close: function(db,alsoUnlink){
|
close: function(db,alsoUnlink){
|
||||||
if(db){
|
if(db){
|
||||||
delete this.dbs[getDbId(db)];
|
delete this.dbs[getDbId(db)];
|
||||||
db.close(alsoUnlink);
|
const filename = db.fileName();
|
||||||
|
db.close();
|
||||||
if(db===this.defaultDb) this.defaultDb = undefined;
|
if(db===this.defaultDb) this.defaultDb = undefined;
|
||||||
|
if(alsoUnlink && filename){
|
||||||
|
sqlite3.capi.sqlite3_wasm_vfs_unlink(filename);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
post: function(type,data,xferList){
|
post: function(type,data,xferList){
|
||||||
if(xferList){
|
if(xferList){
|
||||||
self.postMessage({type, data},xferList);
|
self.postMessage( {type, data}, xferList );
|
||||||
xferList.length = 0;
|
xferList.length = 0;
|
||||||
}else{
|
}else{
|
||||||
self.postMessage({type, data});
|
self.postMessage({type, data});
|
||||||
@ -172,6 +164,68 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
*/
|
*/
|
||||||
const wMsgHandler = {
|
const wMsgHandler = {
|
||||||
xfer: [/*Temp holder for "transferable" postMessage() state.*/],
|
xfer: [/*Temp holder for "transferable" postMessage() state.*/],
|
||||||
|
/**
|
||||||
|
Proxy for the DB constructor. Expects to be passed a single
|
||||||
|
object or a falsy value to use defaults. The object may
|
||||||
|
have a filename property to name the db file (see the DB
|
||||||
|
constructor for peculiarities and transformations) and/or a
|
||||||
|
buffer property (a Uint8Array holding a complete database
|
||||||
|
file's contents). The response is an object:
|
||||||
|
|
||||||
|
{
|
||||||
|
filename: db filename (possibly differing from the input),
|
||||||
|
|
||||||
|
dbId: an opaque ID value which must be passed to other calls
|
||||||
|
in this API to tell them which db to use. If it is not
|
||||||
|
provided to future calls, they will default to
|
||||||
|
operating on the first-opened db.
|
||||||
|
|
||||||
|
messageId: if the client-sent message included this field,
|
||||||
|
it is mirrored in the response.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
open: function(ev){
|
||||||
|
const args = [], data = (ev.data || {});
|
||||||
|
if(data.simulateError){ // undocumented internal testing option
|
||||||
|
toss("Throwing because of simulateError flag.");
|
||||||
|
}
|
||||||
|
if(data.filename) args.push(data.filename);
|
||||||
|
const db = wState.open(args);
|
||||||
|
return {
|
||||||
|
filename: db.filename,
|
||||||
|
dbId: getDbId(db)
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
Proxy for DB.close(). If ev.data may either be a boolean or
|
||||||
|
an object with an `unlink` property. If that value is
|
||||||
|
truthy then the db file (if the db is currently open) will
|
||||||
|
be unlinked from the virtual filesystem, else it will be
|
||||||
|
kept intact. The response object is:
|
||||||
|
|
||||||
|
{
|
||||||
|
filename: db filename _if_ the db is opened when this
|
||||||
|
is called, else the undefined value,
|
||||||
|
unlink: boolean. If true, unlink() (delete) the db file
|
||||||
|
after closing int. Any error while deleting it is
|
||||||
|
ignored.
|
||||||
|
}
|
||||||
|
|
||||||
|
It does not error if the given db is already closed or no db is
|
||||||
|
provided. It is simply does nothing useful in that case.
|
||||||
|
*/
|
||||||
|
close: function(ev){
|
||||||
|
const db = getMsgDb(ev,false);
|
||||||
|
const response = {
|
||||||
|
filename: db && db.filename,
|
||||||
|
dbId: db ? getDbId(db) : undefined
|
||||||
|
};
|
||||||
|
if(db){
|
||||||
|
wState.close(db, !!((ev.data && 'object'===typeof ev.data)
|
||||||
|
? ev.data.unlink : false));
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
Proxy for DB.exec() which expects a single argument of type
|
Proxy for DB.exec() which expects a single argument of type
|
||||||
string (SQL to execute) or an options object in the form
|
string (SQL to execute) or an options object in the form
|
||||||
@ -266,10 +320,16 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
exports of ":memory:" and "" (temp file) DBs. The latter is
|
exports of ":memory:" and "" (temp file) DBs. The latter is
|
||||||
ostensibly easy because the file is (potentially) on disk, but
|
ostensibly easy because the file is (potentially) on disk, but
|
||||||
the former does not have a structure which maps directly to a
|
the former does not have a structure which maps directly to a
|
||||||
db file image.
|
db file image. We can VACUUM INTO a :memory:/temp db into a
|
||||||
|
file for that purpose, though.
|
||||||
*/
|
*/
|
||||||
export: function(ev){
|
export: function(ev){
|
||||||
toss("export() requires reimplementing for portability reasons.");
|
toss("export() requires reimplementing for portability reasons.");
|
||||||
|
/**
|
||||||
|
We need to reimplement this to use the Emscripten FS
|
||||||
|
interface. That part used to be in the OO#1 API but that
|
||||||
|
dependency was removed from that level of the API.
|
||||||
|
*/
|
||||||
/**const db = getMsgDb(ev);
|
/**const db = getMsgDb(ev);
|
||||||
const response = {
|
const response = {
|
||||||
buffer: db.exportBinaryImage(),
|
buffer: db.exportBinaryImage(),
|
||||||
@ -279,66 +339,6 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
this.xfer.push(response.buffer.buffer);
|
this.xfer.push(response.buffer.buffer);
|
||||||
return response;**/
|
return response;**/
|
||||||
}/*export()*/,
|
}/*export()*/,
|
||||||
/**
|
|
||||||
Proxy for the DB constructor. Expects to be passed a single
|
|
||||||
object or a falsy value to use defaults. The object may
|
|
||||||
have a filename property to name the db file (see the DB
|
|
||||||
constructor for peculiarities and transformations) and/or a
|
|
||||||
buffer property (a Uint8Array holding a complete database
|
|
||||||
file's contents). The response is an object:
|
|
||||||
|
|
||||||
{
|
|
||||||
filename: db filename (possibly differing from the input),
|
|
||||||
|
|
||||||
id: an opaque ID value intended for future distinction
|
|
||||||
between multiple db handles. Messages including a specific
|
|
||||||
ID will use the DB for that ID.
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
If the Worker's db is currently opened, this call closes it
|
|
||||||
before proceeding.
|
|
||||||
*/
|
|
||||||
open: function(ev){
|
|
||||||
wState.close(/*true???*/);
|
|
||||||
const args = [], data = (ev.data || {});
|
|
||||||
if(data.simulateError){
|
|
||||||
toss("Throwing because of open.simulateError flag.");
|
|
||||||
}
|
|
||||||
if(data.filename) args.push(data.filename);
|
|
||||||
if(data.buffer){
|
|
||||||
args.push(data.buffer);
|
|
||||||
this.xfer.push(data.buffer.buffer);
|
|
||||||
}
|
|
||||||
const db = wState.open(args);
|
|
||||||
return {
|
|
||||||
filename: db.filename,
|
|
||||||
dbId: getDbId(db)
|
|
||||||
};
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
Proxy for DB.close(). If ev.data may either be a boolean or
|
|
||||||
an object with an `unlink` property. If that value is
|
|
||||||
truthy then the db file (if the db is currently open) will
|
|
||||||
be unlinked from the virtual filesystem, else it will be
|
|
||||||
kept intact. The response object is:
|
|
||||||
|
|
||||||
{
|
|
||||||
filename: db filename _if_ the db is opened when this
|
|
||||||
is called, else the undefined value
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
close: function(ev){
|
|
||||||
const db = getMsgDb(ev,false);
|
|
||||||
const response = {
|
|
||||||
filename: db && db.filename
|
|
||||||
};
|
|
||||||
if(db){
|
|
||||||
wState.close(db, !!((ev.data && 'object'===typeof ev.data)
|
|
||||||
? ev.data.unlink : ev.data));
|
|
||||||
}
|
|
||||||
return response;
|
|
||||||
},
|
|
||||||
toss: function(ev){
|
toss: function(ev){
|
||||||
toss("Testing worker exception");
|
toss("Testing worker exception");
|
||||||
}
|
}
|
||||||
@ -352,7 +352,8 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
|
|
||||||
{ type: apiCommand,
|
{ type: apiCommand,
|
||||||
dbId: optional DB ID value (else uses a default db handle)
|
dbId: optional DB ID value (else uses a default db handle)
|
||||||
data: apiArguments
|
data: apiArguments,
|
||||||
|
messageId: optional client-specific value
|
||||||
}
|
}
|
||||||
|
|
||||||
As a rule, these commands respond with a postMessage() of their
|
As a rule, these commands respond with a postMessage() of their
|
||||||
@ -416,5 +417,5 @@ self.sqlite3.initWorkerAPI = function(){
|
|||||||
response.departureTime = ev.departureTime;
|
response.departureTime = ev.departureTime;
|
||||||
wState.post(evType, response, wMsgHandler.xfer);
|
wState.post(evType, response, wMsgHandler.xfer);
|
||||||
};
|
};
|
||||||
setTimeout(()=>self.postMessage({type:'sqlite3-api',data:'worker-ready'}), 0);
|
setTimeout(()=>self.postMessage({type:'sqlite3-api',data:'worker1-ready'}), 0);
|
||||||
}.bind({self, sqlite3: self.sqlite3});
|
}.bind({self, sqlite3: self.sqlite3});
|
@ -14,7 +14,7 @@
|
|||||||
sqlite3.js, initializes the module, and postMessage()'s a message
|
sqlite3.js, initializes the module, and postMessage()'s a message
|
||||||
after the module is initialized:
|
after the module is initialized:
|
||||||
|
|
||||||
{type: 'sqlite3-api', data: 'worker-ready'}
|
{type: 'sqlite3-api', data: 'worker1-ready'}
|
||||||
|
|
||||||
This seemingly superfluous level of indirection is necessary when
|
This seemingly superfluous level of indirection is necessary when
|
||||||
loading sqlite3.js via a Worker. Instantiating a worker with new
|
loading sqlite3.js via a Worker. Instantiating a worker with new
|
||||||
@ -28,4 +28,4 @@
|
|||||||
*/
|
*/
|
||||||
"use strict";
|
"use strict";
|
||||||
importScripts('sqlite3.js');
|
importScripts('sqlite3.js');
|
||||||
sqlite3InitModule().then((EmscriptenModule)=>EmscriptenModule.sqlite3.initWorkerAPI());
|
sqlite3InitModule().then((EmscriptenModule)=>EmscriptenModule.sqlite3.initWorker1API());
|
@ -163,10 +163,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
throw new capi.WasmAllocError;
|
throw new sqlite3.WasmAllocError;
|
||||||
}catch(e){
|
}catch(e){
|
||||||
T.assert(e instanceof Error)
|
T.assert(e instanceof Error)
|
||||||
.assert(e instanceof capi.WasmAllocError);
|
.assert(e instanceof sqlite3.WasmAllocError);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
|
<link rel="shortcut icon" href="data:image/x-icon;," type="image/x-icon">
|
||||||
<link rel="stylesheet" href="common/emscripten.css"/>
|
<link rel="stylesheet" href="common/emscripten.css"/>
|
||||||
<link rel="stylesheet" href="common/testing.css"/>
|
<link rel="stylesheet" href="common/testing.css"/>
|
||||||
<title>sqlite3-worker.js tests</title>
|
<title>sqlite3-worker1.js tests</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header id='titlebar'><span>sqlite3-worker.js tests</span></header>
|
<header id='titlebar'><span>sqlite3-worker1.js tests</span></header>
|
||||||
<!-- emscripten bits -->
|
<!-- emscripten bits -->
|
||||||
<figure id="module-spinner">
|
<figure id="module-spinner">
|
||||||
<div class="spinner"></div>
|
<div class="spinner"></div>
|
||||||
|
@ -10,12 +10,12 @@
|
|||||||
|
|
||||||
***********************************************************************
|
***********************************************************************
|
||||||
|
|
||||||
A basic test script for sqlite3-worker.js.
|
A basic test script for sqlite3-worker1.js.
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
(function(){
|
(function(){
|
||||||
const T = self.SqliteTestUtil;
|
const T = self.SqliteTestUtil;
|
||||||
const SW = new Worker("sqlite3-worker.js");
|
const SW = new Worker("sqlite3-worker1.js");
|
||||||
const DbState = {
|
const DbState = {
|
||||||
id: undefined
|
id: undefined
|
||||||
};
|
};
|
||||||
@ -261,16 +261,8 @@
|
|||||||
will fail and we have no way of cancelling them once they've
|
will fail and we have no way of cancelling them once they've
|
||||||
been posted to the worker.
|
been posted to the worker.
|
||||||
|
|
||||||
We currently do (2) because (A) it's certainly the most
|
Which approach we use below depends on the boolean value of
|
||||||
client-friendly thing to do and (B) it seems likely that most
|
waitForOpen.
|
||||||
apps using this API will only have a single db to work with so
|
|
||||||
won't need to juggle multiple DB ids. If we revert to (1) then
|
|
||||||
the following call to runTests2() needs to be moved into the
|
|
||||||
callback function of the runOneTest() check for the 'open'
|
|
||||||
command. Note, also, that using approach (2) does not keep the
|
|
||||||
user from instead using approach (1), noting that doing so
|
|
||||||
requires explicit handling of the 'open' message to account for
|
|
||||||
it.
|
|
||||||
*/
|
*/
|
||||||
const waitForOpen = 1,
|
const waitForOpen = 1,
|
||||||
simulateOpenError = 0 /* if true, the remaining tests will
|
simulateOpenError = 0 /* if true, the remaining tests will
|
||||||
@ -315,7 +307,7 @@
|
|||||||
switch(ev.type){
|
switch(ev.type){
|
||||||
case 'sqlite3-api':
|
case 'sqlite3-api':
|
||||||
switch(ev.data){
|
switch(ev.data){
|
||||||
case 'worker-ready':
|
case 'worker1-ready':
|
||||||
log("Message:",ev);
|
log("Message:",ev);
|
||||||
self.sqlite3TestModule.setStatus(null);
|
self.sqlite3TestModule.setStatus(null);
|
||||||
runTests();
|
runTests();
|
||||||
|
30
manifest
30
manifest
@ -1,5 +1,5 @@
|
|||||||
C wasm:\sminor\scleanups\sin\sthe\sOO\sAPI\s#1\sdemo.
|
C Minor\scleanups,\sreorgs,\sand\sdoc\supdates\sfor\sthe\sJS\sAPIs.\sRenamed\ssqlite3(-api)-worker.js\sto\ssqlite3(-api)-worker1.js,\sfor\ssymmetry\swith\ssqlite3-api-oo1.js.
|
||||||
D 2022-08-16T17:29:59.160
|
D 2022-08-17T16:44:05.090
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -474,19 +474,19 @@ F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
|||||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle db7a4602f043cf4a5e4135be3609a487f9f1c83f05778bfbdf93766be4541b96
|
F ext/wasm/EXPORTED_FUNCTIONS.fiddle db7a4602f043cf4a5e4135be3609a487f9f1c83f05778bfbdf93766be4541b96
|
||||||
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02
|
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02
|
||||||
F ext/wasm/GNUmakefile b5b34ee01efcf7c3d6c53d54a332545f2670e7a5a0c63d6de847d3726e5bc521
|
F ext/wasm/GNUmakefile 19c21ce4df5583278cc495bffbe03c69dc64af60fa9dac01766d0192bd191ac6
|
||||||
F ext/wasm/README.md 4b00ae7c7d93c4591251245f0996a319e2651361013c98d2efb0b026771b7331
|
F ext/wasm/README.md 4b00ae7c7d93c4591251245f0996a319e2651361013c98d2efb0b026771b7331
|
||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 77ef4bcf37e362b9ad61f9c175dfc0f1b3e571563fb311b96581cf422ee6a8ec
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 77ef4bcf37e362b9ad61f9c175dfc0f1b3e571563fb311b96581cf422ee6a8ec
|
||||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||||
F ext/wasm/api/README.md b6d0fb64bfdf7bf9ce6938ea4104228f6f5bbef600f5d910b2f8c8694195988c
|
F ext/wasm/api/README.md d876597edd2b9542b6ea031adaaff1c042076fde7b670b1dc6d8a87b28a6631b
|
||||||
F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c
|
F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c
|
||||||
F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
|
F ext/wasm/api/post-js-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js 149fd63a0400cd1d69548887ffde2ed89c13283384a63c2e9fcfc695e38a9e11
|
F ext/wasm/api/sqlite3-api-cleanup.js 149fd63a0400cd1d69548887ffde2ed89c13283384a63c2e9fcfc695e38a9e11
|
||||||
F ext/wasm/api/sqlite3-api-glue.js 82c09f49c69984009ba5af2b628e67cc26c5dd203d383cd3091d40dab4e6514b
|
F ext/wasm/api/sqlite3-api-glue.js 4a09dd1153874f7a716cf953329bc1e78bf24e0870a9aad15214ffd51ac913bc
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 1d63e7e453e38ff2ad0c5e8bf68345f6fc5fe99fbc4a893cc982b4c50d904ca0
|
F ext/wasm/api/sqlite3-api-oo1.js d68dc7a692bc54385d9b851e914b386a146dc6c86624bfeb4672280a2d822082
|
||||||
F ext/wasm/api/sqlite3-api-opfs.js c93cdd14f81a26b3a64990515ee05c7e29827fbc8fba4e4c2fef3a37a984db89
|
F ext/wasm/api/sqlite3-api-opfs.js c93cdd14f81a26b3a64990515ee05c7e29827fbc8fba4e4c2fef3a37a984db89
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js c0f335bf8b44071da0204b8fa95ce78fd737033b155e7bcfdaee6ae64600802f
|
F ext/wasm/api/sqlite3-api-prologue.js 96997e411b41ff3d4024c2ad625c5cdb7b6a619ba8beece4662ad190191b1119
|
||||||
F ext/wasm/api/sqlite3-api-worker.js 1124f404ecdf3c14d9f829425cef778cd683911a9883f0809a463c3c7773c9fd
|
F ext/wasm/api/sqlite3-api-worker1.js 74130ec4979baeaf3e909c7619b99e9f466e2d816cd07370987ff639d168ef45 w ext/wasm/api/sqlite3-api-worker.js
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||||
F ext/wasm/api/sqlite3-wasm.c 0e78035045e3328fb050ec9580c6bfb714c756a1d3b917259e58baf9b0332c98
|
F ext/wasm/api/sqlite3-wasm.c 0e78035045e3328fb050ec9580c6bfb714c756a1d3b917259e58baf9b0332c98
|
||||||
F ext/wasm/common/SqliteTestUtil.js e41a1406f18da9224523fad0c48885caf995b56956a5b9852909c0989e687e90
|
F ext/wasm/common/SqliteTestUtil.js e41a1406f18da9224523fad0c48885caf995b56956a5b9852909c0989e687e90
|
||||||
@ -508,11 +508,11 @@ F ext/wasm/scratchpad-opfs-main.js a819ed26047c5539630cea59add6a5082ba04cdf82da2
|
|||||||
F ext/wasm/scratchpad-opfs-worker.html 66c1d15d678f3bd306373d76b61c6c8aef988f61f4a8dd40185d452f9c6d2bf5
|
F ext/wasm/scratchpad-opfs-worker.html 66c1d15d678f3bd306373d76b61c6c8aef988f61f4a8dd40185d452f9c6d2bf5
|
||||||
F ext/wasm/scratchpad-opfs-worker.js 3ec2868c669713145c76eb5877c64a1b20741f741817b87c907a154b676283a9
|
F ext/wasm/scratchpad-opfs-worker.js 3ec2868c669713145c76eb5877c64a1b20741f741817b87c907a154b676283a9
|
||||||
F ext/wasm/scratchpad-opfs-worker2.js de3ea77548243a638c8426b7e43cc1dbfc511013228ab98436eb102923ed6689
|
F ext/wasm/scratchpad-opfs-worker2.js de3ea77548243a638c8426b7e43cc1dbfc511013228ab98436eb102923ed6689
|
||||||
F ext/wasm/sqlite3-worker.js 1325ca8d40129a82531902a3a077b795db2eeaee81746e5a0c811a04b415fa7f
|
F ext/wasm/sqlite3-worker1.js e93fe8e5da7cb56dcf4d1bb0aa44bf681b509e1c56f2a75885c0f408f034c42b w ext/wasm/sqlite3-worker.js
|
||||||
F ext/wasm/testing1.html 528001c7e32ee567abc195aa071fd9820cc3c8ffc9c8a39a75e680db05f0c409
|
F ext/wasm/testing1.html 528001c7e32ee567abc195aa071fd9820cc3c8ffc9c8a39a75e680db05f0c409
|
||||||
F ext/wasm/testing1.js a25069e20d5f8dc548cc98bcf7002cec812084421a1f7f70ffae2c706d1167b2
|
F ext/wasm/testing1.js 9a97a7e45ce122b479b4a706ae1024abded67fd5f34a5764e41ff5efde8dfa17
|
||||||
F ext/wasm/testing2.html 73e5048e666fd6fb28b6e635677a9810e1e139c599ddcf28d687c982134b92b8
|
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
||||||
F ext/wasm/testing2.js dbb825174878716fab42c340962c0c1b32bfbe26dd16c7b082d30d35f510466c
|
F ext/wasm/testing2.js e16ae385cd24c4a4ec5de6f1c02e621d243e1f179204ac8df31068faa9e31b1a
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||||
@ -2006,8 +2006,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P d6d79b661a1c6137d4693393e02416da4858d58dc84d144081a48d523655b483
|
P b9cdcc06a8f70694d10ee5b1a0fd9f08f4c705ce576e5103bbafb36fc9cc2122
|
||||||
R 495d381dcb72f9436340c5a0c3371031
|
R 0f6a8177d32b201ea7bdd0eb1ddeff9b
|
||||||
U stephan
|
U stephan
|
||||||
Z f43bcfbf56838f97d3048cbeb389d31b
|
Z 89af6a2fddda724fc088d602c326bc26
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
b9cdcc06a8f70694d10ee5b1a0fd9f08f4c705ce576e5103bbafb36fc9cc2122
|
f5059ee6f9fc55a381cbf08a30dfb9a5636c0b44341e42f4e9f12a3b109b5507
|
Reference in New Issue
Block a user