mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Correct opfs-sahpool VFS after the pebkac involving the previous speedtest1 runs. Make that VFS explicitly opt-in to avoid certain unfortunate locking situations.
FossilOrigin-Name: 41bf1fe31f2f3d0daa2bac25dc57262a4b90f22fed6fa97e4e92467c32ae02dc
This commit is contained in:
@ -53,16 +53,43 @@
|
|||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||||
const installOpfsVfs = async function(sqlite3){
|
const toss = sqlite3.util.toss;
|
||||||
|
let vfsRegisterResult = undefined;
|
||||||
|
/**
|
||||||
|
installOpfsSAHPoolVfs() asynchronously initializes the
|
||||||
|
OPFS SyncAccessHandle Pool VFS. It returns a Promise
|
||||||
|
which either resolves to the sqlite3 object or rejects
|
||||||
|
with an Error value.
|
||||||
|
|
||||||
|
Initialization of this VFS is not automatic because its
|
||||||
|
registration requires that it lock all resources it
|
||||||
|
will potentially use, even if client code does not want
|
||||||
|
to use them. That, in turn, can lead to locking errors
|
||||||
|
when, for example, one page in a given origin has loaded
|
||||||
|
this VFS but does not use it, then another page in that
|
||||||
|
origin tries to use the VFS. If the VFS were automatically
|
||||||
|
registered, the second page would fail to load the VFS
|
||||||
|
due to OPFS locking errors.
|
||||||
|
|
||||||
|
On calls after the first this function immediately returns a
|
||||||
|
resolved or rejected Promise. If called while the first call is
|
||||||
|
still pending resolution, a rejected promise with a descriptive
|
||||||
|
error is returned.
|
||||||
|
*/
|
||||||
|
sqlite3.installOpfsSAHPoolVfs = async function(){
|
||||||
|
if(sqlite3===vfsRegisterResult) return Promise.resolve(sqlite3);
|
||||||
|
else if(undefined!==vfsRegisterResult){
|
||||||
|
return Promise.reject(vfsRegisterResult);
|
||||||
|
}
|
||||||
if(!globalThis.FileSystemHandle ||
|
if(!globalThis.FileSystemHandle ||
|
||||||
!globalThis.FileSystemDirectoryHandle ||
|
!globalThis.FileSystemDirectoryHandle ||
|
||||||
!globalThis.FileSystemFileHandle ||
|
!globalThis.FileSystemFileHandle ||
|
||||||
!globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle ||
|
!globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle ||
|
||||||
!navigator?.storage?.getDirectory){
|
!navigator?.storage?.getDirectory){
|
||||||
return Promise.reject(new Error("Missing required OPFS APIs."));
|
return Promise.reject(vfsRegisterResult = new Error("Missing required OPFS APIs."));
|
||||||
}
|
}
|
||||||
return new Promise(async function(promiseResolve, promiseReject_){
|
vfsRegisterResult = new Error("VFS initialization still underway.");
|
||||||
const verbosity = 2;
|
const verbosity = 2 /*3+ == everything*/;
|
||||||
const loggers = [
|
const loggers = [
|
||||||
sqlite3.config.error,
|
sqlite3.config.error,
|
||||||
sqlite3.config.warn,
|
sqlite3.config.warn,
|
||||||
@ -74,17 +101,19 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
const log = (...args)=>logImpl(2, ...args);
|
const log = (...args)=>logImpl(2, ...args);
|
||||||
const warn = (...args)=>logImpl(1, ...args);
|
const warn = (...args)=>logImpl(1, ...args);
|
||||||
const error = (...args)=>logImpl(0, ...args);
|
const error = (...args)=>logImpl(0, ...args);
|
||||||
const toss = sqlite3.util.toss;
|
|
||||||
const capi = sqlite3.capi;
|
const capi = sqlite3.capi;
|
||||||
const wasm = sqlite3.wasm;
|
const wasm = sqlite3.wasm;
|
||||||
const opfsIoMethods = new capi.sqlite3_io_methods();
|
const opfsIoMethods = new capi.sqlite3_io_methods();
|
||||||
const opfsVfs = new capi.sqlite3_vfs()
|
const opfsVfs = new capi.sqlite3_vfs()
|
||||||
.addOnDispose(()=>opfsIoMethods.dispose());
|
.addOnDispose(()=>opfsIoMethods.dispose());
|
||||||
const promiseReject = (err)=>{
|
const promiseReject = (err)=>{
|
||||||
opfsVfs.dispose();
|
error("rejecting promise:",err);
|
||||||
return promiseReject_(err);
|
//opfsVfs.dispose();
|
||||||
|
vfsRegisterResult = err;
|
||||||
|
return Promise.reject(err);
|
||||||
};
|
};
|
||||||
|
const promiseResolve =
|
||||||
|
()=>Promise.resolve(vfsRegisterResult = sqlite3);
|
||||||
// Config opts for the VFS...
|
// Config opts for the VFS...
|
||||||
const SECTOR_SIZE = 4096;
|
const SECTOR_SIZE = 4096;
|
||||||
const HEADER_MAX_PATH_SIZE = 512;
|
const HEADER_MAX_PATH_SIZE = 512;
|
||||||
@ -113,6 +142,7 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
? new capi.sqlite3_vfs(pDVfs)
|
? new capi.sqlite3_vfs(pDVfs)
|
||||||
: null /* dVfs will be null when sqlite3 is built with
|
: null /* dVfs will be null when sqlite3 is built with
|
||||||
SQLITE_OS_OTHER. */;
|
SQLITE_OS_OTHER. */;
|
||||||
|
opfsIoMethods.$iVersion = 1;
|
||||||
opfsVfs.$iVersion = 2/*yes, two*/;
|
opfsVfs.$iVersion = 2/*yes, two*/;
|
||||||
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
||||||
opfsVfs.$mxPathname = HEADER_MAX_PATH_SIZE;
|
opfsVfs.$mxPathname = HEADER_MAX_PATH_SIZE;
|
||||||
@ -358,13 +388,14 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
(or no) value to clear it.
|
(or no) value to clear it.
|
||||||
*/
|
*/
|
||||||
storeErr: function(e){
|
storeErr: function(e){
|
||||||
|
if(e) error(e);
|
||||||
return this.$error = e;
|
return this.$error = e;
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
Pops this object's Error object and returns
|
Pops this object's Error object and returns
|
||||||
it (a falsy value if no error is set).
|
it (a falsy value if no error is set).
|
||||||
*/
|
*/
|
||||||
popErr: function(e){
|
popErr: function(){
|
||||||
const rc = this.$error;
|
const rc = this.$error;
|
||||||
this.$error = undefined;
|
this.$error = undefined;
|
||||||
return rc;
|
return rc;
|
||||||
@ -377,7 +408,9 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
*/
|
*/
|
||||||
const ioSyncWrappers = {
|
const ioSyncWrappers = {
|
||||||
xCheckReservedLock: function(pFile,pOut){
|
xCheckReservedLock: function(pFile,pOut){
|
||||||
|
log('xCheckReservedLock');
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
|
wasm.poke32(pOut, 1);
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
xClose: function(pFile){
|
xClose: function(pFile){
|
||||||
@ -385,15 +418,15 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
const file = SAHPool.mapIdToFile.get(pFile);
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
if(file) {
|
if(file) {
|
||||||
try{
|
try{
|
||||||
log(`xClose ${file.path}`);
|
log(`xClose ${file}`);
|
||||||
|
if(file.sq3File) file.sq3File.dispose();
|
||||||
file.sah.flush();
|
file.sah.flush();
|
||||||
SAHPool.mapIdToFile.delete(pFIle);
|
SAHPool.mapIdToFile.delete(pFile);
|
||||||
if(file.flags & capi.SQLITE_OPEN_DELETEONCLOSE){
|
if(file.flags & capi.SQLITE_OPEN_DELETEONCLOSE){
|
||||||
SAHPool.deletePath(file.path);
|
SAHPool.deletePath(file.path);
|
||||||
}
|
}
|
||||||
}catch(e){
|
}catch(e){
|
||||||
SAHPool.storeErr(e);
|
SAHPool.storeErr(e);
|
||||||
error("xClose() failed:",e.message);
|
|
||||||
return capi.SQLITE_IOERR;
|
return capi.SQLITE_IOERR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -406,24 +439,29 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
return capi.SQLITE_NOTFOUND;
|
return capi.SQLITE_NOTFOUND;
|
||||||
},
|
},
|
||||||
xFileSize: function(pFile,pSz64){
|
xFileSize: function(pFile,pSz64){
|
||||||
const file = SAHPool.mapIdToFile(pFile);
|
log(`xFileSize`);
|
||||||
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
const size = file.sah.getSize() - HEADER_OFFSET_DATA;
|
const size = file.sah.getSize() - HEADER_OFFSET_DATA;
|
||||||
//log(`xFileSize ${file.path} ${size}`);
|
//log(`xFileSize ${file.path} ${size}`);
|
||||||
wasm.poke64(pSz64, BigInt(size));
|
wasm.poke64(pSz64, BigInt(size));
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
xLock: function(pFile,lockType){
|
xLock: function(pFile,lockType){
|
||||||
|
log(`xLock ${lockType}`);
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
let rc = capi.SQLITE_IOERR;
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
return rc;
|
file.lockType = lockType;
|
||||||
|
return 0;
|
||||||
},
|
},
|
||||||
xRead: function(pFile,pDest,n,offset64){
|
xRead: function(pFile,pDest,n,offset64){
|
||||||
|
log(`xRead ${n}@${offset64}`);
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
const file = SAHPool.mapIdToFile.get(pFile);
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
log(`xRead ${file.path} ${n} ${offset64}`);
|
log(`xRead ${file.path} ${n} ${offset64}`);
|
||||||
try {
|
try {
|
||||||
const nRead = file.sah.read(
|
const nRead = file.sah.read(
|
||||||
pDest, {at: HEADER_OFFSET_DATA + offset64}
|
wasm.heap8u().subarray(pDest, pDest+n),
|
||||||
|
{at: HEADER_OFFSET_DATA + Number(offset64)}
|
||||||
);
|
);
|
||||||
if(nRead < n){
|
if(nRead < n){
|
||||||
wasm.heap8u().fill(0, pDest + nRead, pDest + n);
|
wasm.heap8u().fill(0, pDest + nRead, pDest + n);
|
||||||
@ -436,10 +474,11 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
return capi.SQLITE_IOERR;
|
return capi.SQLITE_IOERR;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
xSectorSize: function(pFile){
|
/*xSectorSize: function(pFile){
|
||||||
return SECTOR_SIZE;
|
return SECTOR_SIZE;
|
||||||
},
|
},*/
|
||||||
xSync: function(pFile,flags){
|
xSync: function(pFile,flags){
|
||||||
|
log(`xSync ${flags}`);
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
const file = SAHPool.mapIdToFile.get(pFile);
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
//log(`xSync ${file.path} ${flags}`);
|
//log(`xSync ${file.path} ${flags}`);
|
||||||
@ -453,6 +492,7 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
xTruncate: function(pFile,sz64){
|
xTruncate: function(pFile,sz64){
|
||||||
|
log(`xTruncate ${sz64}`);
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
const file = SAHPool.mapIdToFile.get(pFile);
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
//log(`xTruncate ${file.path} ${iSize}`);
|
//log(`xTruncate ${file.path} ${iSize}`);
|
||||||
@ -465,16 +505,20 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
return capi.SQLITE_IOERR;
|
return capi.SQLITE_IOERR;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
/**xUnlock: function(pFile,lockType){
|
xUnlock: function(pFile,lockType){
|
||||||
return capi.SQLITE_IOERR;
|
log('xUnlock');
|
||||||
},*/
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
|
file.lockType = lockType;
|
||||||
|
return 0;
|
||||||
|
},
|
||||||
xWrite: function(pFile,pSrc,n,offset64){
|
xWrite: function(pFile,pSrc,n,offset64){
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
const file = SAHPool.mapIdToFile(pFile);
|
const file = SAHPool.mapIdToFile.get(pFile);
|
||||||
//log(`xWrite ${file.path} ${n} ${offset64}`);
|
log(`xWrite ${file.path} ${n} ${offset64}`);
|
||||||
try{
|
try{
|
||||||
const nBytes = file.sah.write(
|
const nBytes = file.sah.write(
|
||||||
pSrc, { at: HEADER_OFFSET_DATA + Number(offset64) }
|
wasm.heap8u().subarray(pSrc, pSrc+n),
|
||||||
|
{ at: HEADER_OFFSET_DATA + Number(offset64) }
|
||||||
);
|
);
|
||||||
return nBytes === n ? 0 : capi.SQLITE_IOERR;
|
return nBytes === n ? 0 : capi.SQLITE_IOERR;
|
||||||
}catch(e){
|
}catch(e){
|
||||||
@ -491,6 +535,7 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
*/
|
*/
|
||||||
const vfsSyncWrappers = {
|
const vfsSyncWrappers = {
|
||||||
xAccess: function(pVfs,zName,flags,pOut){
|
xAccess: function(pVfs,zName,flags,pOut){
|
||||||
|
log(`xAccess ${wasm.cstrToJs(zName)}`);
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
try{
|
try{
|
||||||
const name = this.getPath(zName);
|
const name = this.getPath(zName);
|
||||||
@ -511,6 +556,7 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
xDelete: function(pVfs, zName, doSyncDir){
|
xDelete: function(pVfs, zName, doSyncDir){
|
||||||
|
log(`xDelete ${wasm.cstrToJs(zName)}`);
|
||||||
SAHPool.storeErr();
|
SAHPool.storeErr();
|
||||||
try{
|
try{
|
||||||
SAHPool.deletePath(SAHPool.getPath(zName));
|
SAHPool.deletePath(SAHPool.getPath(zName));
|
||||||
@ -522,10 +568,12 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
xFullPathname: function(pVfs,zName,nOut,pOut){
|
xFullPathname: function(pVfs,zName,nOut,pOut){
|
||||||
|
log(`xFullPathname ${wasm.cstrToJs(zName)}`);
|
||||||
const i = wasm.cstrncpy(pOut, zName, nOut);
|
const i = wasm.cstrncpy(pOut, zName, nOut);
|
||||||
return i<nOut ? 0 : capi.SQLITE_CANTOPEN;
|
return i<nOut ? 0 : capi.SQLITE_CANTOPEN;
|
||||||
},
|
},
|
||||||
xGetLastError: function(pVfs,nOut,pOut){
|
xGetLastError: function(pVfs,nOut,pOut){
|
||||||
|
log(`xGetLastError ${nOut}`);
|
||||||
const e = SAHPool.popErr();
|
const e = SAHPool.popErr();
|
||||||
if(e){
|
if(e){
|
||||||
const scope = wasm.scopedAllocPush();
|
const scope = wasm.scopedAllocPush();
|
||||||
@ -543,31 +591,35 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
},
|
},
|
||||||
//xSleep is optionally defined below
|
//xSleep is optionally defined below
|
||||||
xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
|
xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
|
||||||
|
log(`xOpen ${wasm.cstrToJs(zName)} ${flags}`);
|
||||||
try{
|
try{
|
||||||
// First try to open a path that already exists in the file system.
|
// First try to open a path that already exists in the file system.
|
||||||
const path = (zName && wasm.peek8(zName))
|
const path = (zName && wasm.peek8(zName))
|
||||||
? SAHPool.getPath(name)
|
? SAHPool.getPath(zName)
|
||||||
: getRandomName();
|
: getRandomName();
|
||||||
let ah = SAHPool.mapPathToSAH.get(path);
|
let sah = SAHPool.mapPathToSAH.get(path);
|
||||||
if(!ah && (flags & capi.SQLITE_OPEN_CREATE)) {
|
if(!sah && (flags & capi.SQLITE_OPEN_CREATE)) {
|
||||||
// File not found so try to create it.
|
// File not found so try to create it.
|
||||||
if(SAHPool.getFileCount() < SAHPool.getCapacity()) {
|
if(SAHPool.getFileCount() < SAHPool.getCapacity()) {
|
||||||
// Choose an unassociated OPFS file from the pool.
|
// Choose an unassociated OPFS file from the pool.
|
||||||
ah = SAHPool.availableSAH.keys()[0];
|
[sah] = SAHPool.availableSAH.keys();
|
||||||
SAHPool.setAssociatedPath(ah, path, flags);
|
SAHPool.setAssociatedPath(sah, path, flags);
|
||||||
}else{
|
}else{
|
||||||
// File pool is full.
|
// File pool is full.
|
||||||
toss('SAH pool is full. Cannot create file',path);
|
toss('SAH pool is full. Cannot create file',path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!ah){
|
if(!sah){
|
||||||
toss('file not found:',path);
|
toss('file not found:',path);
|
||||||
}
|
}
|
||||||
// Subsequent methods are only passed the file pointer, so
|
// Subsequent methods are only passed the file pointer, so
|
||||||
// map the relevant info we need to that pointer.
|
// map the relevant info we need to that pointer.
|
||||||
const file = { path, flags, ah };
|
const file = {path, flags, sah};
|
||||||
SAHPool.mapIdToFile.set(pFile, file);
|
SAHPool.mapIdToFile.set(pFile, file);
|
||||||
wasm.poke32(pOutFlags, flags);
|
wasm.poke32(pOutFlags, flags);
|
||||||
|
file.sq3File = new capi.sqlite3_file(pFile);
|
||||||
|
file.sq3File.$pMethods = opfsIoMethods.pointer;
|
||||||
|
file.lockType = capi.SQLITE_LOCK_NONE;
|
||||||
return 0;
|
return 0;
|
||||||
}catch(e){
|
}catch(e){
|
||||||
SAHPool.storeErr(e);
|
SAHPool.storeErr(e);
|
||||||
@ -592,17 +644,16 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if(!opfsVfs.$xSleep){
|
if(!opfsVfs.$xSleep){
|
||||||
vfsSyncWrappers.xSleep = function(pVfs,ms){
|
vfsSyncWrappers.xSleep = (pVfs,ms)=>0;
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Ensure that the client has a "fully-sync" SAH impl,
|
Ensure that the client has a "fully-sync" SAH impl,
|
||||||
else reject the promise. Returns true on success,
|
else reject the promise. Returns true on success,
|
||||||
else false.
|
else a value intended to be returned via the containing
|
||||||
|
function's Promise result.
|
||||||
*/
|
*/
|
||||||
if(!(async ()=>{
|
const apiVersionCheck = await (async ()=>{
|
||||||
try {
|
try {
|
||||||
const dh = await navigator.storage.getDirectory();
|
const dh = await navigator.storage.getDirectory();
|
||||||
const fn = '.opfs-sahpool-sync-check-'+getRandomName();
|
const fn = '.opfs-sahpool-sync-check-'+getRandomName();
|
||||||
@ -617,14 +668,13 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}catch(e){
|
}catch(e){
|
||||||
promiseReject(e);
|
return e;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
})()){
|
})();
|
||||||
return;
|
if(true!==apiVersionCheck){
|
||||||
|
return promiseReject(apiVersionCheck);
|
||||||
}
|
}
|
||||||
|
return SAHPool.isReady = SAHPool.reset().then(async ()=>{
|
||||||
SAHPool.isReady = SAHPool.reset().then(async ()=>{
|
|
||||||
if(SAHPool.$error){
|
if(SAHPool.$error){
|
||||||
throw SAHPool.$error;
|
throw SAHPool.$error;
|
||||||
}
|
}
|
||||||
@ -634,9 +684,11 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
//log("vfs list:",capi.sqlite3_js_vfs_list());
|
//log("vfs list:",capi.sqlite3_js_vfs_list());
|
||||||
sqlite3.vfs.installVfs({
|
sqlite3.vfs.installVfs({
|
||||||
io: {struct: opfsIoMethods, methods: ioSyncWrappers},
|
io: {struct: opfsIoMethods, methods: ioSyncWrappers},
|
||||||
vfs: {struct: opfsVfs, methods: vfsSyncWrappers}
|
vfs: {struct: opfsVfs, methods: vfsSyncWrappers},
|
||||||
|
applyArgcCheck: true
|
||||||
});
|
});
|
||||||
//log("vfs list:",capi.sqlite3_js_vfs_list());
|
log("opfsVfs",opfsVfs,"opfsIoMethods",opfsIoMethods);
|
||||||
|
log("vfs list:",capi.sqlite3_js_vfs_list());
|
||||||
if(sqlite3.oo1){
|
if(sqlite3.oo1){
|
||||||
const OpfsSAHPoolDb = function(...args){
|
const OpfsSAHPoolDb = function(...args){
|
||||||
const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args);
|
const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args);
|
||||||
@ -683,15 +735,7 @@ const installOpfsVfs = async function(sqlite3){
|
|||||||
);
|
);
|
||||||
}/*extend sqlite3.oo1*/
|
}/*extend sqlite3.oo1*/
|
||||||
log("VFS initialized.");
|
log("VFS initialized.");
|
||||||
promiseResolve(sqlite3);
|
return promiseResolve();
|
||||||
}).catch(promiseReject);
|
}).catch(promiseReject);
|
||||||
})/*return Promise*/;
|
}/*installOpfsSAHPoolVfs()*/;
|
||||||
}/*installOpfsVfs()*/;
|
|
||||||
|
|
||||||
globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
|
|
||||||
return installOpfsVfs(sqlite3).catch((e)=>{
|
|
||||||
sqlite3.config.warn("Ignoring inability to install opfs-sahpool sqlite3_vfs:",
|
|
||||||
e.message, e);
|
|
||||||
});
|
|
||||||
}/*sqlite3ApiBootstrap.initializersAsync*/);
|
|
||||||
}/*sqlite3ApiBootstrap.initializers*/);
|
}/*sqlite3ApiBootstrap.initializers*/);
|
||||||
|
@ -236,6 +236,7 @@ const installOpfsVfs = function callee(options){
|
|||||||
? new sqlite3_vfs(pDVfs)
|
? new sqlite3_vfs(pDVfs)
|
||||||
: null /* dVfs will be null when sqlite3 is built with
|
: null /* dVfs will be null when sqlite3 is built with
|
||||||
SQLITE_OS_OTHER. */;
|
SQLITE_OS_OTHER. */;
|
||||||
|
opfsIoMethods.$iVersion = 1;
|
||||||
opfsVfs.$iVersion = 2/*yes, two*/;
|
opfsVfs.$iVersion = 2/*yes, two*/;
|
||||||
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
||||||
opfsVfs.$mxPathname = 1024/*sure, why not?*/;
|
opfsVfs.$mxPathname = 1024/*sure, why not?*/;
|
||||||
|
@ -71,20 +71,48 @@
|
|||||||
self.onmessage = function(msg){
|
self.onmessage = function(msg){
|
||||||
msg = msg.data;
|
msg = msg.data;
|
||||||
switch(msg.type){
|
switch(msg.type){
|
||||||
case 'run': runSpeedtest(msg.data || []); break;
|
case 'run':
|
||||||
|
try {
|
||||||
|
runSpeedtest(msg.data || []);
|
||||||
|
}catch(e){
|
||||||
|
mPost('error',e);
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
logErr("Unhandled worker message type:",msg.type);
|
logErr("Unhandled worker message type:",msg.type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sahpSanityChecks = function(sqlite3){
|
||||||
|
log("Attempting OpfsSAHPoolDb sanity checks...");
|
||||||
|
const db = new sqlite3.oo1.OpfsSAHPoolDb('opfs-sahpoool.db');
|
||||||
|
const fn = db.filename;
|
||||||
|
db.exec([
|
||||||
|
'create table t(a);',
|
||||||
|
'insert into t(a) values(1),(2),(3);'
|
||||||
|
]);
|
||||||
|
db.close();
|
||||||
|
sqlite3.wasm.sqlite3_wasm_vfs_unlink(sqlite3_vfs_find("opfs-sahpool"), fn);
|
||||||
|
log("SAH sanity checks done.");
|
||||||
|
};
|
||||||
|
|
||||||
const EmscriptenModule = {
|
const EmscriptenModule = {
|
||||||
print: log,
|
print: log,
|
||||||
printErr: logErr,
|
printErr: logErr,
|
||||||
setStatus: (text)=>mPost('load-status',text)
|
setStatus: (text)=>mPost('load-status',text)
|
||||||
};
|
};
|
||||||
self.sqlite3InitModule(EmscriptenModule).then((sqlite3)=>{
|
log("Initializing speedtest1 module...");
|
||||||
const S = sqlite3;
|
self.sqlite3InitModule(EmscriptenModule).then(async (sqlite3)=>{
|
||||||
|
const S = globalThis.S = sqlite3;
|
||||||
|
log("Loaded speedtest1 module. Setting up...");
|
||||||
|
if(S.installOpfsSAHPoolVfs){
|
||||||
|
await S.installOpfsSAHPoolVfs().then(()=>{
|
||||||
|
log("Loaded SAHPool.");
|
||||||
|
}).catch(e=>{
|
||||||
|
logErr("Error setting up SAHPool:",e.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
App.vfsUnlink = function(pDb, fname){
|
App.vfsUnlink = function(pDb, fname){
|
||||||
const pVfs = S.wasm.sqlite3_wasm_db_vfs(pDb, 0);
|
const pVfs = S.wasm.sqlite3_wasm_db_vfs(pDb, 0);
|
||||||
if(pVfs) S.wasm.sqlite3_wasm_vfs_unlink(pVfs, fname||0);
|
if(pVfs) S.wasm.sqlite3_wasm_vfs_unlink(pVfs, fname||0);
|
||||||
@ -95,5 +123,10 @@
|
|||||||
//else log("Using transient storage.");
|
//else log("Using transient storage.");
|
||||||
mPost('ready',true);
|
mPost('ready',true);
|
||||||
log("Registered VFSes:", ...S.capi.sqlite3_js_vfs_list());
|
log("Registered VFSes:", ...S.capi.sqlite3_js_vfs_list());
|
||||||
|
if(0 && S.installOpfsSAHPoolVfs){
|
||||||
|
sahpSanityChecks(S);
|
||||||
|
}
|
||||||
|
}).catch(e=>{
|
||||||
|
logErr(e);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
|||||||
C speedtest1\sJS:\sonly\sadd\s--memdb\sflag\sby\sdefault\sif\sno\s--vfs\sis\sprovided.
|
C Correct\sopfs-sahpool\sVFS\safter\sthe\spebkac\sinvolving\sthe\sprevious\sspeedtest1\sruns.\sMake\sthat\sVFS\sexplicitly\sopt-in\sto\savoid\scertain\sunfortunate\slocking\ssituations.
|
||||||
D 2023-07-15T16:30:46.383
|
D 2023-07-15T19:08:58.138
|
||||||
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
|
||||||
@ -502,8 +502,8 @@ F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b17386
|
|||||||
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 961bbc3ccc1fa4e91d6519a96e8811ad7ae60173bd969fee7775dacb6eee1da2
|
F ext/wasm/api/sqlite3-opfs-async-proxy.js 961bbc3ccc1fa4e91d6519a96e8811ad7ae60173bd969fee7775dacb6eee1da2
|
||||||
F ext/wasm/api/sqlite3-v-helper.js e5c202a9ecde9ef818536d3f5faf26c03a1a9f5192b1ddea8bdabf30d75ef487
|
F ext/wasm/api/sqlite3-v-helper.js e5c202a9ecde9ef818536d3f5faf26c03a1a9f5192b1ddea8bdabf30d75ef487
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js ad6ec4e87f47152a871a23bf90b64709094bf04e8ee76671fc6cedd1ce45086d
|
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js 83388ead4bfc489bee008298ab51948ccb75227795ce8d1634f2eec8e02548f1
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 891f3a18d9ac9b0422b32fd975319dfcd0af5a8ca392f0cce850524e51b49c87
|
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js a5c3195203e6085d7aa89fae4b84cf3f3eec4ff4f928c6d0e5d3ef8b14cbc1c0
|
||||||
F ext/wasm/api/sqlite3-wasm.c 12a096d8e58a0af0589142bae5a3c27a0c7e19846755a1a37d2c206352fbedda
|
F ext/wasm/api/sqlite3-wasm.c 12a096d8e58a0af0589142bae5a3c27a0c7e19846755a1a37d2c206352fbedda
|
||||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
|
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
|
||||||
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
|
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
|
||||||
@ -540,7 +540,7 @@ F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd84223150
|
|||||||
F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d
|
F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d
|
||||||
F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe
|
F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe
|
||||||
F ext/wasm/speedtest1-worker.html bbcf1e7fd79541040c1a7ca2ebf1cb7793ddaf9900d6bde1784148f11b807c34
|
F ext/wasm/speedtest1-worker.html bbcf1e7fd79541040c1a7ca2ebf1cb7793ddaf9900d6bde1784148f11b807c34
|
||||||
F ext/wasm/speedtest1-worker.js 13b57c4a41729678a1194014afec2bd5b94435dcfc8d1039dfa9a533ac819ee1
|
F ext/wasm/speedtest1-worker.js 4de92e4e6718b8bd1cdecb75af62739d1115fa66656a700b0b51822c848948f5
|
||||||
F ext/wasm/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da
|
F ext/wasm/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da
|
||||||
F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
|
F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
|
||||||
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
|
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
|
||||||
@ -2044,8 +2044,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 fff68e9f25a57045e9d636b02ffa073cf1b984b2587d4fce10f6e35c9988469c
|
P 676ffe6280c1ce787b04d0cdb4a0664229c6125c601af4b18d1bfa125aac3675
|
||||||
R 30945b34df9134e0f98668ba08cfc13f
|
R bca4913f68935c8abed9e461aac753fd
|
||||||
U stephan
|
U stephan
|
||||||
Z 32f9fd4e9e8f1a70cce170b39e2a4458
|
Z 2546a1c8fd9c0ca0c4fd392086704b47
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
676ffe6280c1ce787b04d0cdb4a0664229c6125c601af4b18d1bfa125aac3675
|
41bf1fe31f2f3d0daa2bac25dc57262a4b90f22fed6fa97e4e92467c32ae02dc
|
Reference in New Issue
Block a user