Internal restructuring of the OPFS sqlite3_vfs in order to facilitate certain experimentation and improve error reporting/hints if it cannot be activated. Deprecate the name sqlite3.opfs.OpfsDb, preferring sqlite3.oo1.OpfsDb for consistency with JsStorageDb and any future DB subclasses.
FossilOrigin-Name: 0c5c51f4fb04a4b90c50ec9704cfea9a3fb7d7d0ee55c1b0d4476129188217a6
This commit is contained in:
parent
e6b0154138
commit
04184761de
@ -76,15 +76,25 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
`opfs` property, containing several OPFS-specific utilities.
|
||||
*/
|
||||
const installOpfsVfs = function callee(options){
|
||||
if(!self.SharedArrayBuffer ||
|
||||
!self.Atomics ||
|
||||
!self.FileSystemHandle ||
|
||||
!self.FileSystemDirectoryHandle ||
|
||||
!self.FileSystemFileHandle ||
|
||||
!self.FileSystemFileHandle.prototype.createSyncAccessHandle ||
|
||||
!navigator.storage.getDirectory){
|
||||
if(!self.SharedArrayBuffer
|
||||
|| !self.Atomics){
|
||||
return Promise.reject(
|
||||
new Error("This environment does not have OPFS support.")
|
||||
new Error("Cannot install OPFS: Missing SharedArrayBuffer and/or Atomics. "+
|
||||
"The server must emit the COOP/COEP response headers to enable those. "+
|
||||
"See https://sqlite.org/wasm/doc/trunk/persistence.md#coop-coep")
|
||||
);
|
||||
}else if(self.window===self && self.document){
|
||||
return Promise.reject(
|
||||
new Error("The OPFS sqlite3_vfs cannot run in the main thread "+
|
||||
"because it requires Atomics.wait().")
|
||||
);
|
||||
}else if(!self.FileSystemHandle ||
|
||||
!self.FileSystemDirectoryHandle ||
|
||||
!self.FileSystemFileHandle ||
|
||||
!self.FileSystemFileHandle.prototype.createSyncAccessHandle ||
|
||||
!navigator.storage.getDirectory){
|
||||
return Promise.reject(
|
||||
new Error("Missing required OPFS APIs.")
|
||||
);
|
||||
}
|
||||
if(!options || 'object'!==typeof options){
|
||||
@ -134,6 +144,18 @@ const installOpfsVfs = function callee(options){
|
||||
OPFS-specific sqlite3_vfs evolves.
|
||||
*/
|
||||
const opfsUtil = Object.create(null);
|
||||
|
||||
/**
|
||||
Returns true if _this_ thread has access to the OPFS APIs.
|
||||
*/
|
||||
const thisThreadHasOPFS = ()=>{
|
||||
return self.FileSystemHandle &&
|
||||
self.FileSystemDirectoryHandle &&
|
||||
self.FileSystemFileHandle &&
|
||||
self.FileSystemFileHandle.prototype.createSyncAccessHandle &&
|
||||
navigator.storage.getDirectory;
|
||||
};
|
||||
|
||||
/**
|
||||
Not part of the public API. Solely for internal/development
|
||||
use.
|
||||
@ -1179,12 +1201,16 @@ const installOpfsVfs = function callee(options){
|
||||
//consideration.
|
||||
|
||||
if(sqlite3.oo1){
|
||||
opfsUtil.OpfsDb = function(...args){
|
||||
const OpfsDb = function(...args){
|
||||
const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args);
|
||||
opt.vfs = opfsVfs.$zName;
|
||||
sqlite3.oo1.DB.dbCtorHelper.call(this, opt);
|
||||
};
|
||||
opfsUtil.OpfsDb.prototype = Object.create(sqlite3.oo1.DB.prototype);
|
||||
sqlite3.oo1.OpfsDb =
|
||||
opfsUtil.OpfsDb /* sqlite3.opfs.OpfsDb => deprecated name -
|
||||
will be phased out Real Soon */ =
|
||||
OpfsDb;
|
||||
OpfsDb.prototype = Object.create(sqlite3.oo1.DB.prototype);
|
||||
sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenSql(
|
||||
opfsVfs.pointer,
|
||||
[
|
||||
@ -1206,13 +1232,6 @@ const installOpfsVfs = function callee(options){
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
Potential TODOs:
|
||||
|
||||
- Expose one or both of the Worker objects via opfsUtil and
|
||||
publish an interface for proxying the higher-level OPFS
|
||||
features like getting a directory listing.
|
||||
*/
|
||||
const sanityCheck = function(){
|
||||
const scope = wasm.scopedAllocPush();
|
||||
const sq3File = new sqlite3_file();
|
||||
@ -1282,6 +1301,11 @@ const installOpfsVfs = function callee(options){
|
||||
W.onmessage = function({data}){
|
||||
//log("Worker.onmessage:",data);
|
||||
switch(data.type){
|
||||
case 'opfs-unavailable':
|
||||
/* Async proxy has determined that OPFS is unavailable. There's
|
||||
nothing more for us to do here. */
|
||||
promiseReject(new Error(data.payload.join(' ')));
|
||||
break;
|
||||
case 'opfs-async-loaded':
|
||||
/*Arrives as soon as the asyc proxy finishes loading.
|
||||
Pass our config and shared state on to the async worker.*/
|
||||
@ -1308,14 +1332,18 @@ const installOpfsVfs = function callee(options){
|
||||
warn("Running sanity checks because of opfs-sanity-check URL arg...");
|
||||
sanityCheck();
|
||||
}
|
||||
navigator.storage.getDirectory().then((d)=>{
|
||||
W.onerror = W._originalOnError;
|
||||
delete W._originalOnError;
|
||||
sqlite3.opfs = opfsUtil;
|
||||
opfsUtil.rootDirectory = d;
|
||||
log("End of OPFS sqlite3_vfs setup.", opfsVfs);
|
||||
if(thisThreadHasOPFS()){
|
||||
navigator.storage.getDirectory().then((d)=>{
|
||||
W.onerror = W._originalOnError;
|
||||
delete W._originalOnError;
|
||||
sqlite3.opfs = opfsUtil;
|
||||
opfsUtil.rootDirectory = d;
|
||||
log("End of OPFS sqlite3_vfs setup.", opfsVfs);
|
||||
promiseResolve(sqlite3);
|
||||
});
|
||||
}else{
|
||||
promiseResolve(sqlite3);
|
||||
});
|
||||
}
|
||||
}catch(e){
|
||||
error(e);
|
||||
promiseReject(e);
|
||||
@ -1334,9 +1362,6 @@ const installOpfsVfs = function callee(options){
|
||||
installOpfsVfs.defaultProxyUri =
|
||||
"sqlite3-opfs-async-proxy.js";
|
||||
self.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
|
||||
if(sqlite3.scriptInfo && !sqlite3.scriptInfo.isWorker){
|
||||
return;
|
||||
}
|
||||
try{
|
||||
let proxyJs = installOpfsVfs.defaultProxyUri;
|
||||
if(sqlite3.scriptInfo.sqlite3Dir){
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1784,13 +1784,12 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
.t({
|
||||
name: 'OPFS sanity checks',
|
||||
test: async function(sqlite3){
|
||||
const opfs = sqlite3.opfs;
|
||||
const filename = 'sqlite3-tester1.db';
|
||||
const pVfs = capi.sqlite3_vfs_find('opfs');
|
||||
T.assert(pVfs);
|
||||
const unlink = (fn=filename)=>wasm.sqlite3_wasm_vfs_unlink(pVfs,fn);
|
||||
unlink();
|
||||
let db = new opfs.OpfsDb(filename);
|
||||
let db = new sqlite3.oo1.OpfsDb(filename);
|
||||
try {
|
||||
db.exec([
|
||||
'create table p(a);',
|
||||
@ -1798,7 +1797,7 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
]);
|
||||
T.assert(3 === db.selectValue('select count(*) from p'));
|
||||
db.close();
|
||||
db = new opfs.OpfsDb(filename);
|
||||
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'));
|
||||
}finally{
|
||||
@ -1806,8 +1805,9 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
unlink();
|
||||
}
|
||||
|
||||
if(1){
|
||||
if(sqlite3.opfs){
|
||||
// Sanity-test sqlite3_wasm_vfs_create_file()...
|
||||
const opfs = sqlite3.opfs;
|
||||
const fSize = 1379;
|
||||
let sh;
|
||||
try{
|
||||
@ -1824,20 +1824,20 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
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");
|
||||
// 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 sanity checks*/)
|
||||
;/* end OPFS tests */
|
||||
|
@ -33,9 +33,10 @@
|
||||
with <code>unlock-asap=0-1</code>.
|
||||
</p>
|
||||
<p>Achtung: if it does not start to do anything within a couple of
|
||||
seconds, check the dev console: Chrome often fails with "cannot allocate
|
||||
WasmMemory" at startup. Closing and re-opening the tab usually resolves
|
||||
it.
|
||||
seconds, check the dev console: Chrome sometimes fails to load
|
||||
the wasm module due to "cannot allocate WasmMemory." Closing and
|
||||
re-opening the tab usually resolves it, but sometimes restarting
|
||||
the browser is required.
|
||||
</p>
|
||||
<div class='input-wrapper'>
|
||||
<input type='checkbox' id='cb-log-reverse'>
|
||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Add\san\sexplicit\swarning\sabout\sthe\scurrent\sAPI-instability\sof\sthe\ssqlite3.opfs\snamespace,\swhich\smay\sneed\sto\sbe\seliminated\sbased\son\sre-thinking\sof\show\sthe\sOPFS\ssqlite3_vfs\sis\sregistered.\sComment\schanges\sonly\s-\sno\scode.
|
||||
D 2022-11-29T02:23:12.943
|
||||
C Internal\srestructuring\sof\sthe\sOPFS\ssqlite3_vfs\sin\sorder\sto\sfacilitate\scertain\sexperimentation\sand\simprove\serror\sreporting/hints\sif\sit\scannot\sbe\sactivated.\sDeprecate\sthe\sname\ssqlite3.opfs.OpfsDb,\spreferring\ssqlite3.oo1.OpfsDb\sfor\sconsistency\swith\sJsStorageDb\sand\sany\sfuture\sDB\ssubclasses.
|
||||
D 2022-11-29T05:25:08.036
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -505,11 +505,11 @@ F ext/wasm/api/pre-js.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js ecdc69dbfccfe26146f04799fcfd4a6f5790d46e7e3b9b6e9b0491f92ed8ae34
|
||||
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 3cdae7e98c500f89f9468a260e2a0e1b528c845a107bf72d368e5222769214d3
|
||||
F ext/wasm/api/sqlite3-api-opfs.js 583650ffdc1452496df6b9459d018fa2aede221ae6ea0cbbbe83bd2e1bdba966
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 7fce4c6a138ec3d7c285b7c125cee809e6b668d2cb0d2328a1b790b7037765bd
|
||||
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 798383f6b46fd5dac122d6e35962d25b10401ddb825b5c66df1d21e6b1d8aacc
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js b5dd7eda8e74e07453457925a0dd793d7785da720954e0e37e847c5c6e4d9526
|
||||
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,8 +554,8 @@ 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 3b91f192c159088004fba6fe3441edea58421a8b88bccf3dd20978a077648d19
|
||||
F ext/wasm/tests/opfs/concurrency/index.html e8fec75ea6eddc600c8a382da7ea2579feece2263a2fb4417f2cf3e9d451744c
|
||||
F ext/wasm/tester1.c-pp.js a4b6a165aafcd3b86118efaec6b47c70fbb6c64b5ab86d21ca8c250d42617dfa
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 2b1cda51d6c786102875a28eba22f0da3eecb732a5e677b0d1ecdb53546d1a62
|
||||
F ext/wasm/tests/opfs/concurrency/test.js bfc3d7e27b207f0827f12568986b8d516a744529550b449314f5c21c9e9faf4a
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0eff027cbd3a495acb2ac94f57ca9e4d21125ab9fda07d45f3701b0efe82d450
|
||||
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
|
||||
@ -2064,8 +2064,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 46cdd3637d6a206ad2bcf8653cc6f2c7a886a16cc7685c45967938609941a755
|
||||
R 3870d04bfd54da096e986662fe29b1c8
|
||||
P 0cb2fd14179397051a25d066256a553fc198656d5668c7010c016f2b8f495bf4
|
||||
R 115b7898d7b2ce79a9261f36a9b959d1
|
||||
U stephan
|
||||
Z ad4a8c5f45a34a10f588c0c6dc455846
|
||||
Z f4ff31d5e2499971cf67cb62dbdd0ac3
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
0cb2fd14179397051a25d066256a553fc198656d5668c7010c016f2b8f495bf4
|
||||
0c5c51f4fb04a4b90c50ec9704cfea9a3fb7d7d0ee55c1b0d4476129188217a6
|
Loading…
x
Reference in New Issue
Block a user