mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
Refactor a significant chunk of the OPFS sqlite3_vfs init code into sqlite3.VfsHelper, and internal-use-only API encapsulating code relevant to creating new VFSes in JS. Intended to assist in pending experimentation with an alternative OPFS VFS.
FossilOrigin-Name: e25d7b080a807e35b32cb885ea75b384130e5c6e936dfef783c5b45d9bfe77d8
This commit is contained in:
@ -287,6 +287,7 @@ sqlite3-api.jses += $(dir.common)/whwasmutil.js
|
||||
sqlite3-api.jses += $(dir.jacc)/jaccwabyt.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-glue.js
|
||||
sqlite3-api.jses += $(sqlite3-api-build-version.js)
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-helper.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-opfs.js
|
||||
|
@ -23,13 +23,13 @@ The overall idea is that the following files get concatenated
|
||||
together, in the listed order, the resulting file is loaded by a
|
||||
browser client:
|
||||
|
||||
- `sqlite3-api-prologue.js`\
|
||||
- **`sqlite3-api-prologue.js`**\
|
||||
Contains the initial bootstrap setup of the sqlite3 API
|
||||
objects. This is exposed as a function, rather than objects, so that
|
||||
the next step can pass in a config object which abstracts away parts
|
||||
of the WASM environment, to facilitate plugging it in to arbitrary
|
||||
WASM toolchains.
|
||||
- `../common/whwasmutil.js`\
|
||||
- **`../common/whwasmutil.js`**\
|
||||
A semi-third-party collection of JS/WASM utility code intended to
|
||||
replace much of the Emscripten glue. The sqlite3 APIs internally use
|
||||
these APIs instead of their Emscripten counterparts, in order to be
|
||||
@ -38,47 +38,52 @@ browser client:
|
||||
toolchains. It is "semi-third-party" in that it was created in order
|
||||
to support this tree but is standalone and maintained together
|
||||
with...
|
||||
- `../jaccwabyt/jaccwabyt.js`\
|
||||
- **`../jaccwabyt/jaccwabyt.js`**\
|
||||
Another semi-third-party API which creates bindings between JS
|
||||
and C structs, such that changes to the struct state from either JS
|
||||
or C are visible to the other end of the connection. This is also an
|
||||
independent spinoff project, conceived for the sqlite3 project but
|
||||
maintained separately.
|
||||
- `sqlite3-api-glue.js`\
|
||||
- **`sqlite3-api-glue.js`**\
|
||||
Invokes functionality exposed by the previous two files to
|
||||
flesh out low-level parts of `sqlite3-api-prologue.js`. Most of
|
||||
these pieces related to the `sqlite3.capi.wasm` object.
|
||||
- `sqlite3-api-build-version.js`\
|
||||
- **`sqlite3-api-build-version.js`**\
|
||||
Gets created by the build process and populates the
|
||||
`sqlite3.version` object. This part is not critical, but records the
|
||||
version of the library against which this module was built.
|
||||
- `sqlite3-api-oo1.js`\
|
||||
- **`sqlite3-vfs-helper.js`**\
|
||||
This internal-use-only file installs `sqlite3.VfsHelper` for use by
|
||||
`sqlite3-api-*.js` files which create `sqlite3_vfs` implemenations.
|
||||
`sqlite3.VfsHelper` gets removed from the the `sqlite3` object after
|
||||
the library is finished initializing.
|
||||
- **`sqlite3-api-oo1.js`**\
|
||||
Provides a high-level object-oriented wrapper to the lower-level C
|
||||
API, colloquially known as OO API #1. Its API is similar to other
|
||||
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-worker1.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-worker1.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 #1 API which is implemented in
|
||||
`sqlite3-api-worker1.js`.
|
||||
- `sqlite3-worker1-promiser.js`\
|
||||
- **`sqlite3-worker1-promiser.js`**\
|
||||
Is likewise not part of the amalgamated sources and provides
|
||||
a Promise-based interface into the Worker #1 API. This is
|
||||
a far user-friendlier way to interface with databases running
|
||||
in a Worker thread.
|
||||
- `sqlite3-api-opfs.js`\
|
||||
- **`sqlite3-api-opfs.js`**\
|
||||
is an sqlite3 VFS implementation which supports Google Chrome's
|
||||
Origin-Private FileSystem (OPFS) as a storage layer to provide
|
||||
persistent storage for database files in a browser. It requires...
|
||||
- `sqlite3-opfs-async-proxy.js`\
|
||||
- **`sqlite3-opfs-async-proxy.js`**\
|
||||
is the asynchronous backend part of the OPFS proxy. It speaks
|
||||
directly to the (async) OPFS API and channels those results back
|
||||
to its synchronous counterpart. This file, because it must be
|
||||
|
@ -60,7 +60,7 @@ const toExportForES6 =
|
||||
initModuleState.sqlite3Dir = li.join('/') + '/';
|
||||
}
|
||||
|
||||
self.sqlite3InitModule = (...args)=>{
|
||||
self.sqlite3InitModule = function ff(...args){
|
||||
//console.warn("Using replaced sqlite3InitModule()",self.location);
|
||||
return originalInit(...args).then((EmscriptenModule)=>{
|
||||
if(self.window!==self &&
|
||||
@ -76,10 +76,12 @@ const toExportForES6 =
|
||||
Emscripten details. */
|
||||
return EmscriptenModule;
|
||||
}
|
||||
EmscriptenModule.sqlite3.scriptInfo = initModuleState;
|
||||
//console.warn("sqlite3.scriptInfo =",EmscriptenModule.sqlite3.scriptInfo);
|
||||
const f = EmscriptenModule.sqlite3.asyncPostInit;
|
||||
delete EmscriptenModule.sqlite3.asyncPostInit;
|
||||
const s = EmscriptenModule.sqlite3;
|
||||
s.scriptInfo = initModuleState;
|
||||
//console.warn("sqlite3.scriptInfo =",s.scriptInfo);
|
||||
if(ff.__isUnderTest) s.__isUnderTest = true;
|
||||
const f = s.asyncPostInit;
|
||||
delete s.asyncPostInit;
|
||||
return f();
|
||||
}).catch((e)=>{
|
||||
console.error("Exception loading sqlite3 module:",e);
|
||||
|
@ -58,8 +58,6 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build
|
||||
self.S = sqlite3;
|
||||
}
|
||||
|
||||
/* Clean up temporary references to our APIs... */
|
||||
delete sqlite3.util /* arguable, but these are (currently) internal-use APIs */;
|
||||
Module.sqlite3 = sqlite3 /* Needed for customized sqlite3InitModule() to be able to
|
||||
pass the sqlite3 object off to the client. */;
|
||||
}else{
|
||||
|
@ -129,7 +129,7 @@ const installOpfsVfs = function callee(options){
|
||||
const log = (...args)=>logImpl(2, ...args);
|
||||
const warn = (...args)=>logImpl(1, ...args);
|
||||
const error = (...args)=>logImpl(0, ...args);
|
||||
const toss = function(...args){throw new Error(args.join(' '))};
|
||||
const toss = sqlite3.util.toss;
|
||||
const capi = sqlite3.capi;
|
||||
const wasm = sqlite3.wasm;
|
||||
const sqlite3_vfs = capi.sqlite3_vfs;
|
||||
@ -191,6 +191,8 @@ const installOpfsVfs = function callee(options){
|
||||
s.count = s.time = 0;
|
||||
}
|
||||
}/*metrics*/;
|
||||
const opfsVfs = new sqlite3_vfs();
|
||||
const opfsIoMethods = new sqlite3_io_methods();
|
||||
const promiseReject = function(err){
|
||||
opfsVfs.dispose();
|
||||
return promiseReject_(err);
|
||||
@ -213,8 +215,6 @@ const installOpfsVfs = function callee(options){
|
||||
? new sqlite3_vfs(pDVfs)
|
||||
: null /* dVfs will be null when sqlite3 is built with
|
||||
SQLITE_OS_OTHER. */;
|
||||
const opfsVfs = new sqlite3_vfs();
|
||||
const opfsIoMethods = new sqlite3_io_methods();
|
||||
opfsVfs.$iVersion = 2/*yes, two*/;
|
||||
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
||||
opfsVfs.$mxPathname = 1024/*sure, why not?*/;
|
||||
@ -633,77 +633,6 @@ const installOpfsVfs = function callee(options){
|
||||
*/
|
||||
const __openFiles = Object.create(null);
|
||||
|
||||
/**
|
||||
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.).
|
||||
|
||||
Returns a proxy for this function which is bound to tgt and takes
|
||||
2 args (name,func). That function returns the same thing,
|
||||
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.
|
||||
*/
|
||||
const installMethod = function callee(tgt, name, func){
|
||||
if(!(tgt instanceof sqlite3.StructBinder.StructType)){
|
||||
toss("Usage error: target object is-not-a StructType.");
|
||||
}
|
||||
if(1===arguments.length){
|
||||
return (n,f)=>callee(tgt,n,f);
|
||||
}
|
||||
if(!callee.argcProxy){
|
||||
callee.argcProxy = function(func,sig){
|
||||
return function(...args){
|
||||
if(func.length!==arguments.length){
|
||||
toss("Argument mismatch. Native signature is:",sig);
|
||||
}
|
||||
return func.apply(this, args);
|
||||
}
|
||||
};
|
||||
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," is not a function pointer. Signature =",sigN);
|
||||
}
|
||||
const memKey = tgt.memberKey(name);
|
||||
const fProxy = 0
|
||||
/** 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(func, sigN)
|
||||
: func;
|
||||
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true));
|
||||
tgt[memKey] = pFunc;
|
||||
if(!tgt.ondispose) tgt.ondispose = [];
|
||||
if(!tgt.ondispose.__removeFuncList){
|
||||
tgt.ondispose.push('ondispose.__removeFuncList handler',
|
||||
callee.removeFuncList);
|
||||
tgt.ondispose.__removeFuncList = [];
|
||||
}
|
||||
tgt.ondispose.__removeFuncList.push(memKey, pFunc);
|
||||
return (n,f)=>callee(tgt, n, f);
|
||||
}/*installMethod*/;
|
||||
|
||||
const opTimer = Object.create(null);
|
||||
opTimer.op = undefined;
|
||||
opTimer.start = undefined;
|
||||
@ -729,7 +658,11 @@ const installOpfsVfs = function callee(options){
|
||||
success) release a sync-handle for it, but doing so would
|
||||
involve an inherent race condition. For the time being,
|
||||
pending a better solution, we simply report whether the
|
||||
given pFile instance has a lock.
|
||||
given pFile is open.
|
||||
|
||||
FIXME: we need to ask the async half whether a lock is
|
||||
held, as it's possible (since long after this method was
|
||||
implemented) that we do not hold a lock on an OPFS file.
|
||||
*/
|
||||
const f = __openFiles[pFile];
|
||||
wasm.setMemValue(pOut, f.lockMode ? 1 : 0, 'i32');
|
||||
@ -948,14 +881,6 @@ const installOpfsVfs = function callee(options){
|
||||
};
|
||||
}
|
||||
|
||||
/* Install the vfs/io_methods into their C-level shared instances... */
|
||||
for(let k of Object.keys(ioSyncWrappers)){
|
||||
installMethod(opfsIoMethods, k, ioSyncWrappers[k]);
|
||||
}
|
||||
for(let k of Object.keys(vfsSyncWrappers)){
|
||||
installMethod(opfsVfs, k, vfsSyncWrappers[k]);
|
||||
}
|
||||
|
||||
/**
|
||||
Expects an OPFS file path. It gets resolved, such that ".."
|
||||
components are properly expanded, and returned. If the 2nd arg
|
||||
@ -1095,8 +1020,9 @@ const installOpfsVfs = function callee(options){
|
||||
Irrevocably deletes _all_ files in the current origin's OPFS.
|
||||
Obviously, this must be used with great caution. It may throw
|
||||
an exception if removal of anything fails (e.g. a file is
|
||||
locked), but the precise conditions under which it will throw
|
||||
are not documented (so we cannot tell you what they are).
|
||||
locked), but the precise conditions under which the underlying
|
||||
APIs will throw are not documented (so we cannot tell you what
|
||||
they are).
|
||||
*/
|
||||
opfsUtil.rmfr = async function(){
|
||||
const dir = opfsUtil.rootDirectory, opt = {recurse: true};
|
||||
@ -1320,14 +1246,10 @@ const installOpfsVfs = function callee(options){
|
||||
and has finished initializing, so the real work can
|
||||
begin...*/
|
||||
try {
|
||||
const rc = capi.sqlite3_vfs_register(opfsVfs.pointer, 0);
|
||||
if(rc){
|
||||
toss("sqlite3_vfs_register(OPFS) failed with rc",rc);
|
||||
}
|
||||
if(opfsVfs.pointer !== capi.sqlite3_vfs_find("opfs")){
|
||||
toss("BUG: sqlite3_vfs_find() failed for just-installed OPFS VFS");
|
||||
}
|
||||
capi.sqlite3_vfs_register.addReference(opfsVfs, opfsIoMethods);
|
||||
sqlite3.VfsHelper.installVfs({
|
||||
io: {struct: opfsIoMethods, methods: ioSyncWrappers},
|
||||
vfs: {struct: opfsVfs, methods: vfsSyncWrappers}
|
||||
});
|
||||
state.sabOPView = new Int32Array(state.sabOP);
|
||||
state.sabFileBufView = new Uint8Array(state.sabIO, 0, state.fileBufferSize);
|
||||
state.sabS11nView = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
|
||||
|
@ -612,8 +612,11 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
isBindableTypedArray,
|
||||
isInt32, isSQLableTypedArray, isTypedArray,
|
||||
typedArrayToString,
|
||||
isUIThread: ()=>'undefined'===typeof WorkerGlobalScope,
|
||||
isUIThread: ()=>(self.window===self && !!self.document),
|
||||
// is this true for ESM?: 'undefined'===typeof WorkerGlobalScope
|
||||
isSharedTypedArray,
|
||||
toss: function(...args){throw new Error(args.join(' '))},
|
||||
toss3,
|
||||
typedArrayPart
|
||||
};
|
||||
|
||||
@ -1460,7 +1463,17 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
//let p = lip.shift();
|
||||
//while(lip.length) p = p.then(lip.shift());
|
||||
//return p.then(()=>sqlite3);
|
||||
return Promise.all(lip).then(()=>sqlite3);
|
||||
return Promise.all(lip).then(()=>{
|
||||
if(!sqlite3.__isUnderTest){
|
||||
/* Delete references to internal-only APIs which are used by
|
||||
some initializers. Retain them when running in test mode
|
||||
so that we can add tests for them. */
|
||||
delete sqlite3.util;
|
||||
delete sqlite3.VfsHelper;
|
||||
delete sqlite3.StructBinder;
|
||||
}
|
||||
return sqlite3;
|
||||
});
|
||||
},
|
||||
/**
|
||||
scriptInfo ideally gets injected into this object by the
|
||||
|
209
ext/wasm/api/sqlite3-vfs-helper.js
Normal file
209
ext/wasm/api/sqlite3-vfs-helper.js
Normal file
@ -0,0 +1,209 @@
|
||||
/*
|
||||
** 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 sqlite.VfsHelper, an object which exists
|
||||
to assist in the creation of JavaScript implementations of
|
||||
sqlite3_vfs. It is NOT part of the public API, and is an
|
||||
internal implemenation detail for use in this project's
|
||||
own development of VFSes. It may be exposed to clients
|
||||
at some point, provided there is value in doing so.
|
||||
*/
|
||||
'use strict';
|
||||
self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
const wasm = sqlite3.wasm, capi = sqlite3.capi, toss = sqlite3.util.toss;
|
||||
const vh = Object.create(null);
|
||||
|
||||
/**
|
||||
Does nothing more than holds a permanent reference to each
|
||||
argument. This is useful in some cases to ensure that, e.g., a
|
||||
custom sqlite3_io_methods instance does not get
|
||||
garbage-collected.
|
||||
|
||||
Returns this object.
|
||||
*/
|
||||
vh.holdReference = function(...args){
|
||||
for(const v of args) this.refs.add(v);
|
||||
return vh;
|
||||
}.bind({refs: new Set});
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
If applyArgcCheck is true then each method 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 recommended for dev-time usage for
|
||||
sanity checking. Once a VFS implementation is known to be
|
||||
working, it is a given that the C API will never call it with the
|
||||
wrong argument count.
|
||||
|
||||
Returns a proxy for this function which is bound to tgt and takes
|
||||
2 args (name,func). That function returns the same thing,
|
||||
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.
|
||||
|
||||
If tgt.ondispose is set before this is called then it _must_
|
||||
be an array, to which this function will append entries.
|
||||
*/
|
||||
vh.installMethod = function callee(tgt, name, func,
|
||||
applyArgcCheck=callee.installMethodArgcCheck){
|
||||
if(!(tgt instanceof sqlite3.StructBinder.StructType)){
|
||||
toss("Usage error: target object is-not-a StructType.");
|
||||
}
|
||||
if(1===arguments.length){
|
||||
return (n,f)=>callee(tgt, n, f, applyArgcCheck);
|
||||
}
|
||||
if(!callee.argcProxy){
|
||||
callee.argcProxy = function(func,sig){
|
||||
return function(...args){
|
||||
if(func.length!==arguments.length){
|
||||
toss("Argument mismatch. Native signature is:",sig);
|
||||
}
|
||||
return func.apply(this, args);
|
||||
}
|
||||
};
|
||||
/* An ondispose() callback for use with
|
||||
sqlite3.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," is not a function pointer. Signature =",sigN);
|
||||
}
|
||||
const memKey = tgt.memberKey(name);
|
||||
const fProxy = applyArgcCheck
|
||||
/** 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(func, sigN)
|
||||
: func;
|
||||
const pFunc = wasm.installFunction(fProxy, tgt.memberSignature(name, true));
|
||||
tgt[memKey] = pFunc;
|
||||
if(!tgt.ondispose) tgt.ondispose = [];
|
||||
if(!tgt.ondispose.__removeFuncList){
|
||||
tgt.ondispose.push('ondispose.__removeFuncList handler',
|
||||
callee.removeFuncList);
|
||||
tgt.ondispose.__removeFuncList = [];
|
||||
}
|
||||
tgt.ondispose.__removeFuncList.push(memKey, pFunc);
|
||||
return (n,f)=>callee(tgt, n, f, applyArgcCheck);
|
||||
}/*installMethod*/;
|
||||
vh.installMethod.installMethodArgcCheck = false;
|
||||
|
||||
/**
|
||||
Installs methods into the given StructType-type object. 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.
|
||||
|
||||
On success, passes its first argument to holdRefence() and
|
||||
returns this object. Throws on error.
|
||||
*/
|
||||
vh.installMethods = function(structType, methods,
|
||||
applyArgcCheck=vh.installMethod.installMethodArgcCheck){
|
||||
for(const k of Object.keys(methods)){
|
||||
vh.installMethod(structType, k, methods[k], applyArgcCheck);
|
||||
}
|
||||
return vh.holdReference(structType);
|
||||
};
|
||||
|
||||
/**
|
||||
Uses sqlite3_vfs_register() to register the
|
||||
sqlite3.capi.sqlite3_vfs-type vfs, which must have already been
|
||||
filled out properly. If the 2nd argument is truthy, the VFS is
|
||||
registered as the default VFS, else it is not.
|
||||
|
||||
On success, passes its first argument to this.holdReference() and
|
||||
returns this object. Throws on error.
|
||||
*/
|
||||
vh.registerVfs = function(vfs, asDefault=false){
|
||||
if(!(vfs instanceof sqlite3.capi.sqlite3_vfs)){
|
||||
toss("Expecting a sqlite3_vfs-type argument.");
|
||||
}
|
||||
const rc = capi.sqlite3_vfs_register(vfs.pointer, asDefault ? 1 : 0);
|
||||
if(rc){
|
||||
toss("sqlite3_vfs_register(",vfs,") failed with rc",rc);
|
||||
}
|
||||
if(vfs.pointer !== capi.sqlite3_vfs_find(vfs.$zName)){
|
||||
toss("BUG: sqlite3_vfs_find(vfs.$zName) failed for just-installed VFS",
|
||||
vfs);
|
||||
}
|
||||
return vh.holdReference(vfs);
|
||||
};
|
||||
|
||||
/**
|
||||
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.
|
||||
|
||||
For each of those object, this function passes its (`struct`,
|
||||
`methods`, (optional) `applyArgcCheck`) properties to
|
||||
this.installMethods().
|
||||
|
||||
If the `vfs` entry is set, its `struct` property is passed
|
||||
to this.registerVfs(). The `vfs` entry may optionally have
|
||||
an `asDefault` property, which gets passed as the 2nd
|
||||
argument to registerVfs().
|
||||
|
||||
On success returns this object. Throws on error.
|
||||
*/
|
||||
vh.installVfs = function(opt){
|
||||
let count = 0;
|
||||
for(const key of ['io','vfs']){
|
||||
const o = opt[key];
|
||||
if(o){
|
||||
++count;
|
||||
this.installMethods(o.struct, o.methods, !!o.applyArgcCheck);
|
||||
if('vfs'===key) this.registerVfs(o.struct, !!o.asDefault);
|
||||
}
|
||||
}
|
||||
if(!count) toss("Misue: installVfs() options object requires at least",
|
||||
"one of 'io' or 'vfs' properties.");
|
||||
return this;
|
||||
};
|
||||
|
||||
sqlite3.VfsHelper = vh;
|
||||
}/*sqlite3ApiBootstrap.initializers.push()*/);
|
@ -1867,6 +1867,9 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
}
|
||||
importScripts(sqlite3Js);
|
||||
}
|
||||
self.sqlite3InitModule.__isUnderTest =
|
||||
true /* disables certain API-internal cleanup so that we can
|
||||
test internal APIs from here */;
|
||||
self.sqlite3InitModule({
|
||||
print: log,
|
||||
printErr: error
|
||||
|
25
manifest
25
manifest
@ -1,5 +1,5 @@
|
||||
C Doc\sand\slogging\stext\stweaks\sin\sthe\sOPFS\sasync\sproxy\sand\stest\sapp.
|
||||
D 2022-11-30T03:08:50.289
|
||||
C Refactor\sa\ssignificant\schunk\sof\sthe\sOPFS\ssqlite3_vfs\sinit\scode\sinto\ssqlite3.VfsHelper,\sand\sinternal-use-only\sAPI\sencapsulating\scode\srelevant\sto\screating\snew\sVFSes\sin\sJS.\sIntended\sto\sassist\sin\spending\sexperimentation\swith\san\salternative\sOPFS\sVFS.
|
||||
D 2022-11-30T05:27:36.071
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -491,25 +491,26 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||
F ext/wasm/GNUmakefile bc1696a1189f4c571b3d878b8f3a67c1f4b52c222f52d356027a5a0c707337c7
|
||||
F ext/wasm/GNUmakefile a1a94ff422be90c06263055aec4c569fe3e4ffb3e8cc7f954fd2739aefa52292
|
||||
F ext/wasm/README-dist.txt 2d670b426fc7c613b90a7d2f2b05b433088fe65181abead970980f0a4a75ea20
|
||||
F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api b4d68c97d14944b48d55e06aa44f544a6f56a7fa2bcb6f9e030936a5b2a9479a
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
F ext/wasm/api/README.md 29276a845e57004e82efba61fa5866fd05f9137380a1dc26dc4c6d65264cd81c
|
||||
F ext/wasm/api/extern-post-js.js 59e52f579cd3a332d73dae94c91b9579daafb10dd6ada03803f1afa6bdad7689
|
||||
F ext/wasm/api/README.md 44d1ea63a990678e373f17ff4b08c2f8599e5a5754b7394e76f7e52164f307c0
|
||||
F ext/wasm/api/extern-post-js.js 8923f76c3d2213159e12d641dc750523ead5c848185dc4996fae5cc12397f88d
|
||||
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
||||
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
|
||||
F ext/wasm/api/post-js-header.js d6ab3dfef4a06960d28a7eaa338d4e2a1a5981e9b38718168bbde8fdb2a439b8
|
||||
F ext/wasm/api/pre-js.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js ecdc69dbfccfe26146f04799fcfd4a6f5790d46e7e3b9b6e9b0491f92ed8ae34
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js 6a22a3287b34a2b4b0f8127614242e8307cce31ac060eb705a89a6d04dcb1028
|
||||
F ext/wasm/api/sqlite3-api-glue.js 056f44b82c126358a0175e08a892d56fadfce177b0d7a0012502a6acf67ea6d5
|
||||
F ext/wasm/api/sqlite3-api-oo1.js 06ad2079368e16cb9f182c18cd37bdc3932536856dff4f60582d0ca5f6c491a8
|
||||
F ext/wasm/api/sqlite3-api-opfs.js 2f99c9b2c3c0f53bf40153de20db350378deed825ec0d5cf8f449e9e0081f08b
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 7fce4c6a138ec3d7c285b7c125cee809e6b668d2cb0d2328a1b790b7037765bd
|
||||
F ext/wasm/api/sqlite3-api-opfs.js e36eec4535dab2da186c1fc743b8fb3a37b21a7c61425546d748a3038c25efab
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 09fa4bf1e29596e599ead649003e01691419ffcb12d0f617152d577741973227
|
||||
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
|
||||
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 315582a4fe3b87ceaff69ad4a67d68a350b8014ac94d6a584d09ea922453c983
|
||||
F ext/wasm/api/sqlite3-vfs-helper.js 0b1de47e4407a414db1ee0ca3f9916ae74a9655fe1b1145d4a08e2b52f1ee25f
|
||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||
F ext/wasm/api/sqlite3-wasm.c 8b32787a3b6bb2990cbaba2304bd5b75a9652acbc8d29909b3279019b6cbaef5
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
|
||||
@ -554,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
||||
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
|
||||
F ext/wasm/tester1-worker.html 5ef353348c37cf2e4fd0b23da562d3275523e036260b510734e9a3239ba8c987
|
||||
F ext/wasm/tester1.c-pp.html 74aa9b31c75f12490653f814b53c3dd39f40cd3f70d6a53a716f4e8587107399
|
||||
F ext/wasm/tester1.c-pp.js a4b6a165aafcd3b86118efaec6b47c70fbb6c64b5ab86d21ca8c250d42617dfa
|
||||
F ext/wasm/tester1.c-pp.js 5820d578b67835aaf651230663dd207237071ee1f16f11a9c5168500aae04a50
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
|
||||
F ext/wasm/tests/opfs/concurrency/test.js bfc3d7e27b207f0827f12568986b8d516a744529550b449314f5c21c9e9faf4a
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||
@ -2064,8 +2065,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 d0c8fa30a31c691bc1be5e98d806eeb1e23a8fc6cd54d87e5c1b720aa936e707
|
||||
R 05044488394ac3d7b358270198570ce0
|
||||
P 7ce8608e221924d2c7067687eb6eef0f3cab181d5b4132e55a67d8514b6ce94b
|
||||
R 51f96a0acaea8419465c60238f6c368c
|
||||
U stephan
|
||||
Z cb806f606aa315e69c2e3fceeb852a45
|
||||
Z aa663f409b5ddaba03a8fcd513053db4
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
7ce8608e221924d2c7067687eb6eef0f3cab181d5b4132e55a67d8514b6ce94b
|
||||
e25d7b080a807e35b32cb885ea75b384130e5c6e936dfef783c5b45d9bfe77d8
|
Reference in New Issue
Block a user