mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +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.api)/sqlite3-api-glue.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-cleanup.js
|
||||
|
||||
|
@ -60,17 +60,17 @@ browser client:
|
||||
high-level sqlite3 JS wrappers and should feel relatively familiar
|
||||
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.
|
||||
- `sqlite3-api-worker.js`\
|
||||
- `sqlite3-api-worker1.js`\
|
||||
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
|
||||
thread via the Worker message-passing interface. Like OO API #1,
|
||||
this is an optional component, offering one of any number of
|
||||
potential implementations for such an API.
|
||||
- `sqlite3-worker.js`\
|
||||
- `sqlite3-worker1.js`\
|
||||
Is not part of the amalgamated sources and is intended to be
|
||||
loaded by a client Worker thread. It loads the sqlite3 module
|
||||
and runs the Worker API which is implemented in
|
||||
`sqlite3-api-worker.js`.
|
||||
and runs the Worker #1 API which is implemented in
|
||||
`sqlite3-api-worker1.js`.
|
||||
- `sqlite3-api-opfs.js`\
|
||||
is an in-development/experimental sqlite3 VFS wrapper, the goal of
|
||||
which being to use Google Chrome's Origin-Private FileSystem (OPFS)
|
||||
|
@ -128,7 +128,7 @@
|
||||
*/
|
||||
__prepare.basic = wasm.xWrap('sqlite3_prepare_v3',
|
||||
"int", ["sqlite3*", "string",
|
||||
"int"/*MUST always be negative*/,
|
||||
"int"/*ignored for this impl!*/,
|
||||
"int", "**",
|
||||
"**"/*MUST be 0 or null or undefined!*/]);
|
||||
/**
|
||||
@ -148,19 +148,10 @@
|
||||
|
||||
/* Documented in the api object's initializer. */
|
||||
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);
|
||||
switch(typeof sql){
|
||||
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:
|
||||
return util.sqlite3_wasm_db_error(
|
||||
pDb, capi.SQLITE_MISUSE,
|
||||
|
@ -322,15 +322,14 @@
|
||||
}
|
||||
},
|
||||
/**
|
||||
Similar to this.filename but will return NULL for
|
||||
special names like ":memory:". Not of much use until
|
||||
we have filesystem support. Throws if the DB has
|
||||
been closed. If passed an argument it then it will return
|
||||
the filename of the ATTACHEd db with that name, else it assumes
|
||||
a name of `main`.
|
||||
Similar to this.filename but will return NULL for special names
|
||||
like ":memory:". Not of much use until we have filesystem
|
||||
support. Throws if the DB has been closed. If passed an
|
||||
argument it then it will return the filename of the ATTACHEd db
|
||||
with that name, else it assumes a name of `main`.
|
||||
*/
|
||||
fileName: function(dbName){
|
||||
return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName||"main");
|
||||
fileName: function(dbName='main'){
|
||||
return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName);
|
||||
},
|
||||
/**
|
||||
Returns true if this db instance has a name which resolves to a
|
||||
@ -759,7 +758,7 @@
|
||||
capi.sqlite3_result_null(pCx);
|
||||
break;
|
||||
}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.SQLITE_TRANSIENT);
|
||||
capi.wasm.dealloc(pBlob);
|
||||
@ -1072,7 +1071,7 @@
|
||||
capi.wasm.scopedAllocPop(stack);
|
||||
}
|
||||
}else{
|
||||
const pBlob = capi.wasm.mallocFromTypedArray(val);
|
||||
const pBlob = capi.wasm.allocFromTypedArray(val);
|
||||
try{
|
||||
rc = capi.sqlite3_bind_blob(stmt.pointer, ndx, pBlob, val.byteLength,
|
||||
capi.SQLITE_TRANSIENT);
|
||||
|
@ -172,36 +172,6 @@ self.sqlite3ApiBootstrap = function(config){
|
||||
counterparts.
|
||||
*/
|
||||
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
|
||||
in mind:
|
||||
@ -365,6 +335,33 @@ self.sqlite3ApiBootstrap = function(config){
|
||||
|| toss("API config object requires a WebAssembly.Memory object",
|
||||
"in either config.exports.memory (exported)",
|
||||
"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. */
|
||||
}/*wasm*/
|
||||
}/*capi*/;
|
||||
@ -387,7 +384,7 @@ self.sqlite3ApiBootstrap = function(config){
|
||||
Int8Array types and will throw if srcTypedArray is of
|
||||
any other type.
|
||||
*/
|
||||
capi.wasm.mallocFromTypedArray = function(srcTypedArray){
|
||||
capi.wasm.allocFromTypedArray = function(srcTypedArray){
|
||||
affirmBindableTypedArray(srcTypedArray);
|
||||
const pRet = this.alloc(srcTypedArray.byteLength || 1);
|
||||
this.heapForSize(srcTypedArray.constructor).set(srcTypedArray.byteLength ? srcTypedArray : [0], pRet);
|
||||
@ -400,11 +397,13 @@ self.sqlite3ApiBootstrap = function(config){
|
||||
const f = capi.wasm.exports[key];
|
||||
if(!(f instanceof Function)) toss("Missing required exports[",key,"] function.");
|
||||
}
|
||||
|
||||
capi.wasm.alloc = function(n){
|
||||
const m = this.exports[keyAlloc](n);
|
||||
if(!m) throw new WasmAllocError("Failed to allocate "+n+" bytes.");
|
||||
return m;
|
||||
}.bind(capi.wasm)
|
||||
|
||||
capi.wasm.dealloc = (m)=>capi.wasm.exports[keyDealloc](m);
|
||||
|
||||
/**
|
||||
@ -554,7 +553,8 @@ self.sqlite3ApiBootstrap = function(config){
|
||||
["sqlite3_value_text", "string", "*"],
|
||||
["sqlite3_value_type", "int", "*"],
|
||||
["sqlite3_vfs_find", "*", "string"],
|
||||
["sqlite3_vfs_register", "int", "*", "int"]
|
||||
["sqlite3_vfs_register", "int", "*", "int"],
|
||||
["sqlite3_wasm_vfs_unlink", "int", "string"]
|
||||
]/*capi.wasm.bindingSignatures*/;
|
||||
|
||||
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,
|
||||
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
|
||||
never been called before.
|
||||
The first time this is called, this function inspects the current
|
||||
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;
|
||||
else if(!initIfNeeded) return;
|
||||
// If we have no OPFS, there is no persistent dir
|
||||
if(!self.FileSystemHandle || !self.FileSystemDirectoryHandle
|
||||
|| !self.FileSystemFileHandle){
|
||||
@ -625,8 +633,22 @@ self.sqlite3ApiBootstrap = function(config){
|
||||
}
|
||||
}.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. */
|
||||
return {
|
||||
/**
|
||||
An Error subclass which is thrown by this.wasm.alloc() on OOM.
|
||||
*/
|
||||
WasmAllocError: WasmAllocError,
|
||||
capi,
|
||||
postInit: [
|
||||
/* 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
|
||||
from sqlite3ApiBootstrap(). This array will be removed at the
|
||||
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
|
||||
};
|
||||
}/*sqlite3ApiBootstrap()*/;
|
||||
|
@ -10,26 +10,40 @@
|
||||
|
||||
***********************************************************************
|
||||
|
||||
This file implements a Worker-based wrapper around SQLite3 OO API
|
||||
#1.
|
||||
This file implements the initializer for the sqlite3 "Worker API
|
||||
#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
|
||||
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.
|
||||
|
||||
When initialized, it installs message listeners to receive messages
|
||||
from the main thread and then it posts a message in the form:
|
||||
When initialized, it installs message listeners to receive Worker
|
||||
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
|
||||
have been loaded and that self.sqlite3 contains both,
|
||||
as documented for those APIs.
|
||||
to let the client know that it has been initialized. Clients may
|
||||
optionally depend on this function not returning until
|
||||
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';
|
||||
/**
|
||||
UNDER CONSTRUCTION
|
||||
@ -39,39 +53,12 @@ self.sqlite3.initWorkerAPI = function(){
|
||||
cannot pass callback functions between the window thread and a
|
||||
worker thread, so we have to receive all db results via
|
||||
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
|
||||
easier, but there's always going to be a user out there who wants
|
||||
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.
|
||||
- Support for handling multiple DBs via this interface is under
|
||||
development.
|
||||
|
||||
- Revisit how virtual files are managed. We currently delete DBs
|
||||
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
|
||||
ATTACH, where a user can upload multiple DBs and ATTACH them,
|
||||
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(' '))};
|
||||
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?).
|
||||
if(!arg && this.defaultDb) return this.defaultDb;
|
||||
//???if(this.defaultDb) this.defaultDb.close();
|
||||
let db;
|
||||
db = (Array.isArray(arg) ? new DB(...arg) : new DB(arg));
|
||||
const db = (Array.isArray(arg) ? new DB(...arg) : new DB(arg));
|
||||
this.dbs[getDbId(db)] = db;
|
||||
if(!this.defaultDb) this.defaultDb = db;
|
||||
return db;
|
||||
@ -125,13 +113,17 @@ self.sqlite3.initWorkerAPI = function(){
|
||||
close: function(db,alsoUnlink){
|
||||
if(db){
|
||||
delete this.dbs[getDbId(db)];
|
||||
db.close(alsoUnlink);
|
||||
const filename = db.fileName();
|
||||
db.close();
|
||||
if(db===this.defaultDb) this.defaultDb = undefined;
|
||||
if(alsoUnlink && filename){
|
||||
sqlite3.capi.sqlite3_wasm_vfs_unlink(filename);
|
||||
}
|
||||
}
|
||||
},
|
||||
post: function(type,data,xferList){
|
||||
if(xferList){
|
||||
self.postMessage({type, data},xferList);
|
||||
self.postMessage( {type, data}, xferList );
|
||||
xferList.length = 0;
|
||||
}else{
|
||||
self.postMessage({type, data});
|
||||
@ -172,6 +164,68 @@ self.sqlite3.initWorkerAPI = function(){
|
||||
*/
|
||||
const wMsgHandler = {
|
||||
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
|
||||
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
|
||||
ostensibly easy because the file is (potentially) on disk, but
|
||||
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){
|
||||
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 response = {
|
||||
buffer: db.exportBinaryImage(),
|
||||
@ -279,66 +339,6 @@ self.sqlite3.initWorkerAPI = function(){
|
||||
this.xfer.push(response.buffer.buffer);
|
||||
return response;**/
|
||||
}/*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("Testing worker exception");
|
||||
}
|
||||
@ -352,7 +352,8 @@ self.sqlite3.initWorkerAPI = function(){
|
||||
|
||||
{ type: apiCommand,
|
||||
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
|
||||
@ -416,5 +417,5 @@ self.sqlite3.initWorkerAPI = function(){
|
||||
response.departureTime = ev.departureTime;
|
||||
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});
|
@ -14,7 +14,7 @@
|
||||
sqlite3.js, initializes the module, and postMessage()'s a message
|
||||
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
|
||||
loading sqlite3.js via a Worker. Instantiating a worker with new
|
||||
@ -28,4 +28,4 @@
|
||||
*/
|
||||
"use strict";
|
||||
importScripts('sqlite3.js');
|
||||
sqlite3InitModule().then((EmscriptenModule)=>EmscriptenModule.sqlite3.initWorkerAPI());
|
||||
sqlite3InitModule().then((EmscriptenModule)=>EmscriptenModule.sqlite3.initWorker1API());
|
@ -163,10 +163,10 @@
|
||||
}
|
||||
|
||||
try {
|
||||
throw new capi.WasmAllocError;
|
||||
throw new sqlite3.WasmAllocError;
|
||||
}catch(e){
|
||||
T.assert(e instanceof Error)
|
||||
.assert(e instanceof capi.WasmAllocError);
|
||||
.assert(e instanceof sqlite3.WasmAllocError);
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -6,10 +6,10 @@
|
||||
<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/testing.css"/>
|
||||
<title>sqlite3-worker.js tests</title>
|
||||
<title>sqlite3-worker1.js tests</title>
|
||||
</head>
|
||||
<body>
|
||||
<header id='titlebar'><span>sqlite3-worker.js tests</span></header>
|
||||
<header id='titlebar'><span>sqlite3-worker1.js tests</span></header>
|
||||
<!-- emscripten bits -->
|
||||
<figure id="module-spinner">
|
||||
<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';
|
||||
(function(){
|
||||
const T = self.SqliteTestUtil;
|
||||
const SW = new Worker("sqlite3-worker.js");
|
||||
const SW = new Worker("sqlite3-worker1.js");
|
||||
const DbState = {
|
||||
id: undefined
|
||||
};
|
||||
@ -261,16 +261,8 @@
|
||||
will fail and we have no way of cancelling them once they've
|
||||
been posted to the worker.
|
||||
|
||||
We currently do (2) because (A) it's certainly the most
|
||||
client-friendly thing to do and (B) it seems likely that most
|
||||
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.
|
||||
Which approach we use below depends on the boolean value of
|
||||
waitForOpen.
|
||||
*/
|
||||
const waitForOpen = 1,
|
||||
simulateOpenError = 0 /* if true, the remaining tests will
|
||||
@ -315,7 +307,7 @@
|
||||
switch(ev.type){
|
||||
case 'sqlite3-api':
|
||||
switch(ev.data){
|
||||
case 'worker-ready':
|
||||
case 'worker1-ready':
|
||||
log("Message:",ev);
|
||||
self.sqlite3TestModule.setStatus(null);
|
||||
runTests();
|
||||
|
30
manifest
30
manifest
@ -1,5 +1,5 @@
|
||||
C wasm:\sminor\scleanups\sin\sthe\sOO\sAPI\s#1\sdemo.
|
||||
D 2022-08-16T17:29:59.160
|
||||
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-17T16:44:05.090
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -474,19 +474,19 @@ F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle db7a4602f043cf4a5e4135be3609a487f9f1c83f05778bfbdf93766be4541b96
|
||||
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/api/EXPORTED_FUNCTIONS.sqlite3-api 77ef4bcf37e362b9ad61f9c175dfc0f1b3e571563fb311b96581cf422ee6a8ec
|
||||
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-header.js 0e853b78db83cb1c06b01663549e0e8b4f377f12f5a2d9a4a06cb776c003880b
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js 149fd63a0400cd1d69548887ffde2ed89c13283384a63c2e9fcfc695e38a9e11
|
||||
F ext/wasm/api/sqlite3-api-glue.js 82c09f49c69984009ba5af2b628e67cc26c5dd203d383cd3091d40dab4e6514b
|
||||
F ext/wasm/api/sqlite3-api-oo1.js 1d63e7e453e38ff2ad0c5e8bf68345f6fc5fe99fbc4a893cc982b4c50d904ca0
|
||||
F ext/wasm/api/sqlite3-api-glue.js 4a09dd1153874f7a716cf953329bc1e78bf24e0870a9aad15214ffd51ac913bc
|
||||
F ext/wasm/api/sqlite3-api-oo1.js d68dc7a692bc54385d9b851e914b386a146dc6c86624bfeb4672280a2d822082
|
||||
F ext/wasm/api/sqlite3-api-opfs.js c93cdd14f81a26b3a64990515ee05c7e29827fbc8fba4e4c2fef3a37a984db89
|
||||
F ext/wasm/api/sqlite3-api-prologue.js c0f335bf8b44071da0204b8fa95ce78fd737033b155e7bcfdaee6ae64600802f
|
||||
F ext/wasm/api/sqlite3-api-worker.js 1124f404ecdf3c14d9f829425cef778cd683911a9883f0809a463c3c7773c9fd
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 96997e411b41ff3d4024c2ad625c5cdb7b6a619ba8beece4662ad190191b1119
|
||||
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-wasm.c 0e78035045e3328fb050ec9580c6bfb714c756a1d3b917259e58baf9b0332c98
|
||||
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.js 3ec2868c669713145c76eb5877c64a1b20741f741817b87c907a154b676283a9
|
||||
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.js a25069e20d5f8dc548cc98bcf7002cec812084421a1f7f70ffae2c706d1167b2
|
||||
F ext/wasm/testing2.html 73e5048e666fd6fb28b6e635677a9810e1e139c599ddcf28d687c982134b92b8
|
||||
F ext/wasm/testing2.js dbb825174878716fab42c340962c0c1b32bfbe26dd16c7b082d30d35f510466c
|
||||
F ext/wasm/testing1.js 9a97a7e45ce122b479b4a706ae1024abded67fd5f34a5764e41ff5efde8dfa17
|
||||
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
||||
F ext/wasm/testing2.js e16ae385cd24c4a4ec5de6f1c02e621d243e1f179204ac8df31068faa9e31b1a
|
||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||
@ -2006,8 +2006,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P d6d79b661a1c6137d4693393e02416da4858d58dc84d144081a48d523655b483
|
||||
R 495d381dcb72f9436340c5a0c3371031
|
||||
P b9cdcc06a8f70694d10ee5b1a0fd9f08f4c705ce576e5103bbafb36fc9cc2122
|
||||
R 0f6a8177d32b201ea7bdd0eb1ddeff9b
|
||||
U stephan
|
||||
Z f43bcfbf56838f97d3048cbeb389d31b
|
||||
Z 89af6a2fddda724fc088d602c326bc26
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
b9cdcc06a8f70694d10ee5b1a0fd9f08f4c705ce576e5103bbafb36fc9cc2122
|
||||
f5059ee6f9fc55a381cbf08a30dfb9a5636c0b44341e42f4e9f12a3b109b5507
|
Reference in New Issue
Block a user