mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
Split the JS vfs/vtab helper code into discreet units as a step towards a build which optionally elides those pieces. This is an internal restructuring change and does not affect the API.
FossilOrigin-Name: ede945fd2360097d9961b8a4b8fb48fea57399cb9163534ed1c3c6b86588b0a5
This commit is contained in:
@ -433,8 +433,10 @@ sqlite3-api.jses += $(sqlite3-api-build-version.js)
|
|||||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.js
|
sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.js
|
||||||
# sqlite3-api-worker.js = the Worker1 API:
|
# sqlite3-api-worker.js = the Worker1 API:
|
||||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.js
|
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.js
|
||||||
# sqlite3-v-helper = helper APIs for VFSes and VTABLEs:
|
# sqlite3-vfs-helper = helper APIs for VFSes:
|
||||||
sqlite3-api.jses += $(dir.api)/sqlite3-v-helper.js
|
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.c-pp.js
|
||||||
|
# sqlite3-vtab-helper = helper APIs for VTABLEs:
|
||||||
|
sqlite3-api.jses += $(dir.api)/sqlite3-vtab-helper.c-pp.js
|
||||||
# sqlite3-vfs-opfs.c-pp.js = the first OPFS VFS:
|
# sqlite3-vfs-opfs.c-pp.js = the first OPFS VFS:
|
||||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
|
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
|
||||||
# sqlite3-vfs-opfs-sahpool.c-pp.js = the second OPFS VFS:
|
# sqlite3-vfs-opfs-sahpool.c-pp.js = the second OPFS VFS:
|
||||||
|
@ -78,10 +78,12 @@ browser client:
|
|||||||
a Promise-based interface into the Worker #1 API. This is
|
a Promise-based interface into the Worker #1 API. This is
|
||||||
a far user-friendlier way to interface with databases running
|
a far user-friendlier way to interface with databases running
|
||||||
in a Worker thread.
|
in a Worker thread.
|
||||||
- **`sqlite3-v-helper.js`**\
|
- **`sqlite3-vfs-helper.js`**\
|
||||||
Installs `sqlite3.vfs` and `sqlite3.vtab`, namespaces which contain
|
Installs the `sqlite3.vfs` namespace, which contain helpers for use
|
||||||
helpers for use by downstream code which creates `sqlite3_vfs`
|
by downstream code which creates `sqlite3_vfs` implementations.
|
||||||
and `sqlite3_module` implementations.
|
- **`sqlite3-vtab-helper.js`**\
|
||||||
|
Installs the `sqlite3.vtab` namespace, which contain helpers for use
|
||||||
|
by downstream code which creates `sqlite3_module` implementations.
|
||||||
- **`sqlite3-vfs-opfs.c-pp.js`**\
|
- **`sqlite3-vfs-opfs.c-pp.js`**\
|
||||||
is an sqlite3 VFS implementation which supports the Origin-Private
|
is an sqlite3 VFS implementation which supports the Origin-Private
|
||||||
FileSystem (OPFS) as a storage layer to provide persistent storage
|
FileSystem (OPFS) as a storage layer to provide persistent storage
|
||||||
|
@ -329,6 +329,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(wasm.exports.sqlite3_activate_see instanceof Function){
|
if(wasm.exports.sqlite3_activate_see instanceof Function){
|
||||||
|
/**
|
||||||
|
This code is capable of using an SEE build but note that an SEE
|
||||||
|
WASM build is generally incompatible with SEE's license
|
||||||
|
conditions. It is permitted for use internally in organizations
|
||||||
|
which have licensed SEE, but not for public sites because
|
||||||
|
exposing an SEE build of sqlite3.wasm effectively provides all
|
||||||
|
clients with a working copy of the commercial SEE code.
|
||||||
|
*/
|
||||||
wasm.bindingSignatures.push(
|
wasm.bindingSignatures.push(
|
||||||
["sqlite3_key", "int", "sqlite3*", "string", "int"],
|
["sqlite3_key", "int", "sqlite3*", "string", "int"],
|
||||||
["sqlite3_key_v2","int","sqlite3*","string","*","int"],
|
["sqlite3_key_v2","int","sqlite3*","string","*","int"],
|
||||||
@ -341,6 +349,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
Functions which require BigInt (int64) support are separated from
|
Functions which require BigInt (int64) support are separated from
|
||||||
the others because we need to conditionally bind them or apply
|
the others because we need to conditionally bind them or apply
|
||||||
dummy impls, depending on the capabilities of the environment.
|
dummy impls, depending on the capabilities of the environment.
|
||||||
|
(That said: we never actually build without BigInt support,
|
||||||
|
and such builds are untested.)
|
||||||
|
|
||||||
Note that not all of these functions directly require int64
|
Note that not all of these functions directly require int64
|
||||||
but are only for use with APIs which require int64. For example,
|
but are only for use with APIs which require int64. For example,
|
||||||
@ -359,7 +369,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
/* Careful! Short version: de/serialize() are problematic because they
|
/* Careful! Short version: de/serialize() are problematic because they
|
||||||
might use a different allocator than the user for managing the
|
might use a different allocator than the user for managing the
|
||||||
deserialized block. de/serialize() are ONLY safe to use with
|
deserialized block. de/serialize() are ONLY safe to use with
|
||||||
sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. */,
|
sqlite3_malloc(), sqlite3_free(), and its 64-bit variants. Because
|
||||||
|
of this, the canonical builds of sqlite3.wasm/js guarantee that
|
||||||
|
sqlite3.wasm.alloc() and friends use those allocators. Custom builds
|
||||||
|
may not guarantee that, however. */,
|
||||||
["sqlite3_drop_modules", "int", ["sqlite3*", "**"]],
|
["sqlite3_drop_modules", "int", ["sqlite3*", "**"]],
|
||||||
["sqlite3_last_insert_rowid", "i64", ["sqlite3*"]],
|
["sqlite3_last_insert_rowid", "i64", ["sqlite3*"]],
|
||||||
["sqlite3_malloc64", "*","i64"],
|
["sqlite3_malloc64", "*","i64"],
|
||||||
@ -422,8 +435,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
|
|
||||||
// Add session/changeset APIs...
|
// Add session/changeset APIs...
|
||||||
if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){
|
if(wasm.bigIntEnabled && !!wasm.exports.sqlite3changegroup_add){
|
||||||
/* ACHTUNG: 2022-12-23: the session/changeset API bindings are
|
|
||||||
COMPLETELY UNTESTED. */
|
|
||||||
/**
|
/**
|
||||||
FuncPtrAdapter options for session-related callbacks with the
|
FuncPtrAdapter options for session-related callbacks with the
|
||||||
native signature "i(ps)". This proxy converts the 2nd argument
|
native signature "i(ps)". This proxy converts the 2nd argument
|
||||||
@ -602,7 +613,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
Functions which are intended solely for API-internal use by the
|
Functions which are intended solely for API-internal use by the
|
||||||
WASM components, not client code. These get installed into
|
WASM components, not client code. These get installed into
|
||||||
sqlite3.util. Some of them get exposed to clients via variants
|
sqlite3.util. Some of them get exposed to clients via variants
|
||||||
in wasm.sqlite3_js_...().
|
in sqlite3_js_...().
|
||||||
|
|
||||||
|
2024-01-11: these were renamed, with two underscores in the
|
||||||
|
prefix, to ensure that clients do not accidentally depend on
|
||||||
|
them. They have always been documented as internal-use-only, so
|
||||||
|
no clients "should" be depending on the old names.
|
||||||
*/
|
*/
|
||||||
wasm.bindingSignatures.wasmInternal = [
|
wasm.bindingSignatures.wasmInternal = [
|
||||||
["sqlite3__wasm_db_reset", "int", "sqlite3*"],
|
["sqlite3__wasm_db_reset", "int", "sqlite3*"],
|
||||||
@ -652,7 +668,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
|
|
||||||
Use case: sqlite3_bind_pointer() and sqlite3_result_pointer()
|
Use case: sqlite3_bind_pointer() and sqlite3_result_pointer()
|
||||||
call for "a static string and preferably a string
|
call for "a static string and preferably a string
|
||||||
literal". This converter is used to ensure that the string
|
literal." This converter is used to ensure that the string
|
||||||
value seen by those functions is long-lived and behaves as they
|
value seen by those functions is long-lived and behaves as they
|
||||||
need it to.
|
need it to.
|
||||||
*/
|
*/
|
||||||
@ -674,14 +690,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
`sqlite3_vfs*` via capi.sqlite3_vfs.pointer.
|
`sqlite3_vfs*` via capi.sqlite3_vfs.pointer.
|
||||||
*/
|
*/
|
||||||
const __xArgPtr = wasm.xWrap.argAdapter('*');
|
const __xArgPtr = wasm.xWrap.argAdapter('*');
|
||||||
const nilType = function(){}/*a class no value can ever be an instance of*/;
|
const nilType = function(){
|
||||||
|
/*a class which no value can ever be an instance of*/
|
||||||
|
};
|
||||||
wasm.xWrap.argAdapter('sqlite3_filename', __xArgPtr)
|
wasm.xWrap.argAdapter('sqlite3_filename', __xArgPtr)
|
||||||
('sqlite3_context*', __xArgPtr)
|
('sqlite3_context*', __xArgPtr)
|
||||||
('sqlite3_value*', __xArgPtr)
|
('sqlite3_value*', __xArgPtr)
|
||||||
('void*', __xArgPtr)
|
('void*', __xArgPtr)
|
||||||
('sqlite3_changegroup*', __xArgPtr)
|
('sqlite3_changegroup*', __xArgPtr)
|
||||||
('sqlite3_changeset_iter*', __xArgPtr)
|
('sqlite3_changeset_iter*', __xArgPtr)
|
||||||
//('sqlite3_rebaser*', __xArgPtr)
|
|
||||||
('sqlite3_session*', __xArgPtr)
|
('sqlite3_session*', __xArgPtr)
|
||||||
('sqlite3_stmt*', (v)=>
|
('sqlite3_stmt*', (v)=>
|
||||||
__xArgPtr((v instanceof (sqlite3?.oo1?.Stmt || nilType))
|
__xArgPtr((v instanceof (sqlite3?.oo1?.Stmt || nilType))
|
||||||
@ -1667,5 +1684,181 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
}
|
}
|
||||||
}/*pKvvfs*/
|
}/*pKvvfs*/
|
||||||
|
|
||||||
|
/* Warn if client-level code makes use of FuncPtrAdapter. */
|
||||||
wasm.xWrap.FuncPtrAdapter.warnOnUse = true;
|
wasm.xWrap.FuncPtrAdapter.warnOnUse = true;
|
||||||
|
|
||||||
|
const StructBinder = sqlite3.StructBinder
|
||||||
|
/* we require a local alias b/c StructBinder is removed from the sqlite3
|
||||||
|
object during the final steps of the API cleanup. */;
|
||||||
|
/**
|
||||||
|
Installs a StructBinder-bound function pointer member of the
|
||||||
|
given name and function in the given StructBinder.StructType
|
||||||
|
target object.
|
||||||
|
|
||||||
|
It creates a WASM proxy for the given function and arranges for
|
||||||
|
that proxy to be cleaned up when tgt.dispose() is called. Throws
|
||||||
|
on the slightest hint of error, e.g. tgt is-not-a StructType,
|
||||||
|
name does not map to a struct-bound member, etc.
|
||||||
|
|
||||||
|
As a special case, if the given function is a pointer, then
|
||||||
|
`wasm.functionEntry()` is used to validate that it is a known
|
||||||
|
function. If so, it is used as-is with no extra level of proxying
|
||||||
|
or cleanup, else an exception is thrown. It is legal to pass a
|
||||||
|
value of 0, indicating a NULL pointer, with the caveat that 0
|
||||||
|
_is_ a legal function pointer in WASM but it will not be accepted
|
||||||
|
as such _here_. (Justification: the function at address zero must
|
||||||
|
be one which initially came from the WASM module, not a method we
|
||||||
|
want to bind to a virtual table or VFS.)
|
||||||
|
|
||||||
|
This function returns a proxy for itself which is bound to tgt
|
||||||
|
and takes 2 args (name,func). That function returns the same
|
||||||
|
thing as this one, permitting calls to be chained.
|
||||||
|
|
||||||
|
If called with only 1 arg, it has no side effects but returns a
|
||||||
|
func with the same signature as described above.
|
||||||
|
|
||||||
|
ACHTUNG: because we cannot generically know how to transform JS
|
||||||
|
exceptions into result codes, the installed functions do no
|
||||||
|
automatic catching of exceptions. It is critical, to avoid
|
||||||
|
undefined behavior in the C layer, that methods mapped via
|
||||||
|
this function do not throw. The exception, as it were, to that
|
||||||
|
rule is...
|
||||||
|
|
||||||
|
If applyArgcCheck is true then each JS function (as opposed to
|
||||||
|
function pointers) gets wrapped in a proxy which asserts that it
|
||||||
|
is passed the expected number of arguments, throwing if the
|
||||||
|
argument count does not match expectations. That is only intended
|
||||||
|
for dev-time usage for sanity checking, and may leave the C
|
||||||
|
environment in an undefined state.
|
||||||
|
*/
|
||||||
|
const installMethod = function callee(
|
||||||
|
tgt, name, func, applyArgcCheck = callee.installMethodArgcCheck
|
||||||
|
){
|
||||||
|
if(!(tgt instanceof StructBinder.StructType)){
|
||||||
|
toss("Usage error: target object is-not-a StructType.");
|
||||||
|
}else if(!(func instanceof Function) && !wasm.isPtr(func)){
|
||||||
|
toss("Usage errror: expecting a Function or WASM pointer to one.");
|
||||||
|
}
|
||||||
|
if(1===arguments.length){
|
||||||
|
return (n,f)=>callee(tgt, n, f, applyArgcCheck);
|
||||||
|
}
|
||||||
|
if(!callee.argcProxy){
|
||||||
|
callee.argcProxy = function(tgt, funcName, func,sig){
|
||||||
|
return function(...args){
|
||||||
|
if(func.length!==arguments.length){
|
||||||
|
toss("Argument mismatch for",
|
||||||
|
tgt.structInfo.name+"::"+funcName
|
||||||
|
+": Native signature is:",sig);
|
||||||
|
}
|
||||||
|
return func.apply(this, args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/* An ondispose() callback for use with
|
||||||
|
StructBinder-created types. */
|
||||||
|
callee.removeFuncList = function(){
|
||||||
|
if(this.ondispose.__removeFuncList){
|
||||||
|
this.ondispose.__removeFuncList.forEach(
|
||||||
|
(v,ndx)=>{
|
||||||
|
if('number'===typeof v){
|
||||||
|
try{wasm.uninstallFunction(v)}
|
||||||
|
catch(e){/*ignore*/}
|
||||||
|
}
|
||||||
|
/* else it's a descriptive label for the next number in
|
||||||
|
the list. */
|
||||||
|
}
|
||||||
|
);
|
||||||
|
delete this.ondispose.__removeFuncList;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}/*static init*/
|
||||||
|
const sigN = tgt.memberSignature(name);
|
||||||
|
if(sigN.length<2){
|
||||||
|
toss("Member",name,"does not have a function pointer signature:",sigN);
|
||||||
|
}
|
||||||
|
const memKey = tgt.memberKey(name);
|
||||||
|
const fProxy = (applyArgcCheck && !wasm.isPtr(func))
|
||||||
|
/** This middle-man proxy is only for use during development, to
|
||||||
|
confirm that we always pass the proper number of
|
||||||
|
arguments. We know that the C-level code will always use the
|
||||||
|
correct argument count. */
|
||||||
|
? callee.argcProxy(tgt, memKey, func, sigN)
|
||||||
|
: func;
|
||||||
|
if(wasm.isPtr(fProxy)){
|
||||||
|
if(fProxy && !wasm.functionEntry(fProxy)){
|
||||||
|
toss("Pointer",fProxy,"is not a WASM function table entry.");
|
||||||
|
}
|
||||||
|
tgt[memKey] = fProxy;
|
||||||
|
}else{
|
||||||
|
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true));
|
||||||
|
tgt[memKey] = pFunc;
|
||||||
|
if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){
|
||||||
|
tgt.addOnDispose('ondispose.__removeFuncList handler',
|
||||||
|
callee.removeFuncList);
|
||||||
|
tgt.ondispose.__removeFuncList = [];
|
||||||
|
}
|
||||||
|
tgt.ondispose.__removeFuncList.push(memKey, pFunc);
|
||||||
|
}
|
||||||
|
return (n,f)=>callee(tgt, n, f, applyArgcCheck);
|
||||||
|
}/*installMethod*/;
|
||||||
|
installMethod.installMethodArgcCheck = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Installs methods into the given StructBinder.StructType-type
|
||||||
|
instance. Each entry in the given methods object must map to a
|
||||||
|
known member of the given StructType, else an exception will be
|
||||||
|
triggered. See installMethod() for more details, including the
|
||||||
|
semantics of the 3rd argument.
|
||||||
|
|
||||||
|
As an exception to the above, if any two or more methods in the
|
||||||
|
2nd argument are the exact same function, installMethod() is
|
||||||
|
_not_ called for the 2nd and subsequent instances, and instead
|
||||||
|
those instances get assigned the same method pointer which is
|
||||||
|
created for the first instance. This optimization is primarily to
|
||||||
|
accommodate special handling of sqlite3_module::xConnect and
|
||||||
|
xCreate methods.
|
||||||
|
|
||||||
|
On success, returns its first argument. Throws on error.
|
||||||
|
*/
|
||||||
|
const installMethods = function(
|
||||||
|
structInstance, methods, applyArgcCheck = installMethod.installMethodArgcCheck
|
||||||
|
){
|
||||||
|
const seen = new Map /* map of <Function, memberName> */;
|
||||||
|
for(const k of Object.keys(methods)){
|
||||||
|
const m = methods[k];
|
||||||
|
const prior = seen.get(m);
|
||||||
|
if(prior){
|
||||||
|
const mkey = structInstance.memberKey(k);
|
||||||
|
structInstance[mkey] = structInstance[structInstance.memberKey(prior)];
|
||||||
|
}else{
|
||||||
|
installMethod(structInstance, k, m, applyArgcCheck);
|
||||||
|
seen.set(m, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return structInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Equivalent to calling installMethod(this,...arguments) with a
|
||||||
|
first argument of this object. If called with 1 or 2 arguments
|
||||||
|
and the first is an object, it's instead equivalent to calling
|
||||||
|
installMethods(this,...arguments).
|
||||||
|
*/
|
||||||
|
StructBinder.StructType.prototype.installMethod = function callee(
|
||||||
|
name, func, applyArgcCheck = installMethod.installMethodArgcCheck
|
||||||
|
){
|
||||||
|
return (arguments.length < 3 && name && 'object'===typeof name)
|
||||||
|
? installMethods(this, ...arguments)
|
||||||
|
: installMethod(this, ...arguments);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Equivalent to calling installMethods() with a first argument
|
||||||
|
of this object.
|
||||||
|
*/
|
||||||
|
StructBinder.StructType.prototype.installMethods = function(
|
||||||
|
methods, applyArgcCheck = installMethod.installMethodArgcCheck
|
||||||
|
){
|
||||||
|
return installMethods(this, methods, applyArgcCheck);
|
||||||
|
};
|
||||||
|
|
||||||
});
|
});
|
||||||
|
103
ext/wasm/api/sqlite3-vfs-helper.c-pp.js
Normal file
103
ext/wasm/api/sqlite3-vfs-helper.c-pp.js
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
** 2022-11-30
|
||||||
|
**
|
||||||
|
** The author disclaims copyright to this source code. In place of a
|
||||||
|
** legal notice, here is a blessing:
|
||||||
|
**
|
||||||
|
** * May you do good and not evil.
|
||||||
|
** * May you find forgiveness for yourself and forgive others.
|
||||||
|
** * May you share freely, never taking more than you give.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
This file installs sqlite3.vfs, an object which exists to assist
|
||||||
|
in the creation of JavaScript implementations of sqlite3_vfs.
|
||||||
|
*/
|
||||||
|
'use strict';
|
||||||
|
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||||
|
const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3;
|
||||||
|
const vfs = Object.create(null);
|
||||||
|
sqlite3.vfs = vfs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Uses sqlite3_vfs_register() to register this
|
||||||
|
sqlite3.capi.sqlite3_vfs. This object must have already been
|
||||||
|
filled out properly. If the first argument is truthy, the VFS is
|
||||||
|
registered as the default VFS, else it is not.
|
||||||
|
|
||||||
|
On success, returns this object. Throws on error.
|
||||||
|
*/
|
||||||
|
capi.sqlite3_vfs.prototype.registerVfs = function(asDefault=false){
|
||||||
|
if(!(this instanceof sqlite3.capi.sqlite3_vfs)){
|
||||||
|
toss("Expecting a sqlite3_vfs-type argument.");
|
||||||
|
}
|
||||||
|
const rc = capi.sqlite3_vfs_register(this, asDefault ? 1 : 0);
|
||||||
|
if(rc){
|
||||||
|
toss("sqlite3_vfs_register(",this,") failed with rc",rc);
|
||||||
|
}
|
||||||
|
if(this.pointer !== capi.sqlite3_vfs_find(this.$zName)){
|
||||||
|
toss("BUG: sqlite3_vfs_find(vfs.$zName) failed for just-installed VFS",
|
||||||
|
this);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
A wrapper for
|
||||||
|
sqlite3.StructBinder.StructType.prototype.installMethods() or
|
||||||
|
registerVfs() to reduce installation of a VFS and/or its I/O
|
||||||
|
methods to a single call.
|
||||||
|
|
||||||
|
Accepts an object which contains the properties "io" and/or
|
||||||
|
"vfs", each of which is itself an object with following properties:
|
||||||
|
|
||||||
|
- `struct`: an sqlite3.StructBinder.StructType-type struct. This
|
||||||
|
must be a populated (except for the methods) object of type
|
||||||
|
sqlite3_io_methods (for the "io" entry) or sqlite3_vfs (for the
|
||||||
|
"vfs" entry).
|
||||||
|
|
||||||
|
- `methods`: an object mapping sqlite3_io_methods method names
|
||||||
|
(e.g. 'xClose') to JS implementations of those methods. The JS
|
||||||
|
implementations must be call-compatible with their native
|
||||||
|
counterparts.
|
||||||
|
|
||||||
|
For each of those object, this function passes its (`struct`,
|
||||||
|
`methods`, (optional) `applyArgcCheck`) properties to
|
||||||
|
installMethods().
|
||||||
|
|
||||||
|
If the `vfs` entry is set then:
|
||||||
|
|
||||||
|
- Its `struct` property's registerVfs() is called. The
|
||||||
|
`vfs` entry may optionally have an `asDefault` property, which
|
||||||
|
gets passed as the argument to registerVfs().
|
||||||
|
|
||||||
|
- If `struct.$zName` is falsy and the entry has a string-type
|
||||||
|
`name` property, `struct.$zName` is set to the C-string form of
|
||||||
|
that `name` value before registerVfs() is called. That string
|
||||||
|
gets added to the on-dispose state of the struct.
|
||||||
|
|
||||||
|
On success returns this object. Throws on error.
|
||||||
|
*/
|
||||||
|
vfs.installVfs = function(opt){
|
||||||
|
let count = 0;
|
||||||
|
const propList = ['io','vfs'];
|
||||||
|
for(const key of propList){
|
||||||
|
const o = opt[key];
|
||||||
|
if(o){
|
||||||
|
++count;
|
||||||
|
o.struct.installMethods(o.methods, !!o.applyArgcCheck);
|
||||||
|
if('vfs'===key){
|
||||||
|
if(!o.struct.$zName && 'string'===typeof o.name){
|
||||||
|
o.struct.addOnDispose(
|
||||||
|
o.struct.$zName = wasm.allocCString(o.name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
o.struct.registerVfs(!!o.asDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!count) toss("Misuse: installVfs() options object requires at least",
|
||||||
|
"one of:", propList);
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
}/*sqlite3ApiBootstrap.initializers.push()*/);
|
@ -10,19 +10,17 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This file installs sqlite3.vfs, and object which exists to assist
|
This file installs sqlite3.vtab, an object which exists to assist
|
||||||
in the creation of JavaScript implementations of sqlite3_vfs, along
|
in the creation of JavaScript implementations virtual tables.
|
||||||
with its virtual table counterpart, sqlite3.vtab.
|
|
||||||
|
Maintenance note: 2024-01-11: this file requires that StructBinder
|
||||||
|
has been extended with the installMethod(s)() methods, which
|
||||||
|
currently happens in sqlite3-api-glue.js.
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||||
const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3;
|
const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss3;
|
||||||
const vfs = Object.create(null), vtab = Object.create(null);
|
const vtab = Object.create(null);
|
||||||
|
|
||||||
const StructBinder = sqlite3.StructBinder
|
|
||||||
/* we require a local alias b/c StructBinder is removed from the sqlite3
|
|
||||||
object during the final steps of the API cleanup. */;
|
|
||||||
sqlite3.vfs = vfs;
|
|
||||||
sqlite3.vtab = vtab;
|
sqlite3.vtab = vtab;
|
||||||
|
|
||||||
const sii = capi.sqlite3_index_info;
|
const sii = capi.sqlite3_index_info;
|
||||||
@ -72,257 +70,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
return asPtr ? ptr : new sii.sqlite3_index_orderby(ptr);
|
return asPtr ? ptr : new sii.sqlite3_index_orderby(ptr);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
Installs a StructBinder-bound function pointer member of the
|
|
||||||
given name and function in the given StructType target object.
|
|
||||||
|
|
||||||
It creates a WASM proxy for the given function and arranges for
|
|
||||||
that proxy to be cleaned up when tgt.dispose() is called. Throws
|
|
||||||
on the slightest hint of error, e.g. tgt is-not-a StructType,
|
|
||||||
name does not map to a struct-bound member, etc.
|
|
||||||
|
|
||||||
As a special case, if the given function is a pointer, then
|
|
||||||
`wasm.functionEntry()` is used to validate that it is a known
|
|
||||||
function. If so, it is used as-is with no extra level of proxying
|
|
||||||
or cleanup, else an exception is thrown. It is legal to pass a
|
|
||||||
value of 0, indicating a NULL pointer, with the caveat that 0
|
|
||||||
_is_ a legal function pointer in WASM but it will not be accepted
|
|
||||||
as such _here_. (Justification: the function at address zero must
|
|
||||||
be one which initially came from the WASM module, not a method we
|
|
||||||
want to bind to a virtual table or VFS.)
|
|
||||||
|
|
||||||
This function returns a proxy for itself which is bound to tgt
|
|
||||||
and takes 2 args (name,func). That function returns the same
|
|
||||||
thing as this one, permitting calls to be chained.
|
|
||||||
|
|
||||||
If called with only 1 arg, it has no side effects but returns a
|
|
||||||
func with the same signature as described above.
|
|
||||||
|
|
||||||
ACHTUNG: because we cannot generically know how to transform JS
|
|
||||||
exceptions into result codes, the installed functions do no
|
|
||||||
automatic catching of exceptions. It is critical, to avoid
|
|
||||||
undefined behavior in the C layer, that methods mapped via
|
|
||||||
this function do not throw. The exception, as it were, to that
|
|
||||||
rule is...
|
|
||||||
|
|
||||||
If applyArgcCheck is true then each JS function (as opposed to
|
|
||||||
function pointers) gets wrapped in a proxy which asserts that it
|
|
||||||
is passed the expected number of arguments, throwing if the
|
|
||||||
argument count does not match expectations. That is only intended
|
|
||||||
for dev-time usage for sanity checking, and will leave the C
|
|
||||||
environment in an undefined state.
|
|
||||||
*/
|
|
||||||
const installMethod = function callee(
|
|
||||||
tgt, name, func, applyArgcCheck = callee.installMethodArgcCheck
|
|
||||||
){
|
|
||||||
if(!(tgt instanceof StructBinder.StructType)){
|
|
||||||
toss("Usage error: target object is-not-a StructType.");
|
|
||||||
}else if(!(func instanceof Function) && !wasm.isPtr(func)){
|
|
||||||
toss("Usage errror: expecting a Function or WASM pointer to one.");
|
|
||||||
}
|
|
||||||
if(1===arguments.length){
|
|
||||||
return (n,f)=>callee(tgt, n, f, applyArgcCheck);
|
|
||||||
}
|
|
||||||
if(!callee.argcProxy){
|
|
||||||
callee.argcProxy = function(tgt, funcName, func,sig){
|
|
||||||
return function(...args){
|
|
||||||
if(func.length!==arguments.length){
|
|
||||||
toss("Argument mismatch for",
|
|
||||||
tgt.structInfo.name+"::"+funcName
|
|
||||||
+": Native signature is:",sig);
|
|
||||||
}
|
|
||||||
return func.apply(this, args);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/* An ondispose() callback for use with
|
|
||||||
StructBinder-created types. */
|
|
||||||
callee.removeFuncList = function(){
|
|
||||||
if(this.ondispose.__removeFuncList){
|
|
||||||
this.ondispose.__removeFuncList.forEach(
|
|
||||||
(v,ndx)=>{
|
|
||||||
if('number'===typeof v){
|
|
||||||
try{wasm.uninstallFunction(v)}
|
|
||||||
catch(e){/*ignore*/}
|
|
||||||
}
|
|
||||||
/* else it's a descriptive label for the next number in
|
|
||||||
the list. */
|
|
||||||
}
|
|
||||||
);
|
|
||||||
delete this.ondispose.__removeFuncList;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}/*static init*/
|
|
||||||
const sigN = tgt.memberSignature(name);
|
|
||||||
if(sigN.length<2){
|
|
||||||
toss("Member",name,"does not have a function pointer signature:",sigN);
|
|
||||||
}
|
|
||||||
const memKey = tgt.memberKey(name);
|
|
||||||
const fProxy = (applyArgcCheck && !wasm.isPtr(func))
|
|
||||||
/** This middle-man proxy is only for use during development, to
|
|
||||||
confirm that we always pass the proper number of
|
|
||||||
arguments. We know that the C-level code will always use the
|
|
||||||
correct argument count. */
|
|
||||||
? callee.argcProxy(tgt, memKey, func, sigN)
|
|
||||||
: func;
|
|
||||||
if(wasm.isPtr(fProxy)){
|
|
||||||
if(fProxy && !wasm.functionEntry(fProxy)){
|
|
||||||
toss("Pointer",fProxy,"is not a WASM function table entry.");
|
|
||||||
}
|
|
||||||
tgt[memKey] = fProxy;
|
|
||||||
}else{
|
|
||||||
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true));
|
|
||||||
tgt[memKey] = pFunc;
|
|
||||||
if(!tgt.ondispose || !tgt.ondispose.__removeFuncList){
|
|
||||||
tgt.addOnDispose('ondispose.__removeFuncList handler',
|
|
||||||
callee.removeFuncList);
|
|
||||||
tgt.ondispose.__removeFuncList = [];
|
|
||||||
}
|
|
||||||
tgt.ondispose.__removeFuncList.push(memKey, pFunc);
|
|
||||||
}
|
|
||||||
return (n,f)=>callee(tgt, n, f, applyArgcCheck);
|
|
||||||
}/*installMethod*/;
|
|
||||||
installMethod.installMethodArgcCheck = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
Installs methods into the given StructType-type instance. Each
|
|
||||||
entry in the given methods object must map to a known member of
|
|
||||||
the given StructType, else an exception will be triggered. See
|
|
||||||
installMethod() for more details, including the semantics of the
|
|
||||||
3rd argument.
|
|
||||||
|
|
||||||
As an exception to the above, if any two or more methods in the
|
|
||||||
2nd argument are the exact same function, installMethod() is
|
|
||||||
_not_ called for the 2nd and subsequent instances, and instead
|
|
||||||
those instances get assigned the same method pointer which is
|
|
||||||
created for the first instance. This optimization is primarily to
|
|
||||||
accommodate special handling of sqlite3_module::xConnect and
|
|
||||||
xCreate methods.
|
|
||||||
|
|
||||||
On success, returns its first argument. Throws on error.
|
|
||||||
*/
|
|
||||||
const installMethods = function(
|
|
||||||
structInstance, methods, applyArgcCheck = installMethod.installMethodArgcCheck
|
|
||||||
){
|
|
||||||
const seen = new Map /* map of <Function, memberName> */;
|
|
||||||
for(const k of Object.keys(methods)){
|
|
||||||
const m = methods[k];
|
|
||||||
const prior = seen.get(m);
|
|
||||||
if(prior){
|
|
||||||
const mkey = structInstance.memberKey(k);
|
|
||||||
structInstance[mkey] = structInstance[structInstance.memberKey(prior)];
|
|
||||||
}else{
|
|
||||||
installMethod(structInstance, k, m, applyArgcCheck);
|
|
||||||
seen.set(m, k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return structInstance;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Equivalent to calling installMethod(this,...arguments) with a
|
|
||||||
first argument of this object. If called with 1 or 2 arguments
|
|
||||||
and the first is an object, it's instead equivalent to calling
|
|
||||||
installMethods(this,...arguments).
|
|
||||||
*/
|
|
||||||
StructBinder.StructType.prototype.installMethod = function callee(
|
|
||||||
name, func, applyArgcCheck = installMethod.installMethodArgcCheck
|
|
||||||
){
|
|
||||||
return (arguments.length < 3 && name && 'object'===typeof name)
|
|
||||||
? installMethods(this, ...arguments)
|
|
||||||
: installMethod(this, ...arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Equivalent to calling installMethods() with a first argument
|
|
||||||
of this object.
|
|
||||||
*/
|
|
||||||
StructBinder.StructType.prototype.installMethods = function(
|
|
||||||
methods, applyArgcCheck = installMethod.installMethodArgcCheck
|
|
||||||
){
|
|
||||||
return installMethods(this, methods, applyArgcCheck);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
Uses sqlite3_vfs_register() to register this
|
|
||||||
sqlite3.capi.sqlite3_vfs. This object must have already been
|
|
||||||
filled out properly. If the first argument is truthy, the VFS is
|
|
||||||
registered as the default VFS, else it is not.
|
|
||||||
|
|
||||||
On success, returns this object. Throws on error.
|
|
||||||
*/
|
|
||||||
capi.sqlite3_vfs.prototype.registerVfs = function(asDefault=false){
|
|
||||||
if(!(this instanceof sqlite3.capi.sqlite3_vfs)){
|
|
||||||
toss("Expecting a sqlite3_vfs-type argument.");
|
|
||||||
}
|
|
||||||
const rc = capi.sqlite3_vfs_register(this, asDefault ? 1 : 0);
|
|
||||||
if(rc){
|
|
||||||
toss("sqlite3_vfs_register(",this,") failed with rc",rc);
|
|
||||||
}
|
|
||||||
if(this.pointer !== capi.sqlite3_vfs_find(this.$zName)){
|
|
||||||
toss("BUG: sqlite3_vfs_find(vfs.$zName) failed for just-installed VFS",
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
A wrapper for installMethods() or registerVfs() to reduce
|
|
||||||
installation of a VFS and/or its I/O methods to a single
|
|
||||||
call.
|
|
||||||
|
|
||||||
Accepts an object which contains the properties "io" and/or
|
|
||||||
"vfs", each of which is itself an object with following properties:
|
|
||||||
|
|
||||||
- `struct`: an sqlite3.StructType-type struct. This must be a
|
|
||||||
populated (except for the methods) object of type
|
|
||||||
sqlite3_io_methods (for the "io" entry) or sqlite3_vfs (for the
|
|
||||||
"vfs" entry).
|
|
||||||
|
|
||||||
- `methods`: an object mapping sqlite3_io_methods method names
|
|
||||||
(e.g. 'xClose') to JS implementations of those methods. The JS
|
|
||||||
implementations must be call-compatible with their native
|
|
||||||
counterparts.
|
|
||||||
|
|
||||||
For each of those object, this function passes its (`struct`,
|
|
||||||
`methods`, (optional) `applyArgcCheck`) properties to
|
|
||||||
installMethods().
|
|
||||||
|
|
||||||
If the `vfs` entry is set then:
|
|
||||||
|
|
||||||
- Its `struct` property's registerVfs() is called. The
|
|
||||||
`vfs` entry may optionally have an `asDefault` property, which
|
|
||||||
gets passed as the argument to registerVfs().
|
|
||||||
|
|
||||||
- If `struct.$zName` is falsy and the entry has a string-type
|
|
||||||
`name` property, `struct.$zName` is set to the C-string form of
|
|
||||||
that `name` value before registerVfs() is called. That string
|
|
||||||
gets added to the on-dispose state of the struct.
|
|
||||||
|
|
||||||
On success returns this object. Throws on error.
|
|
||||||
*/
|
|
||||||
vfs.installVfs = function(opt){
|
|
||||||
let count = 0;
|
|
||||||
const propList = ['io','vfs'];
|
|
||||||
for(const key of propList){
|
|
||||||
const o = opt[key];
|
|
||||||
if(o){
|
|
||||||
++count;
|
|
||||||
installMethods(o.struct, o.methods, !!o.applyArgcCheck);
|
|
||||||
if('vfs'===key){
|
|
||||||
if(!o.struct.$zName && 'string'===typeof o.name){
|
|
||||||
o.struct.addOnDispose(
|
|
||||||
o.struct.$zName = wasm.allocCString(o.name)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
o.struct.registerVfs(!!o.asDefault);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!count) toss("Misuse: installVfs() options object requires at least",
|
|
||||||
"one of:", propList);
|
|
||||||
return this;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Internal factory function for xVtab and xCursor impls.
|
Internal factory function for xVtab and xCursor impls.
|
||||||
*/
|
*/
|
||||||
@ -456,30 +203,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
*/
|
*/
|
||||||
vtab.xIndexInfo = (pIdxInfo)=>new capi.sqlite3_index_info(pIdxInfo);
|
vtab.xIndexInfo = (pIdxInfo)=>new capi.sqlite3_index_info(pIdxInfo);
|
||||||
|
|
||||||
/**
|
|
||||||
Given an error object, this function returns
|
|
||||||
sqlite3.capi.SQLITE_NOMEM if (e instanceof
|
|
||||||
sqlite3.WasmAllocError), else it returns its
|
|
||||||
second argument. Its intended usage is in the methods
|
|
||||||
of a sqlite3_vfs or sqlite3_module:
|
|
||||||
|
|
||||||
```
|
|
||||||
try{
|
|
||||||
let rc = ...
|
|
||||||
return rc;
|
|
||||||
}catch(e){
|
|
||||||
return sqlite3.vtab.exceptionToRc(e, sqlite3.capi.SQLITE_XYZ);
|
|
||||||
// where SQLITE_XYZ is some call-appropriate result code.
|
|
||||||
}
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
/**vfs.exceptionToRc = vtab.exceptionToRc =
|
|
||||||
(e, defaultRc=capi.SQLITE_ERROR)=>(
|
|
||||||
(e instanceof sqlite3.WasmAllocError)
|
|
||||||
? capi.SQLITE_NOMEM
|
|
||||||
: defaultRc
|
|
||||||
);*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Given an sqlite3_module method name and error object, this
|
Given an sqlite3_module method name and error object, this
|
||||||
function returns sqlite3.capi.SQLITE_NOMEM if (e instanceof
|
function returns sqlite3.capi.SQLITE_NOMEM if (e instanceof
|
||||||
@ -525,20 +248,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
};
|
};
|
||||||
vtab.xError.errorReporter = 1 ? console.error.bind(console) : false;
|
vtab.xError.errorReporter = 1 ? console.error.bind(console) : false;
|
||||||
|
|
||||||
/**
|
|
||||||
"The problem" with this is that it introduces an outer function with
|
|
||||||
a different arity than the passed-in method callback. That means we
|
|
||||||
cannot do argc validation on these. Additionally, some methods (namely
|
|
||||||
xConnect) may have call-specific error handling. It would be a shame to
|
|
||||||
hard-coded that per-method support in this function.
|
|
||||||
*/
|
|
||||||
/** vtab.methodCatcher = function(methodName, method, defaultErrRc=capi.SQLITE_ERROR){
|
|
||||||
return function(...args){
|
|
||||||
try { method(...args); }
|
|
||||||
}catch(e){ return vtab.xError(methodName, e, defaultRc) }
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A helper for sqlite3_vtab::xRowid() and xUpdate()
|
A helper for sqlite3_vtab::xRowid() and xUpdate()
|
||||||
implementations. It must be passed the final argument to one of
|
implementations. It must be passed the final argument to one of
|
||||||
@ -685,12 +394,12 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
remethods[k] = fwrap(k, m);
|
remethods[k] = fwrap(k, m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
installMethods(mod, remethods, false);
|
mod.installMethods(remethods, false);
|
||||||
}else{
|
}else{
|
||||||
// No automatic exception handling. Trust the client
|
// No automatic exception handling. Trust the client
|
||||||
// to not throw.
|
// to not throw.
|
||||||
installMethods(
|
mod.installMethods(
|
||||||
mod, methods, !!opt.applyArgcCheck/*undocumented option*/
|
methods, !!opt.applyArgcCheck/*undocumented option*/
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if(0===mod.$iVersion){
|
if(0===mod.$iVersion){
|
22
manifest
22
manifest
@ -1,5 +1,5 @@
|
|||||||
C Make\sexplicit\swhich\sJS\sAPIs\sare\sfor\sinternal\suse\sonly\sby\smoving\sthe\sJS-bound\sinternal-use-only\sfunctions\sout\sof\sclient-visible\sreach\sand\srenaming\sthe\sWASM-exported\sones\sfrom\ssqlite3_wasm...\sto\ssqlite3__wasm...\s(with\stwo\sunderscores).\sThese\shave\salways\sbeen\sdocumented\sas\sinternal-use-only,\sso\sthis\sis\snot\sa\sbreaking\schange\sexcept\sfor\sclients\swhich\shave\signored\sthe\sdocs.
|
C Split\sthe\sJS\svfs/vtab\shelper\scode\sinto\sdiscreet\sunits\sas\sa\sstep\stowards\sa\sbuild\swhich\soptionally\selides\sthose\spieces.\sThis\sis\san\sinternal\srestructuring\schange\sand\sdoes\snot\saffect\sthe\sAPI.
|
||||||
D 2024-01-08T07:52:47.965
|
D 2024-01-11T12:31:58.929
|
||||||
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
|
||||||
@ -575,7 +575,7 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
|||||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
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.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||||
F ext/wasm/GNUmakefile 0f4ccfd350a9b0ebe60183fb4ad3b41c670eec62c88279f22e2627887b524b3c
|
F ext/wasm/GNUmakefile 693ff54a2710751a34ef4419a63eb7ea957f7e730f837fc1ef1dc475bdc5a6c8
|
||||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||||
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
|
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
|
||||||
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
|
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
|
||||||
@ -586,22 +586,23 @@ F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f30
|
|||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api f442460ed9a109e637dd3ea1caa4489553ad9414e8988118b208bb7a4bbece6b
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api f442460ed9a109e637dd3ea1caa4489553ad9414e8988118b208bb7a4bbece6b
|
||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||||
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 5eb44fa02e9c693a1884a3692428647894b0380b24bca120866b7a24c8786134
|
F ext/wasm/api/README.md 34fe11466f9c1d81b10a0469e1114e5f1c5a6365c73d80a1a6ca639a1a358b73
|
||||||
F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac
|
F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac
|
||||||
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
||||||
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
|
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
|
||||||
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
||||||
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219
|
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
|
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
|
||||||
F ext/wasm/api/sqlite3-api-glue.js 8f4478c927466245259478788c293810bc812ac8c49df38c62574966d836131a
|
F ext/wasm/api/sqlite3-api-glue.js 81ec1423e8c6dc8c26a3af470c993460d2f5137319ab1a00581203017e8b6b1f
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 7f3bcf0549ac44cde4b9da0b642d771916738d3f6781fb8a1757c50a91e506c0
|
F ext/wasm/api/sqlite3-api-oo1.js 7f3bcf0549ac44cde4b9da0b642d771916738d3f6781fb8a1757c50a91e506c0
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js fffcee629bf020a8ccf5c367fbe6a169f5d5d73dfce1707a75c9fbf4aa21c7da
|
F ext/wasm/api/sqlite3-api-prologue.js fffcee629bf020a8ccf5c367fbe6a169f5d5d73dfce1707a75c9fbf4aa21c7da
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js 8d9c0562831f62218170a3373468d8a0b7a6503b5985e309b69bf71187b525cf
|
F ext/wasm/api/sqlite3-api-worker1.js 8d9c0562831f62218170a3373468d8a0b7a6503b5985e309b69bf71187b525cf
|
||||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
|
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
|
||||||
F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
|
F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 6c02e969ad988e083415221e84445711730a321c748d8555bb61aebec6b4a37c w ext/wasm/api/sqlite3-v-helper.js
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 595953994aa3ae2287c889c4da39ab3d6f17b6461ecf4bec334b7a3faafddb02
|
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 595953994aa3ae2287c889c4da39ab3d6f17b6461ecf4bec334b7a3faafddb02
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 46c4afa6c50d7369252c104f274ad977a97e91ccfafc38b400fe36e90bdda88e
|
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 46c4afa6c50d7369252c104f274ad977a97e91ccfafc38b400fe36e90bdda88e
|
||||||
|
F ext/wasm/api/sqlite3-vtab-helper.c-pp.js ebbabbd33915904d3135680a0ea25f374adb60d6f39d664994bc48ac1673c280
|
||||||
F ext/wasm/api/sqlite3-wasm.c d33a16495ca871781e78812d3a18fed78b797468fffee657b8d7199b277ff359
|
F ext/wasm/api/sqlite3-wasm.c d33a16495ca871781e78812d3a18fed78b797468fffee657b8d7199b277ff359
|
||||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f234191fe6bf41a5a1e59c9f43ed816e74a522b3d60d3f556f66c3085c448503
|
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js f234191fe6bf41a5a1e59c9f43ed816e74a522b3d60d3f556f66c3085c448503
|
||||||
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
|
F ext/wasm/api/sqlite3-worker1.c-pp.js 5e8706c2c4af2a57fbcdc02f4e7ef79869971bc21bb8ede777687786ce1c92d5
|
||||||
@ -2156,11 +2157,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 40f0a29e6dd90fcb969d7c0e49728ba0ee8f31d9e8f502b9a21469620a8ad283
|
P 0eddc20f37988df6bce5f407b69e4a315e5cca4af104586e6fe942f0d656cccd
|
||||||
R 31be0596762218f8c1e89235c4c8d052
|
R 1d7e7db8e9c4453b4e333bcfcd1a037e
|
||||||
T *branch * wasm-post-3.45
|
|
||||||
T *sym-wasm-post-3.45 *
|
|
||||||
T -sym-trunk * Cancelled\sby\sbranch.
|
|
||||||
U stephan
|
U stephan
|
||||||
Z 0af9fee02d812416e8b303fb5ea1a236
|
Z d03852f251d26d93c85f34544dbc6738
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
0eddc20f37988df6bce5f407b69e4a315e5cca4af104586e6fe942f0d656cccd
|
ede945fd2360097d9961b8a4b8fb48fea57399cb9163534ed1c3c6b86588b0a5
|
Reference in New Issue
Block a user