mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Minor cleanups and doc improvements in the OPFS sqlite3_vfs proxy.
FossilOrigin-Name: 48645f7bcacf81c4149f26d20ee1752fbe93a02f96b85bd7e28bfa49322137e5
This commit is contained in:
@ -1,6 +1,9 @@
|
||||
/* extern-post-js.js must be appended to the resulting sqlite3.js
|
||||
file. It gets its name from being used as the value for
|
||||
the --extern-post-js=... Emscripten flag. */
|
||||
file. It gets its name from being used as the value for the
|
||||
--extern-post-js=... Emscripten flag. Note that this code, unlike
|
||||
most of the associated JS code, runs outside of the
|
||||
Emscripten-generated module init scope, in the current
|
||||
global scope. */
|
||||
(function(){
|
||||
/**
|
||||
In order to hide the sqlite3InitModule()'s resulting Emscripten
|
||||
|
@ -15,14 +15,17 @@
|
||||
asynchronous Origin-Private FileSystem (OPFS) APIs using a second
|
||||
Worker, implemented in sqlite3-opfs-async-proxy.js. This file is
|
||||
intended to be appended to the main sqlite3 JS deliverable somewhere
|
||||
after sqlite3-api-glue.js and before sqlite3-api-cleanup.js.
|
||||
after sqlite3-api-oo1.js and before sqlite3-api-cleanup.js.
|
||||
*/
|
||||
'use strict';
|
||||
self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
/**
|
||||
installOpfsVfs() returns a Promise which, on success, installs
|
||||
an sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
|
||||
which accept a VFS. It uses the Origin-Private FileSystem API for
|
||||
installOpfsVfs() returns a Promise which, on success, installs an
|
||||
sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
|
||||
which accept a VFS. It is intended to be called via
|
||||
sqlite3ApiBootstrap.initializersAsync or an equivalent mechanism.
|
||||
|
||||
The installed VFS uses the Origin-Private FileSystem API for
|
||||
all file storage. On error it is rejected with an exception
|
||||
explaining the problem. Reasons for rejection include, but are
|
||||
not limited to:
|
||||
@ -48,12 +51,12 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
proxying OPFS's synchronous API via the synchronous interface
|
||||
required by the sqlite3_vfs API.
|
||||
|
||||
- This function may only be called a single time and it must be
|
||||
called from the client, as opposed to the library initialization,
|
||||
in case the client requires a custom path for this API's
|
||||
"counterpart": this function's argument is the relative URI to
|
||||
this module's "asynchronous half". When called, this function removes
|
||||
itself from the sqlite3 object.
|
||||
- This function may only be called a single time. When called, this
|
||||
function removes itself from the sqlite3 object.
|
||||
|
||||
All arguments to this function are for internal/development purposes
|
||||
only. They do not constitute a public API and may change at any
|
||||
time.
|
||||
|
||||
The argument may optionally be a plain object with the following
|
||||
configuration options:
|
||||
@ -72,7 +75,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
object and that object gets a new object installed in its
|
||||
`opfs` property, containing several OPFS-specific utilities.
|
||||
*/
|
||||
const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
const installOpfsVfs = function callee(options){
|
||||
if(!self.SharedArrayBuffer ||
|
||||
!self.Atomics ||
|
||||
!self.FileSystemHandle ||
|
||||
@ -84,9 +87,9 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
new Error("This environment does not have OPFS support.")
|
||||
);
|
||||
}
|
||||
const options = (asyncProxyUri && 'object'===asyncProxyUri) ? asyncProxyUri : {
|
||||
proxyUri: asyncProxyUri
|
||||
};
|
||||
if(!options || 'object'!==typeof options){
|
||||
options = Object.create(null);
|
||||
}
|
||||
const urlParams = new URL(self.location.href).searchParams;
|
||||
if(undefined===options.verbose){
|
||||
options.verbose = urlParams.has('opfs-verbose') ? 3 : 2;
|
||||
@ -113,7 +116,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
const log = (...args)=>logImpl(2, ...args);
|
||||
const warn = (...args)=>logImpl(1, ...args);
|
||||
const error = (...args)=>logImpl(0, ...args);
|
||||
//warn("The OPFS VFS feature is very much experimental and under construction.");
|
||||
const toss = function(...args){throw new Error(args.join(' '))};
|
||||
const capi = sqlite3.capi;
|
||||
const wasm = capi.wasm;
|
||||
@ -158,9 +160,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
s.count = s.time = 0;
|
||||
s = metrics.s11n.deserialize = Object.create(null);
|
||||
s.count = s.time = 0;
|
||||
//[ // timed routines which are not in state.opIds
|
||||
// 'xFileControl'
|
||||
//].forEach((k)=>r(metrics[k] = Object.create(null)));
|
||||
}
|
||||
}/*metrics*/;
|
||||
const promiseReject = function(err){
|
||||
@ -223,17 +222,21 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
cases. We should probably have one SAB here with a single slot
|
||||
for locking a per-file initialization step and then allocate a
|
||||
separate SAB like the above one for each file. That will
|
||||
require a bit of acrobatics but should be feasible.
|
||||
require a bit of acrobatics but should be feasible. The most
|
||||
problematic part is that xOpen() would have to use
|
||||
postMessage() to communicate its SharedArrayBuffer, and mixing
|
||||
that approach with Atomics.wait/notify() gets a bit messy.
|
||||
*/
|
||||
const state = Object.create(null);
|
||||
state.verbose = options.verbose;
|
||||
state.littleEndian = (()=>{
|
||||
const buffer = new ArrayBuffer(2);
|
||||
new DataView(buffer).setInt16(0, 256, true /* littleEndian */);
|
||||
new DataView(buffer).setInt16(0, 256, true /* ==>littleEndian */);
|
||||
// Int16Array uses the platform's endianness.
|
||||
return new Int16Array(buffer)[0] === 256;
|
||||
})();
|
||||
/** Whether the async counterpart should log exceptions to
|
||||
/**
|
||||
Whether the async counterpart should log exceptions to
|
||||
the serialization channel. That produces a great deal of
|
||||
noise for seemingly innocuous things like xAccess() checks
|
||||
for missing files, so this option may have one of 3 values:
|
||||
@ -246,9 +249,9 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
2 = log all exceptions.
|
||||
*/
|
||||
state.asyncS11nExceptions = 1;
|
||||
/* Size of file I/O buffer block. 64k = max sqlite3 page size. */
|
||||
state.fileBufferSize =
|
||||
1024 * 64;
|
||||
/* Size of file I/O buffer block. 64k = max sqlite3 page size, and
|
||||
xRead/xWrite() will never deal in blocks larger than that. */
|
||||
state.fileBufferSize = 1024 * 64;
|
||||
state.sabS11nOffset = state.fileBufferSize;
|
||||
/**
|
||||
The size of the block in our SAB for serializing arguments and
|
||||
@ -258,7 +261,8 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
*/
|
||||
state.sabS11nSize = opfsVfs.$mxPathname * 2;
|
||||
/**
|
||||
The SAB used for all data I/O (files and arg/result s11n).
|
||||
The SAB used for all data I/O between the synchronous and
|
||||
async halves (file i/o and arg/result s11n).
|
||||
*/
|
||||
state.sabIO = new SharedArrayBuffer(
|
||||
state.fileBufferSize/* file i/o block */
|
||||
@ -297,7 +301,13 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
state.opIds.mkdir = i++;
|
||||
state.opIds['opfs-async-metrics'] = i++;
|
||||
state.opIds['opfs-async-shutdown'] = i++;
|
||||
state.sabOP = new SharedArrayBuffer(i * 4/*sizeof int32*/);
|
||||
/* The retry slot is used by the async part for wait-and-retry
|
||||
semantics. Though we could hypothetically use the xSleep slot
|
||||
for that, doing so might lead to undesired side effects. */
|
||||
state.opIds.retry = i++;
|
||||
state.sabOP = new SharedArrayBuffer(
|
||||
i * 4/* ==sizeof int32, noting that Atomics.wait() and friends
|
||||
can only function on Int32Array views of an SAB. */);
|
||||
opfsUtil.metrics.reset();
|
||||
}
|
||||
/**
|
||||
@ -338,9 +348,12 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
state.s11n.serialize(...args);
|
||||
Atomics.store(state.sabOPView, state.opIds.rc, -1);
|
||||
Atomics.store(state.sabOPView, state.opIds.whichOp, opNdx);
|
||||
Atomics.notify(state.sabOPView, state.opIds.whichOp) /* async thread will take over here */;
|
||||
Atomics.notify(state.sabOPView, state.opIds.whichOp)
|
||||
/* async thread will take over here */;
|
||||
const t = performance.now();
|
||||
Atomics.wait(state.sabOPView, state.opIds.rc, -1);
|
||||
Atomics.wait(state.sabOPView, state.opIds.rc, -1)
|
||||
/* When this wait() call returns, the async half will have
|
||||
completed the operation and reported its results. */;
|
||||
const rc = Atomics.load(state.sabOPView, state.opIds.rc);
|
||||
metrics[op].wait += performance.now() - t;
|
||||
if(rc && state.asyncS11nExceptions){
|
||||
@ -352,17 +365,22 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
|
||||
const initS11n = ()=>{
|
||||
/**
|
||||
ACHTUNG: this code is 100% duplicated in the other half of this
|
||||
proxy! The documentation is maintained in the "synchronous half".
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
ACHTUNG: this code is 100% duplicated in the other half of
|
||||
this proxy! The documentation is maintained in the
|
||||
"synchronous half".
|
||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
This proxy de/serializes cross-thread function arguments and
|
||||
output-pointer values via the state.sabIO SharedArrayBuffer,
|
||||
using the region defined by (state.sabS11nOffset,
|
||||
state.sabS11nOffset]. Only one dataset is recorded at a time.
|
||||
|
||||
This is not a general-purpose format. It only supports the range
|
||||
of operations, and data sizes, needed by the sqlite3_vfs and
|
||||
sqlite3_io_methods operations.
|
||||
This is not a general-purpose format. It only supports the
|
||||
range of operations, and data sizes, needed by the
|
||||
sqlite3_vfs and sqlite3_io_methods operations. Serialized
|
||||
data are transient and this serialization algorithm may
|
||||
change at any time.
|
||||
|
||||
The data format can be succinctly summarized as:
|
||||
|
||||
@ -386,7 +404,8 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
using their TextEncoder/TextDecoder representations. It would
|
||||
arguably make more sense to store them as Int16Arrays of
|
||||
their JS character values, but how best/fastest to get that
|
||||
in and out of string form us an open point.
|
||||
in and out of string form is an open point. Initial
|
||||
experimentation with that approach did not gain us any speed.
|
||||
|
||||
Historical note: this impl was initially about 1% this size by
|
||||
using using JSON.stringify/parse(), but using fit-to-purpose
|
||||
@ -583,9 +602,11 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
toss("Member",name," is not a function pointer. Signature =",sigN);
|
||||
}
|
||||
const memKey = tgt.memberKey(name);
|
||||
//log("installMethod",tgt, name, sigN);
|
||||
const fProxy = 0
|
||||
// We can remove this proxy middle-man once the VFS is working
|
||||
/** 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));
|
||||
@ -606,7 +627,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
const mTimeStart = (op)=>{
|
||||
opTimer.start = performance.now();
|
||||
opTimer.op = op;
|
||||
//metrics[op] || toss("Maintenance required: missing metrics for",op);
|
||||
++metrics[op].count;
|
||||
};
|
||||
const mTimeEnd = ()=>(
|
||||
@ -619,8 +639,15 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
*/
|
||||
const ioSyncWrappers = {
|
||||
xCheckReservedLock: function(pFile,pOut){
|
||||
// Exclusive lock is automatically acquired when opened
|
||||
//warn("xCheckReservedLock(",arguments,") is a no-op");
|
||||
/**
|
||||
As of late 2022, only a single lock can be held on an OPFS
|
||||
file. We have no way of checking whether any _other_ db
|
||||
connection has a lock except by trying to obtain and (on
|
||||
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.
|
||||
*/
|
||||
const f = __openFiles[pFile];
|
||||
wasm.setMemValue(pOut, f.lockMode ? 1 : 0, 'i32');
|
||||
return 0;
|
||||
@ -673,14 +700,17 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
return rc;
|
||||
},
|
||||
xRead: function(pFile,pDest,n,offset64){
|
||||
/* int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst) */
|
||||
mTimeStart('xRead');
|
||||
const f = __openFiles[pFile];
|
||||
let rc;
|
||||
try {
|
||||
rc = opRun('xRead',pFile, n, Number(offset64));
|
||||
if(0===rc || capi.SQLITE_IOERR_SHORT_READ===rc){
|
||||
// set() seems to be the fastest way to copy this...
|
||||
/**
|
||||
Results get written to the SharedArrayBuffer f.sabView.
|
||||
Because the heap is _not_ a SharedArrayBuffer, we have
|
||||
to copy the results. TypedArray.set() seems to be the
|
||||
fastest way to copy this. */
|
||||
wasm.heap8u().set(f.sabView.subarray(0, n), pDest);
|
||||
}
|
||||
}catch(e){
|
||||
@ -713,7 +743,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
return rc;
|
||||
},
|
||||
xWrite: function(pFile,pSrc,n,offset64){
|
||||
/* int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst) */
|
||||
mTimeStart('xWrite');
|
||||
const f = __openFiles[pFile];
|
||||
let rc;
|
||||
@ -779,28 +808,6 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
//xSleep is optionally defined below
|
||||
xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
|
||||
mTimeStart('xOpen');
|
||||
if(!f._){
|
||||
f._ = {
|
||||
fileTypes: {
|
||||
SQLITE_OPEN_MAIN_DB: 'mainDb',
|
||||
SQLITE_OPEN_MAIN_JOURNAL: 'mainJournal',
|
||||
SQLITE_OPEN_TEMP_DB: 'tempDb',
|
||||
SQLITE_OPEN_TEMP_JOURNAL: 'tempJournal',
|
||||
SQLITE_OPEN_TRANSIENT_DB: 'transientDb',
|
||||
SQLITE_OPEN_SUBJOURNAL: 'subjournal',
|
||||
SQLITE_OPEN_SUPER_JOURNAL: 'superJournal',
|
||||
SQLITE_OPEN_WAL: 'wal'
|
||||
},
|
||||
getFileType: function(filename,oflags){
|
||||
const ft = f._.fileTypes;
|
||||
for(let k of Object.keys(ft)){
|
||||
if(oflags & capi[k]) return ft[k];
|
||||
}
|
||||
warn("Cannot determine fileType based on xOpen() flags for file",filename);
|
||||
return '???';
|
||||
}
|
||||
};
|
||||
}
|
||||
if(0===zName){
|
||||
zName = randomFilename();
|
||||
}else if('number'===typeof zName){
|
||||
@ -1084,16 +1091,13 @@ const installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri){
|
||||
promiseReject(e);
|
||||
error("Unexpected message from the async worker:",data);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
}/*switch(data.type)*/
|
||||
}/*W.onmessage()*/;
|
||||
})/*thePromise*/;
|
||||
return thePromise;
|
||||
}/*installOpfsVfs()*/;
|
||||
installOpfsVfs.defaultProxyUri =
|
||||
//self.location.pathname.replace(/[^/]*$/, "sqlite3-opfs-async-proxy.js");
|
||||
"sqlite3-opfs-async-proxy.js";
|
||||
//console.warn("sqlite3.installOpfsVfs.defaultProxyUri =",sqlite3.installOpfsVfs.defaultProxyUri);
|
||||
self.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
|
||||
if(sqlite3.scriptInfo && !sqlite3.scriptInfo.isWorker){
|
||||
return;
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
***********************************************************************
|
||||
|
||||
An Worker which manages asynchronous OPFS handles on behalf of a
|
||||
A Worker which manages asynchronous OPFS handles on behalf of a
|
||||
synchronous API which controls it via a combination of Worker
|
||||
messages, SharedArrayBuffer, and Atomics. It is the asynchronous
|
||||
counterpart of the API defined in sqlite3-api-opfs.js.
|
||||
@ -25,8 +25,12 @@
|
||||
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.
|
||||
|
||||
This file represents an implementation detail of a larger piece of
|
||||
code, and not a public interface. Its details may change at any time
|
||||
and are not intended to be used by any client-level code.
|
||||
*/
|
||||
'use strict';
|
||||
"use strict";
|
||||
const toss = function(...args){throw new Error(args.join(' '))};
|
||||
if(self.window === self){
|
||||
toss("This code cannot run from the main thread.",
|
||||
@ -133,8 +137,8 @@ const getDirForFilename = async function f(absFilename, createDirs = false){
|
||||
|
||||
/**
|
||||
Returns the sync access handle associated with the given file
|
||||
handle object (which must be a valid handle object), lazily opening
|
||||
it if needed.
|
||||
handle object (which must be a valid handle object, as created by
|
||||
xOpen()), lazily opening it if needed.
|
||||
|
||||
In order to help alleviate cross-tab contention for a dabase,
|
||||
if an exception is thrown while acquiring the handle, this routine
|
||||
@ -150,7 +154,7 @@ const getSyncHandle = async (fh)=>{
|
||||
let i = 1, ms = 300;
|
||||
for(; true; ms *= ++i){
|
||||
try {
|
||||
//if(1===i) toss("Just testing.");
|
||||
//if(i<3) toss("Just testing.");
|
||||
//TODO? A config option which tells it to throw here
|
||||
//randomly every now and then, for testing purposes.
|
||||
fh.syncHandle = await fh.fileHandle.createSyncAccessHandle();
|
||||
@ -163,7 +167,7 @@ const getSyncHandle = async (fh)=>{
|
||||
}
|
||||
warn("Error getting sync handle. Waiting",ms,
|
||||
"ms and trying again.",fh.filenameAbs,e);
|
||||
Atomics.wait(state.sabOPView, state.opIds.xSleep, 0, ms);
|
||||
Atomics.wait(state.sabOPView, state.opIds.retry, 0, ms);
|
||||
}
|
||||
}
|
||||
log("Got sync handle for",fh.filenameAbs,'in',performance.now() - t,'ms');
|
||||
@ -305,7 +309,7 @@ const vfsAsyncImpls = {
|
||||
storeAndNotify('xAccess', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xClose: async function(fid){
|
||||
xClose: async function(fid/*sqlite3_file pointer*/){
|
||||
const opName = 'xClose';
|
||||
mTimeStart(opName);
|
||||
const fh = __openFiles[fid];
|
||||
@ -364,7 +368,7 @@ const vfsAsyncImpls = {
|
||||
wTimeEnd();
|
||||
return rc;
|
||||
},
|
||||
xFileSize: async function(fid){
|
||||
xFileSize: async function(fid/*sqlite3_file pointer*/){
|
||||
mTimeStart('xFileSize');
|
||||
const fh = __openFiles[fid];
|
||||
let sz;
|
||||
@ -381,7 +385,8 @@ const vfsAsyncImpls = {
|
||||
storeAndNotify('xFileSize', sz);
|
||||
mTimeEnd();
|
||||
},
|
||||
xLock: async function(fid,lockType){
|
||||
xLock: async function(fid/*sqlite3_file pointer*/,
|
||||
lockType/*SQLITE_LOCK_...*/){
|
||||
mTimeStart('xLock');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
@ -397,7 +402,8 @@ const vfsAsyncImpls = {
|
||||
storeAndNotify('xLock',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xOpen: async function(fid/*sqlite3_file pointer*/, filename, flags){
|
||||
xOpen: async function(fid/*sqlite3_file pointer*/, filename,
|
||||
flags/*SQLITE_OPEN_...*/){
|
||||
const opName = 'xOpen';
|
||||
mTimeStart(opName);
|
||||
const deleteOnClose = (state.sq3Codes.SQLITE_OPEN_DELETEONCLOSE & flags);
|
||||
@ -440,7 +446,7 @@ const vfsAsyncImpls = {
|
||||
}
|
||||
mTimeEnd();
|
||||
},
|
||||
xRead: async function(fid,n,offset){
|
||||
xRead: async function(fid/*sqlite3_file pointer*/,n,offset64){
|
||||
mTimeStart('xRead');
|
||||
let rc = 0, nRead;
|
||||
const fh = __openFiles[fid];
|
||||
@ -448,7 +454,7 @@ const vfsAsyncImpls = {
|
||||
wTimeStart('xRead');
|
||||
nRead = (await getSyncHandle(fh)).read(
|
||||
fh.sabView.subarray(0, n),
|
||||
{at: Number(offset)}
|
||||
{at: Number(offset64)}
|
||||
);
|
||||
wTimeEnd();
|
||||
if(nRead < n){/* Zero-fill remaining bytes */
|
||||
@ -464,7 +470,7 @@ const vfsAsyncImpls = {
|
||||
storeAndNotify('xRead',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xSync: async function(fid,flags/*ignored*/){
|
||||
xSync: async function(fid/*sqlite3_file pointer*/,flags/*ignored*/){
|
||||
mTimeStart('xSync');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
@ -480,7 +486,7 @@ const vfsAsyncImpls = {
|
||||
storeAndNotify('xSync',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xTruncate: async function(fid,size){
|
||||
xTruncate: async function(fid/*sqlite3_file pointer*/,size){
|
||||
mTimeStart('xTruncate');
|
||||
let rc = 0;
|
||||
const fh = __openFiles[fid];
|
||||
@ -497,7 +503,8 @@ const vfsAsyncImpls = {
|
||||
storeAndNotify('xTruncate',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xUnlock: async function(fid,lockType){
|
||||
xUnlock: async function(fid/*sqlite3_file pointer*/,
|
||||
lockType/*SQLITE_LOCK_...*/){
|
||||
mTimeStart('xUnlock');
|
||||
let rc = 0;
|
||||
const fh = __openFiles[fid];
|
||||
@ -514,7 +521,7 @@ const vfsAsyncImpls = {
|
||||
storeAndNotify('xUnlock',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xWrite: async function(fid,n,offset){
|
||||
xWrite: async function(fid/*sqlite3_file pointer*/,n,offset64){
|
||||
mTimeStart('xWrite');
|
||||
let rc;
|
||||
wTimeStart('xWrite');
|
||||
@ -524,7 +531,7 @@ const vfsAsyncImpls = {
|
||||
rc = (
|
||||
n === (await getSyncHandle(fh))
|
||||
.write(fh.sabView.subarray(0, n),
|
||||
{at: Number(offset)})
|
||||
{at: Number(offset64)})
|
||||
) ? 0 : state.sq3Codes.SQLITE_IOERR_WRITE;
|
||||
}catch(e){
|
||||
error("xWrite():",e,fh);
|
||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\stypo\sin\scomment.
|
||||
D 2022-10-24T18:42:45.118
|
||||
C Minor\scleanups\sand\sdoc\simprovements\sin\sthe\sOPFS\ssqlite3_vfs\sproxy.
|
||||
D 2022-10-25T08:06:17.330
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -478,7 +478,7 @@ F ext/wasm/README.md 1e5b28158b74ab3ffc9d54fcbc020f0bbeb82c2ff8bbd904214c86c70e8
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 36f413ab4dbb057d2dec938fb366ac0a4c5e85ba14660a8d672f0277602c0fc5
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
F ext/wasm/api/README.md 1350088aee90e959ad9a94fab1bb6bcb5e99d4d27f976db389050f54f2640c78
|
||||
F ext/wasm/api/extern-post-js.js efbed835f290b3741259acc5faf68714a60d38e6834e6cfe172d5354c87566d2
|
||||
F ext/wasm/api/extern-post-js.js 926d192b72fa808378e5e7843721dc7ba3908c163a0260e06d8aa501c12f5469
|
||||
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 2e5c886398013ba2af88028ecbced1e4b22dc96a86467f1ecc5ba9e64ef90a8b
|
||||
@ -486,11 +486,11 @@ F ext/wasm/api/pre-js.js 151e0616614a49f3db19ed544fa13b38c87c108959fbcd4029ea839
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js 4d07a7524dc9b7b050acfde57163e839243ad2383bd7ee0de0178b1b3e988588
|
||||
F ext/wasm/api/sqlite3-api-glue.js 6e4e472eb5afc732a695cd7c5ded6dee6ef8b480e61aa0d648a3fc9033c84745
|
||||
F ext/wasm/api/sqlite3-api-oo1.js ca41ffe58bfbbefc98181081fba0b7af58afcc2770e963558f4f6a408c583fc0
|
||||
F ext/wasm/api/sqlite3-api-opfs.js 22d60ba956e873b65e2e0591e239178082bd53a6d563c3c58db7dc03e562e8f7
|
||||
F ext/wasm/api/sqlite3-api-opfs.js 62da8b7cac30d4e7bb940762d2ac948b0aeb89704a5a290b74eb268ecbd1a64e
|
||||
F ext/wasm/api/sqlite3-api-prologue.js fa00d55f927e5a4ec51cf2c80f6f0eaed2f4f5774341ecf3d63a0ea4c738f8f5
|
||||
F ext/wasm/api/sqlite3-api-worker1.js a7f38f03275d6c27ab2aef3e83215d3c97ce09c43e6904df47c3764d9d4572b4
|
||||
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 206ce6bbc3c30ad51a37d9c25e3a2712e70b586e0f9a2cf8cb0b9619017c2671
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js f04cb1eb483c92bc61fe02749f7afcf17ec803968171aedd7d96faf428c26bcb
|
||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||
F ext/wasm/api/sqlite3-wasm.c 940d576bda7068ba60492e206d06a3567b8a89a3770700aa88690a6e246a0c78
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
|
||||
@ -2037,8 +2037,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 69d704224e9ed022fcec591beff2ffcc4daf3e7fc586debfdcf00b25c1fddd87
|
||||
R e2a88fcf6a9d4446fa629ea861bc8ca4
|
||||
U drh
|
||||
Z ea85a8ca90f8837e6e02f1969966b7f9
|
||||
P f65c95658fe4d30817da8de7eb88e823ea1cd8be40e347d626870bad3cc13359
|
||||
R 18bf727aa37df31466f2ea66a532842e
|
||||
U stephan
|
||||
Z 9cf62ee935cac4cb5c613433da7a1983
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
f65c95658fe4d30817da8de7eb88e823ea1cd8be40e347d626870bad3cc13359
|
||||
48645f7bcacf81c4149f26d20ee1752fbe93a02f96b85bd7e28bfa49322137e5
|
Reference in New Issue
Block a user