1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Internal refactoring in opfs-sahpool. Move OPFS tests to the end of tester1.c-cpp.js.

FossilOrigin-Name: 6bd5a7413dd830ca41b587a2826fb599a2196fb0186646a2333500f950b3cf4d
This commit is contained in:
stephan
2023-07-19 08:18:25 +00:00
parent aed5abcc0f
commit 780bc4c557
5 changed files with 249 additions and 228 deletions

View File

@ -89,7 +89,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const optionDefaults = Object.assign(Object.create(null),{
name: 'opfs-sahpool',
directory: undefined,
directory: undefined /* derived from .name */,
initialCapacity: 6,
clearOnInit: false,
verbosity: 2 /*3+ == everything, 2 == warnings+errors, 1 == errors only*/
@ -390,6 +390,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
return rc;
}
getFileForPtr(ptr){
return this.mapIdToFile.get(ptr);
}
setFileForPtr(ptr,file){
if(file) this.mapIdToFile.set(ptr, file);
else this.mapIdToFile.delete(ptr);
}
hasFilename(name){
return this.mapFilenameToSAH.has(name)
}
getSAHForPath(path){
return this.mapFilenameToSAH.get(path);
}
}/*class OpfsSAHPool*/;
@ -576,6 +591,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
the default directory. If no directory is explicitly provided
then a directory name is synthesized from the `name` option.
Peculiarities of this VFS:
- Paths given to it _must_ be absolute. Relative paths will not
be properly recognized. This is arguably a bug but correcting it
requires some hoop-jumping and memory allocation in routines
which should not be allocating.
The API for the utility object passed on by this function's
Promise, in alphabetical order...
@ -673,7 +695,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
throw new Error("Just testing rejection.");
}
if(initPromises[vfsName]){
console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]);
//console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]);
return initPromises[vfsName];
}
if(!globalThis.FileSystemHandle ||
@ -699,13 +721,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const opfsVfs = new capi.sqlite3_vfs()
.addOnDispose(()=>opfsIoMethods.dispose());
const promiseReject = (err)=>{
error("rejecting promise:",err);
opfsVfs.dispose();
initPromises[vfsName] = Promise.reject(err);
throw err;
};
/* We fetch the default VFS so that we can inherit some
methods from it. */
const pDVfs = capi.sqlite3_vfs_find(null);
@ -755,13 +770,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
},
xClose: function(pFile){
thePool.storeErr();
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
if(file) {
try{
log(`xClose ${file.path}`);
if(file.sq3File) file.sq3File.dispose();
file.sah.flush();
thePool.mapIdToFile.delete(pFile);
thePool.setFileForPtr(pFile,0);
if(file.flags & capi.SQLITE_OPEN_DELETEONCLOSE){
thePool.deletePath(file.path);
}
@ -780,7 +795,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
},
xFileSize: function(pFile,pSz64){
log(`xFileSize`);
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
const size = file.sah.getSize() - HEADER_OFFSET_DATA;
//log(`xFileSize ${file.path} ${size}`);
wasm.poke64(pSz64, BigInt(size));
@ -789,14 +804,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
xLock: function(pFile,lockType){
log(`xLock ${lockType}`);
thePool.storeErr();
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
file.lockType = lockType;
return 0;
},
xRead: function(pFile,pDest,n,offset64){
log(`xRead ${n}@${offset64}`);
thePool.storeErr();
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
log(`xRead ${file.path} ${n} ${offset64}`);
try {
const nRead = file.sah.read(
@ -819,7 +834,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
xSync: function(pFile,flags){
log(`xSync ${flags}`);
thePool.storeErr();
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
//log(`xSync ${file.path} ${flags}`);
try{
file.sah.flush();
@ -832,7 +847,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
xTruncate: function(pFile,sz64){
log(`xTruncate ${sz64}`);
thePool.storeErr();
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
//log(`xTruncate ${file.path} ${iSize}`);
try{
file.sah.truncate(HEADER_OFFSET_DATA + Number(sz64));
@ -844,13 +859,13 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
},
xUnlock: function(pFile,lockType){
log('xUnlock');
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
file.lockType = lockType;
return 0;
},
xWrite: function(pFile,pSrc,n,offset64){
thePool.storeErr();
const file = thePool.mapIdToFile.get(pFile);
const file = thePool.getFileForPtr(pFile);
log(`xWrite ${file.path} ${n} ${offset64}`);
try{
const nBytes = file.sah.write(
@ -870,13 +885,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
*/
const vfsMethods = {
xAccess: function(pVfs,zName,flags,pOut){
log(`xAccess ${wasm.cstrToJs(zName)}`);
//log(`xAccess ${wasm.cstrToJs(zName)}`);
thePool.storeErr();
try{
const name = this.getPath(zName);
wasm.poke32(pOut, thePool.mapFilenameToSAH.has(name) ? 1 : 0);
const name = thePool.getPath(zName);
wasm.poke32(pOut, thePool.hasFilename(name) ? 1 : 0);
}catch(e){
/*ignored*/;
/*ignored*/
wasm.poke32(pOut, 0);
}
return 0;
},
@ -931,7 +947,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
const path = (zName && wasm.peek8(zName))
? thePool.getPath(zName)
: getRandomName();
let sah = thePool.mapFilenameToSAH.get(path);
let sah = thePool.getSAHForPath(path);
if(!sah && (flags & capi.SQLITE_OPEN_CREATE)) {
// File not found so try to create it.
if(thePool.getFileCount() < thePool.getCapacity()) {
@ -949,7 +965,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
// Subsequent methods are only passed the file pointer, so
// map the relevant info we need to that pointer.
const file = {path, flags, sah};
thePool.mapIdToFile.set(pFile, file);
thePool.setFileForPtr(pFile, file);
wasm.poke32(pOutFlags, flags);
file.sq3File = new capi.sqlite3_file(pFile);
file.sq3File.$pMethods = opfsIoMethods.pointer;
@ -1020,6 +1036,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
log("VFS initialized.");
return poolUtil;
});
}).catch(promiseReject);
}).catch((err)=>{
error("rejecting promise:",err);
opfsVfs.dispose();
return initPromises[vfsName] = Promise.reject(err);
});
}/*installOpfsSAHPoolVfs()*/;
}/*sqlite3ApiBootstrap.initializers*/);

View File

@ -2634,199 +2634,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
}/*kvvfs sqlite3_js_vfs_create_file()*/)
;/* end kvvfs tests */
////////////////////////////////////////////////////////////////////////
T.g('OPFS: Origin-Private File System',
(sqlite3)=>(sqlite3.capi.sqlite3_vfs_find("opfs")
|| 'requires "opfs" VFS'))
.t({
name: 'OPFS db sanity checks',
test: async function(sqlite3){
const filename = this.opfsDbFile = 'sqlite3-tester1.db';
const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
T.assert(pVfs);
const unlink = this.opfsUnlink =
(fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)};
unlink();
let db = new sqlite3.oo1.OpfsDb(filename);
try {
db.exec([
'create table p(a);',
'insert into p(a) values(1),(2),(3)'
]);
T.assert(3 === db.selectValue('select count(*) from p'));
db.close();
db = new sqlite3.oo1.OpfsDb(filename);
db.exec('insert into p(a) values(4),(5),(6)');
T.assert(6 === db.selectValue('select count(*) from p'));
this.opfsDbExport = capi.sqlite3_js_db_export(db);
T.assert(this.opfsDbExport instanceof Uint8Array)
.assert(this.opfsDbExport.byteLength>0
&& 0===this.opfsDbExport.byteLength % 512);
}finally{
db.close();
unlink();
}
}
}/*OPFS db sanity checks*/)
.t({
name: 'OPFS export/import',
test: async function(sqlite3){
let db;
try {
const exp = this.opfsDbExport;
delete this.opfsDbExport;
capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp);
const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
T.assert(6 === db.selectValue('select count(*) from p'));
}finally{
if(db) db.close();
}
}
}/*OPFS export/import*/)
.t({
name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()',
test: async function(sqlite3){
const filename = this.opfsDbFile;
const pVfs = this.opfsVfs;
const unlink = this.opfsUnlink;
T.assert(filename && pVfs && !!unlink);
delete this.opfsDbFile;
delete this.opfsVfs;
delete this.opfsUnlink;
unlink();
// Sanity-test sqlite3_js_vfs_create_file()...
/**************************************************************
ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended
for client-side use. It is only for this project's own
internal use. Its APIs are subject to change or removal at
any time.
***************************************************************/
const opfs = sqlite3.opfs;
const fSize = 1379;
let sh;
try{
T.assert(!(await opfs.entryExists(filename)));
capi.sqlite3_js_vfs_create_file(
pVfs, filename, null, fSize
);
T.assert(await opfs.entryExists(filename));
let fh = await opfs.rootDirectory.getFileHandle(filename);
sh = await fh.createSyncAccessHandle();
T.assert(fSize === await sh.getSize());
await sh.close();
sh = undefined;
unlink();
T.assert(!(await opfs.entryExists(filename)));
const ba = new Uint8Array([1,2,3,4,5]);
capi.sqlite3_js_vfs_create_file(
"opfs", filename, ba
);
T.assert(await opfs.entryExists(filename));
fh = await opfs.rootDirectory.getFileHandle(filename);
sh = await fh.createSyncAccessHandle();
T.assert(ba.byteLength === await sh.getSize());
await sh.close();
sh = undefined;
unlink();
T.mustThrowMatching(()=>{
capi.sqlite3_js_vfs_create_file(
"no-such-vfs", filename, ba
);
}, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs");
}finally{
if(sh) await sh.close();
unlink();
}
// Some sanity checks of the opfs utility functions...
const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
const aDir = testDir+'/test/dir';
T.assert(await opfs.mkdir(aDir), "mkdir failed")
.assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists")
.assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)")
.assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed")
.assert(!(await opfs.unlink(testDir+'/test/dir')),
"delete 2b should have failed (dir already deleted)")
.assert((await opfs.unlink(testDir, true)), "delete 3 failed")
.assert(!(await opfs.entryExists(testDir)),
"entryExists(",testDir,") should have failed");
}
}/*OPFS util sanity checks*/)
;/* end OPFS tests */
////////////////////////////////////////////////////////////////////////
T.g('OPFS SyncAccessHandle Pool VFS',
(sqlite3)=>(hasOpfs() || "requires OPFS APIs"))
.t({
name: 'SAH sanity checks',
test: async function(sqlite3){
T.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) < 0)
const inst = sqlite3.installOpfsSAHPoolVfs,
catcher = (e)=>{
error("Cannot load SAH pool VFS.",
"This might not be a problem,",
"depending on the environment.");
return false;
};
let u1, u2;
const P1 = inst(sahPoolConfig).then(u=>u1 = u).catch(catcher),
P2 = inst(sahPoolConfig).then(u=>u2 = u).catch(catcher);
await Promise.all([P1, P2]);
if(!P1) return;
T.assert(u1 === u2)
.assert(sahPoolConfig.name === u1.vfsName)
.assert(sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
.assert(u1.getCapacity() >= sahPoolConfig.initialCapacity
/* If a test fails before we get to nuke the VFS, we
can have more than the initial capacity on the next
run. */)
.assert(u1.getCapacity() + 2 === (await u2.addCapacity(2)))
.assert(2 === (await u2.reduceCapacity(2)))
.assert(sqlite3.oo1.OpfsSAHPool.default instanceof Function)
.assert(sqlite3.oo1.OpfsSAHPool.default ===
sqlite3.oo1.OpfsSAHPool[sahPoolConfig.name])
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) >= 0);
T.assert(0 === u1.getFileCount());
const DbCtor = sqlite3.oo1.OpfsSAHPool.default;
const dbName = '/foo.db';
let db = new DbCtor(dbName);
T.assert(1 === u1.getFileCount());
db.exec([
'create table t(a);',
'insert into t(a) values(1),(2),(3)'
]);
T.assert(1 === u1.getFileCount());
T.assert(3 === db.selectValue('select count(*) from t'));
db.close();
T.assert(1 === u1.getFileCount());
db = new DbCtor(dbName);
T.assert(1 === u1.getFileCount());
db.close();
T.assert(1 === u1.getFileCount())
.assert(true === u1.unlink(dbName))
.assert(false === u1.unlink(dbName))
.assert(0 === u1.getFileCount());
T.assert(true === await u2.removeVfs())
.assert(false === await u1.removeVfs())
.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
let cErr, u3;
const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
conf2.$testThrowInInit = new Error("Testing throwing during init.");
conf2.name = sahPoolConfig.name+'-err';
const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
T.assert(P3 === conf2.$testThrowInInit)
.assert(cErr === P3)
.assert(undefined === u3)
.assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name));
}
}/*OPFS SAH Pool sanity checks*/)
////////////////////////////////////////////////////////////////////////
T.g('Hook APIs')
.t({
@ -3096,6 +2903,200 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
}
})/*session API sanity tests*/
;/*end of session API group*/;
////////////////////////////////////////////////////////////////////////
T.g('OPFS: Origin-Private File System',
(sqlite3)=>(sqlite3.capi.sqlite3_vfs_find("opfs")
|| 'requires "opfs" VFS'))
.t({
name: 'OPFS db sanity checks',
test: async function(sqlite3){
const filename = this.opfsDbFile = 'sqlite3-tester1.db';
const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
T.assert(pVfs);
const unlink = this.opfsUnlink =
(fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)};
unlink();
let db = new sqlite3.oo1.OpfsDb(filename);
try {
db.exec([
'create table p(a);',
'insert into p(a) values(1),(2),(3)'
]);
T.assert(3 === db.selectValue('select count(*) from p'));
db.close();
db = new sqlite3.oo1.OpfsDb(filename);
db.exec('insert into p(a) values(4),(5),(6)');
T.assert(6 === db.selectValue('select count(*) from p'));
this.opfsDbExport = capi.sqlite3_js_db_export(db);
T.assert(this.opfsDbExport instanceof Uint8Array)
.assert(this.opfsDbExport.byteLength>0
&& 0===this.opfsDbExport.byteLength % 512);
}finally{
db.close();
unlink();
}
}
}/*OPFS db sanity checks*/)
.t({
name: 'OPFS export/import',
test: async function(sqlite3){
let db;
try {
const exp = this.opfsDbExport;
delete this.opfsDbExport;
capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp);
const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
T.assert(6 === db.selectValue('select count(*) from p'));
}finally{
if(db) db.close();
}
}
}/*OPFS export/import*/)
.t({
name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()',
test: async function(sqlite3){
const filename = this.opfsDbFile;
const pVfs = this.opfsVfs;
const unlink = this.opfsUnlink;
T.assert(filename && pVfs && !!unlink);
delete this.opfsDbFile;
delete this.opfsVfs;
delete this.opfsUnlink;
unlink();
// Sanity-test sqlite3_js_vfs_create_file()...
/**************************************************************
ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended
for client-side use. It is only for this project's own
internal use. Its APIs are subject to change or removal at
any time.
***************************************************************/
const opfs = sqlite3.opfs;
const fSize = 1379;
let sh;
try{
T.assert(!(await opfs.entryExists(filename)));
capi.sqlite3_js_vfs_create_file(
pVfs, filename, null, fSize
);
T.assert(await opfs.entryExists(filename));
let fh = await opfs.rootDirectory.getFileHandle(filename);
sh = await fh.createSyncAccessHandle();
T.assert(fSize === await sh.getSize());
await sh.close();
sh = undefined;
unlink();
T.assert(!(await opfs.entryExists(filename)));
const ba = new Uint8Array([1,2,3,4,5]);
capi.sqlite3_js_vfs_create_file(
"opfs", filename, ba
);
T.assert(await opfs.entryExists(filename));
fh = await opfs.rootDirectory.getFileHandle(filename);
sh = await fh.createSyncAccessHandle();
T.assert(ba.byteLength === await sh.getSize());
await sh.close();
sh = undefined;
unlink();
T.mustThrowMatching(()=>{
capi.sqlite3_js_vfs_create_file(
"no-such-vfs", filename, ba
);
}, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs");
}finally{
if(sh) await sh.close();
unlink();
}
// Some sanity checks of the opfs utility functions...
const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
const aDir = testDir+'/test/dir';
T.assert(await opfs.mkdir(aDir), "mkdir failed")
.assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists")
.assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)")
.assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed")
.assert(!(await opfs.unlink(testDir+'/test/dir')),
"delete 2b should have failed (dir already deleted)")
.assert((await opfs.unlink(testDir, true)), "delete 3 failed")
.assert(!(await opfs.entryExists(testDir)),
"entryExists(",testDir,") should have failed");
}
}/*OPFS util sanity checks*/)
;/* end OPFS tests */
////////////////////////////////////////////////////////////////////////
T.g('OPFS SyncAccessHandle Pool VFS',
(sqlite3)=>(hasOpfs() || "requires OPFS APIs"))
.t({
name: 'SAH sanity checks',
test: async function(sqlite3){
T.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) < 0)
const inst = sqlite3.installOpfsSAHPoolVfs,
catcher = (e)=>{
error("Cannot load SAH pool VFS.",
"This might not be a problem,",
"depending on the environment.");
return false;
};
let u1, u2;
const P1 = inst(sahPoolConfig).then(u=>u1 = u).catch(catcher),
P2 = inst(sahPoolConfig).then(u=>u2 = u).catch(catcher);
await Promise.all([P1, P2]);
if(!P1) return;
T.assert(u1 === u2)
.assert(sahPoolConfig.name === u1.vfsName)
.assert(sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
.assert(u1.getCapacity() >= sahPoolConfig.initialCapacity
/* If a test fails before we get to nuke the VFS, we
can have more than the initial capacity on the next
run. */)
.assert(u1.getCapacity() + 2 === (await u2.addCapacity(2)))
.assert(2 === (await u2.reduceCapacity(2)))
.assert(sqlite3.oo1.OpfsSAHPool.default instanceof Function)
.assert(sqlite3.oo1.OpfsSAHPool.default ===
sqlite3.oo1.OpfsSAHPool[sahPoolConfig.name])
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) >= 0);
T.assert(0 === u1.getFileCount());
const DbCtor = sqlite3.oo1.OpfsSAHPool.default;
const dbName = '/foo.db';
let db = new DbCtor(dbName);
T.assert(1 === u1.getFileCount());
db.exec([
'create table t(a);',
'insert into t(a) values(1),(2),(3)'
]);
T.assert(1 === u1.getFileCount());
T.assert(3 === db.selectValue('select count(*) from t'));
db.close();
T.assert(1 === u1.getFileCount());
db = new DbCtor(dbName);
T.assert(1 === u1.getFileCount());
db.close();
T.assert(1 === u1.getFileCount())
.assert(true === u1.unlink(dbName))
.assert(false === u1.unlink(dbName))
.assert(0 === u1.getFileCount());
T.assert(true === await u2.removeVfs())
.assert(false === await u1.removeVfs())
.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
let cErr, u3;
const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
conf2.$testThrowInInit = new Error("Testing throwing during init.");
conf2.name = sahPoolConfig.name+'-err';
const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
T.assert(P3 === conf2.$testThrowInInit)
.assert(cErr === P3)
.assert(undefined === u3)
.assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name));
}
}/*OPFS SAH Pool sanity checks*/)
////////////////////////////////////////////////////////////////////////
T.g('Bug Reports')
.t({

View File

@ -1,5 +1,5 @@
C More\sopfs-sahpool\stests.
D 2023-07-18T19:47:19.982
C Internal\srefactoring\sin\sopfs-sahpool.\sMove\sOPFS\stests\sto\sthe\send\sof\stester1.c-cpp.js.
D 2023-07-19T08:18:25.901
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -501,8 +501,8 @@ F ext/wasm/api/sqlite3-api-prologue.js d747cbb379e13881c9edf39dce019cbbbae860c45
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
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-v-helper.js fc9ed95433d943a65905d16b7ed51515ddb6667d2a2c5a711c7ce33b29d3be31
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js a33b88beb55e0e19a8f9c3d37620e9aa58a0a32cacf7c398195d3d045d414815
F ext/wasm/api/sqlite3-v-helper.js e4b7b27a8259e40407b3c16e42dd5df05b80726c609594cc23b1565dc2ad9ca2
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js 9a8ba44b775b0e8faaffc8d877cfef0726713c2ca368e5776b59d9029f5ebf23
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4946af0d6fbd395aa39966562ca85900664605a5f0cc10fff50146dee527812c
F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
@ -549,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
F ext/wasm/tester1.c-pp.js f625ce01681956cfd895a834d8aeb68d59595200441628ac2e41adf48788d8c9
F ext/wasm/tester1.c-pp.js a72fc43950ce26c1ad7cee47aa225dd18efdb92743cf616b2e114b4cd1cdf2dd
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@ -2044,8 +2044,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 9c8a73aff0f291e0c18072372e0d8961d3a05910489598d0d342227d99871954
R 17462841136511130de69ca7a00ea9cc
P 60713fa9c4627ef17e0b8778eee37913d2b930c5a06414721a00af30e1395090
R b81da7c28422da4e0ac61aef8c2566f8
U stephan
Z c3c355ff206bb421832084a0cbc9cd73
Z 2d92190e2a732ef23d4b23ca479d2da6
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
60713fa9c4627ef17e0b8778eee37913d2b930c5a06414721a00af30e1395090
6bd5a7413dd830ca41b587a2826fb599a2196fb0186646a2333500f950b3cf4d