aboutsummaryrefslogtreecommitdiff
path: root/ext/wasm/sqlite3-opfs-async-proxy.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/wasm/sqlite3-opfs-async-proxy.js')
-rw-r--r--ext/wasm/sqlite3-opfs-async-proxy.js48
1 files changed, 34 insertions, 14 deletions
diff --git a/ext/wasm/sqlite3-opfs-async-proxy.js b/ext/wasm/sqlite3-opfs-async-proxy.js
index 025cd97a4..b19568d63 100644
--- a/ext/wasm/sqlite3-opfs-async-proxy.js
+++ b/ext/wasm/sqlite3-opfs-async-proxy.js
@@ -25,6 +25,13 @@
access to the sqlite3 JS/WASM bits, so any bits which it needs (most
notably SQLITE_xxx integer codes) have to be imported into it via an
initialization process.
+
+ Potential TODOs:
+
+ - When idle for "a long time", close the sync access handle in order
+ to release the lock, then re-open it on demand. Similarly, delay
+ fetching of the sync access handle until we need it. The intent
+ would be to help multi-tab access to a db avoid locking issues.
*/
'use strict';
const toss = function(...args){throw new Error(args.join(' '))};
@@ -132,6 +139,17 @@ const getDirForFilename = async function f(absFilename, createDirs = false){
return [dh, filename];
};
+/**
+ Returns the sync access handle associated with the given file
+ handle object (which must be a valid handle object), lazily opening
+ it if needed.
+*/
+const getSyncHandle = async (f)=>(
+ f.accessHandle || (
+ f.accessHandle =
+ await f.fileHandle.createSyncAccessHandle()
+ )
+);
/**
Stores the given value at state.sabOPView[state.opIds.rc] and then
@@ -294,7 +312,7 @@ const vfsAsyncImpls = {
let sz;
wTimeStart('xFileSize');
try{
- sz = await fh.accessHandle.getSize();
+ sz = await (await getSyncHandle(fh)).getSize();
state.s11n.serialize(Number(sz));
sz = 0;
}catch(e){
@@ -322,23 +340,24 @@ const vfsAsyncImpls = {
return;
}
const hFile = await hDir.getFileHandle(filenamePart, {create});
- const fobj = Object.create(null);
/**
wa-sqlite, at this point, grabs a SyncAccessHandle and
assigns it to the accessHandle prop of the file state
object, but only for certain cases and it's unclear why it
places that limitation on it.
*/
- fobj.accessHandle = await hFile.createSyncAccessHandle();
wTimeEnd();
+ const fobj = Object.assign(Object.create(null),{
+ filenameAbs: filename,
+ filenamePart: filenamePart,
+ dirHandle: hDir,
+ fileHandle: hFile,
+ sabView: state.sabFileBufView,
+ readOnly: create
+ ? false : (state.sq3Codes.SQLITE_OPEN_READONLY & flags),
+ deleteOnClose: deleteOnClose
+ });
__openFiles[fid] = fobj;
- fobj.filenameAbs = filename;
- fobj.filenamePart = filenamePart;
- fobj.dirHandle = hDir;
- fobj.fileHandle = hFile;
- fobj.sabView = state.sabFileBufView;
- fobj.readOnly = create ? false : (state.sq3Codes.SQLITE_OPEN_READONLY & flags);
- fobj.deleteOnClose = deleteOnClose;
storeAndNotify(opName, 0);
}catch(e){
wTimeEnd();
@@ -354,7 +373,7 @@ const vfsAsyncImpls = {
try{
const fh = __openFiles[fid];
wTimeStart('xRead');
- const nRead = fh.accessHandle.read(
+ const nRead = (await getSyncHandle(fh)).read(
fh.sabView.subarray(0, n),
{at: Number(offset)}
);
@@ -395,7 +414,7 @@ const vfsAsyncImpls = {
wTimeStart('xTruncate');
try{
affirmNotRO('xTruncate', fh);
- await fh.accessHandle.truncate(size);
+ await (await getSyncHandle(fh)).truncate(size);
}catch(e){
error("xTruncate():",e,fh);
state.s11n.storeException(2,e);
@@ -413,8 +432,9 @@ const vfsAsyncImpls = {
const fh = __openFiles[fid];
affirmNotRO('xWrite', fh);
rc = (
- n === fh.accessHandle.write(fh.sabView.subarray(0, n),
- {at: Number(offset)})
+ n === (await getSyncHandle(fh))
+ .write(fh.sabView.subarray(0, n),
+ {at: Number(offset)})
) ? 0 : state.sq3Codes.SQLITE_IOERR_WRITE;
}catch(e){
error("xWrite():",e,fh);