mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Significant cleanups and expansion of the sqlite3.opfs utilities. Add oo1.DB.dbVfsName(). Add VFS name to worker1:open's arguments and result.
FossilOrigin-Name: 86a341d7e061f946b39e8647ddd4743013b851b33ae9e6e755d8dbc53fba5286
This commit is contained in:
@ -258,9 +258,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
in the form of a single configuration object with the following
|
in the form of a single configuration object with the following
|
||||||
properties:
|
properties:
|
||||||
|
|
||||||
- `.filename`: database file name
|
- `filename`: database file name
|
||||||
- `.flags`: open-mode flags
|
- `flags`: open-mode flags
|
||||||
- `.vfs`: the VFS fname
|
- `vfs`: the VFS fname
|
||||||
|
|
||||||
The `filename` and `vfs` arguments may be either JS strings or
|
The `filename` and `vfs` arguments may be either JS strings or
|
||||||
C-strings allocated via WASM. `flags` is required to be a JS
|
C-strings allocated via WASM. `flags` is required to be a JS
|
||||||
@ -560,6 +560,25 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
dbName: function(dbNumber=0){
|
dbName: function(dbNumber=0){
|
||||||
return capi.sqlite3_db_name(affirmDbOpen(this).pointer, dbNumber);
|
return capi.sqlite3_db_name(affirmDbOpen(this).pointer, dbNumber);
|
||||||
},
|
},
|
||||||
|
/**
|
||||||
|
Returns the name of the sqlite3_vfs used by the given database
|
||||||
|
of this connection (defaulting to 'main'). The argument may be
|
||||||
|
either a JS string or a WASM C-string. Returns undefined if the
|
||||||
|
given db name is invalid. Throws if this object has been
|
||||||
|
close()d.
|
||||||
|
*/
|
||||||
|
dbVfsName: function(dbName=0){
|
||||||
|
let rc;
|
||||||
|
const pVfs = capi.sqlite3_js_db_vfs(
|
||||||
|
affirmDbOpen(this).pointer, dbName
|
||||||
|
);
|
||||||
|
if(pVfs){
|
||||||
|
const v = new capi.sqlite3_vfs(pVfs);
|
||||||
|
try{ rc = wasm.cstringToJs(v.$zName) }
|
||||||
|
finally { v.dispose() }
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
Compiles the given SQL and returns a prepared Stmt. This is
|
Compiles the given SQL and returns a prepared Stmt. This is
|
||||||
the only way to create new Stmt objects. Throws on error.
|
the only way to create new Stmt objects. Throws on error.
|
||||||
|
@ -371,6 +371,20 @@ const installOpfsVfs = function callee(options){
|
|||||||
return rc;
|
return rc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Not part of the public API. Only for test/development use.
|
||||||
|
*/
|
||||||
|
opfsUtil.debug = {
|
||||||
|
asyncShutdown: ()=>{
|
||||||
|
warn("Shutting down OPFS async listener. The OPFS VFS will no longer work.");
|
||||||
|
opRun('opfs-async-shutdown');
|
||||||
|
},
|
||||||
|
asyncRestart: ()=>{
|
||||||
|
warn("Attempting to restart OPFS VFS async listener. Might work, might not.");
|
||||||
|
W.postMessage({type: 'opfs-async-restart'});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const initS11n = ()=>{
|
const initS11n = ()=>{
|
||||||
/**
|
/**
|
||||||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||||
@ -876,37 +890,61 @@ const installOpfsVfs = function callee(options){
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Syncronously deletes the given OPFS filesystem entry, ignoring
|
Expects an OPFS file path. It gets resolved, such that ".."
|
||||||
any errors. As this environment has no notion of "current
|
components are properly expanded, and returned. If the 2nd arg
|
||||||
directory", the given name must be an absolute path. If the 2nd
|
is true, the result is returned as an array of path elements,
|
||||||
argument is truthy, deletion is recursive (use with caution!).
|
else an absolute path string is returned.
|
||||||
|
|
||||||
Returns true if the deletion succeeded and false if it fails,
|
|
||||||
but cannot report the nature of the failure.
|
|
||||||
*/
|
*/
|
||||||
opfsUtil.deleteEntry = function(fsEntryName,recursive=false){
|
opfsUtil.getResolvedPath = function(filename,splitIt){
|
||||||
mTimeStart('xDelete');
|
const p = new URL(filename, "file://irrelevant").pathname;
|
||||||
const rc = opRun('xDelete', fsEntryName, 0, recursive);
|
return splitIt ? p.split('/').filter((v)=>!!v) : p;
|
||||||
mTimeEnd();
|
|
||||||
return 0===rc;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Synchronously creates the given directory name, recursively, in
|
Takes the absolute path to a filesystem element. Returns an
|
||||||
|
array of [handleOfContainingDir, filename]. If the 2nd argument
|
||||||
|
is truthy then each directory element leading to the file is
|
||||||
|
created along the way. Throws if any creation or resolution
|
||||||
|
fails.
|
||||||
|
*/
|
||||||
|
opfsUtil.getDirForFilename = async function f(absFilename, createDirs = false){
|
||||||
|
const path = opfsUtil.getResolvedPath(absFilename, true);
|
||||||
|
const filename = path.pop();
|
||||||
|
let dh = opfsUtil.rootDirectory;
|
||||||
|
for(const dirName of path){
|
||||||
|
if(dirName){
|
||||||
|
dh = await dh.getDirectoryHandle(dirName, {create: !!createDirs});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [dh, filename];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates the given directory name, recursively, in
|
||||||
the OPFS filesystem. Returns true if it succeeds or the
|
the OPFS filesystem. Returns true if it succeeds or the
|
||||||
directory already exists, else false.
|
directory already exists, else false.
|
||||||
*/
|
*/
|
||||||
opfsUtil.mkdir = function(absDirName){
|
opfsUtil.mkdir = async function(absDirName){
|
||||||
mTimeStart('mkdir');
|
try {
|
||||||
const rc = opRun('mkdir', absDirName);
|
await opfsUtil.getDirForFilename(absDirName+"/filepart", true);
|
||||||
mTimeEnd();
|
return true;
|
||||||
return 0===rc;
|
}catch(e){
|
||||||
|
//console.warn("mkdir(",absDirName,") failed:",e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
Synchronously checks whether the given OPFS filesystem exists,
|
Checks whether the given OPFS filesystem entry exists,
|
||||||
returning true if it does, false if it doesn't.
|
returning true if it does, false if it doesn't.
|
||||||
*/
|
*/
|
||||||
opfsUtil.entryExists = function(fsEntryName){
|
opfsUtil.entryExists = async function(fsEntryName){
|
||||||
return 0===opRun('xAccess', fsEntryName);
|
try {
|
||||||
|
const [dh, fn] = await opfsUtil.getDirForFilename(filename);
|
||||||
|
await dh.getFileHandle(fn);
|
||||||
|
return true;
|
||||||
|
}catch(e){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -938,20 +976,160 @@ const installOpfsVfs = function callee(options){
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Only for test/development use.
|
Returns a promise which resolves to an object which represents
|
||||||
|
all files and directories in the OPFS tree. The top-most object
|
||||||
|
has two properties: `dirs` is an array of directory entries
|
||||||
|
(described below) and `files` is a list of file names for all
|
||||||
|
files in that directory.
|
||||||
|
|
||||||
|
Traversal starts at sqlite3.opfs.rootDirectory.
|
||||||
|
|
||||||
|
Each `dirs` entry is an object in this form:
|
||||||
|
|
||||||
|
```
|
||||||
|
{ name: directoryName,
|
||||||
|
dirs: [...subdirs],
|
||||||
|
files: [...file names]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The `files` and `subdirs` entries are always set but may be
|
||||||
|
empty arrays.
|
||||||
|
|
||||||
|
The returned object has the same structure but its `name` is
|
||||||
|
an empty string. All returned objects are created with
|
||||||
|
Object.create(null), so have no prototype.
|
||||||
|
|
||||||
|
Design note: the entries do not contain more information,
|
||||||
|
e.g. file sizes, because getting such info is not only
|
||||||
|
expensive but is subject to locking-related errors.
|
||||||
*/
|
*/
|
||||||
opfsUtil.debug = {
|
opfsUtil.treeList = async function(){
|
||||||
asyncShutdown: ()=>{
|
const doDir = async function callee(dirHandle,tgt){
|
||||||
warn("Shutting down OPFS async listener. OPFS will no longer work.");
|
tgt.name = dirHandle.name;
|
||||||
opRun('opfs-async-shutdown');
|
tgt.dirs = [];
|
||||||
},
|
tgt.files = [];
|
||||||
asyncRestart: ()=>{
|
for await (const handle of dirHandle.values()){
|
||||||
warn("Attempting to restart OPFS async listener. Might work, might not.");
|
if('directory' === handle.kind){
|
||||||
W.postMessage({type: 'opfs-async-restart'});
|
const subDir = Object.create(null);
|
||||||
|
tgt.dirs.push(subDir);
|
||||||
|
await callee(handle, subDir);
|
||||||
|
}else{
|
||||||
|
tgt.files.push(handle.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const root = Object.create(null);
|
||||||
|
await doDir(opfsUtil.rootDirectory, root);
|
||||||
|
return root;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Irrevocably deletes _all_ files in the current origin's OPFS.
|
||||||
|
Obviously, this must be used with great caution. It may throw
|
||||||
|
an exception if removal of anything fails (e.g. a file is
|
||||||
|
locked), but the precise conditions under which it will throw
|
||||||
|
are not documented (so we cannot tell you what they are).
|
||||||
|
*/
|
||||||
|
opfsUtil.rmfr = async function(){
|
||||||
|
const dir = opfsUtil.rootDirectory, opt = {recurse: true};
|
||||||
|
for await (const handle of dir.values()){
|
||||||
|
dir.removeEntry(handle.name, opt);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//TODO to support fiddle db upload:
|
/**
|
||||||
|
Deletes the given OPFS filesystem entry. As this environment
|
||||||
|
has no notion of "current directory", the given name must be an
|
||||||
|
absolute path. If the 2nd argument is truthy, deletion is
|
||||||
|
recursive (use with caution!).
|
||||||
|
|
||||||
|
The returned Promise resolves to true if the deletion was
|
||||||
|
successful, else false (but...). The OPFS API reports the
|
||||||
|
reason for the failure only in human-readable form, not
|
||||||
|
exceptions which can be type-checked to determine the
|
||||||
|
failure. Because of that...
|
||||||
|
|
||||||
|
If the final argument is truthy then this function will
|
||||||
|
propagate any exception on error, rather than returning false.
|
||||||
|
*/
|
||||||
|
opfsUtil.unlink = async function(fsEntryName, recursive = false,
|
||||||
|
throwOnError = false){
|
||||||
|
try {
|
||||||
|
const [hDir, filenamePart] =
|
||||||
|
await opfsUtil.getDirForFilename(fsEntryName, false);
|
||||||
|
await hDir.removeEntry(filenamePart, {recursive});
|
||||||
|
return true;
|
||||||
|
}catch(e){
|
||||||
|
if(throwOnError){
|
||||||
|
throw new Error("unlink(",arguments[0],") failed: "+e.message,{
|
||||||
|
cause: e
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Traverses the OPFS filesystem, calling a callback for each one.
|
||||||
|
The argument may be either a callback function or an options object
|
||||||
|
with any of the following properties:
|
||||||
|
|
||||||
|
- `callback`: function which gets called for each filesystem
|
||||||
|
entry. It gets passed 3 arguments: 1) the
|
||||||
|
FileSystemFileHandle or FileSystemDirectoryHandle of each
|
||||||
|
entry (noting that both are instanceof FileSystemHandle). 2)
|
||||||
|
the FileSystemDirectoryHandle of the parent directory. 3) the
|
||||||
|
current depth level, with 0 being at the top of the tree
|
||||||
|
relative to the starting directory. If the callback returns a
|
||||||
|
literal false, as opposed to any other falsy value, traversal
|
||||||
|
stops without an error. Any exceptions it throws are
|
||||||
|
propagated. Results are undefined if the callback manipulate
|
||||||
|
the filesystem (e.g. removing or adding entries) because the
|
||||||
|
how OPFS iterators behave in the face of such changes is
|
||||||
|
undocumented.
|
||||||
|
|
||||||
|
- `recursive` [bool=true]: specifies whether to recurse into
|
||||||
|
subdirectories or not. Whether recursion is depth-first or
|
||||||
|
breadth-first is unspecified!
|
||||||
|
|
||||||
|
- `directory` [FileSystemDirectoryEntry=sqlite3.opfs.rootDirectory]
|
||||||
|
specifies the starting directory.
|
||||||
|
|
||||||
|
If this function is passed a function, it is assumed to be the
|
||||||
|
callback.
|
||||||
|
|
||||||
|
Returns a promise because it has to (by virtue of being async)
|
||||||
|
but that promise has no specific meaning: the traversal it
|
||||||
|
performs is synchronous. The promise must be used to catch any
|
||||||
|
exceptions propagated by the callback, however.
|
||||||
|
|
||||||
|
TODO: add an option which specifies whether to traverse
|
||||||
|
depth-first or breadth-first. We currently do depth-first but
|
||||||
|
an incremental file browsing widget would benefit more from
|
||||||
|
breadth-first.
|
||||||
|
*/
|
||||||
|
opfsUtil.traverse = async function(opt){
|
||||||
|
const defaultOpt = {
|
||||||
|
recursive: true,
|
||||||
|
directory: opfsUtil.rootDirectory
|
||||||
|
};
|
||||||
|
if('function'===typeof opt){
|
||||||
|
opt = {callback:opt};
|
||||||
|
}
|
||||||
|
opt = Object.assign(defaultOpt, opt||{});
|
||||||
|
const doDir = async function callee(dirHandle, depth){
|
||||||
|
for await (const handle of dirHandle.values()){
|
||||||
|
if(false === opt.callback(handle, dirHandle, depth)) return false;
|
||||||
|
else if(opt.recursive && 'directory' === handle.kind){
|
||||||
|
if(false === await callee(handle, depth + 1)) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
doDir(opt.directory, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO to support fiddle and worker1 db upload:
|
||||||
//opfsUtil.createFile = function(absName, content=undefined){...}
|
//opfsUtil.createFile = function(absName, content=undefined){...}
|
||||||
|
|
||||||
if(sqlite3.oo1){
|
if(sqlite3.oo1){
|
||||||
|
@ -1187,14 +1187,15 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Given an `sqlite3*`, an sqlite3_vfs name, and an optional db
|
Given an `sqlite3*`, an sqlite3_vfs name, and an optional db name
|
||||||
name, returns a truthy value (see below) if that db handle uses
|
(defaulting to "main"), returns a truthy value (see below) if
|
||||||
that VFS, else returns false. If pDb is falsy then the 3rd
|
that db uses that VFS, else returns false. If pDb is falsy then
|
||||||
argument is ignored and this function returns a truthy value if
|
the 3rd argument is ignored and this function returns a truthy
|
||||||
the default VFS name matches that of the 2nd argument. Results
|
value if the default VFS name matches that of the 2nd
|
||||||
are undefined if pDb is truthy but refers to an invalid
|
argument. Results are undefined if pDb is truthy but refers to an
|
||||||
pointer. The 3rd argument specifies the database name of the
|
invalid pointer. The 3rd argument specifies the database name of
|
||||||
given database connection to check, defaulting to the main db.
|
the given database connection to check, defaulting to the main
|
||||||
|
db.
|
||||||
|
|
||||||
The 2nd and 3rd arguments may either be a JS string or a WASM
|
The 2nd and 3rd arguments may either be a JS string or a WASM
|
||||||
C-string. If the 2nd argument is a NULL WASM pointer, the default
|
C-string. If the 2nd argument is a NULL WASM pointer, the default
|
||||||
@ -1209,14 +1210,14 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
bad arguments cause a conversion error when passing into
|
bad arguments cause a conversion error when passing into
|
||||||
wasm-space, false is returned.
|
wasm-space, false is returned.
|
||||||
*/
|
*/
|
||||||
capi.sqlite3_js_db_uses_vfs = function(pDb,vfsName,dbName="main"){
|
capi.sqlite3_js_db_uses_vfs = function(pDb,vfsName,dbName=0){
|
||||||
try{
|
try{
|
||||||
const pK = capi.sqlite3_vfs_find(vfsName);
|
const pK = capi.sqlite3_vfs_find(vfsName);
|
||||||
if(!pK) return false;
|
if(!pK) return false;
|
||||||
else if(!pDb){
|
else if(!pDb){
|
||||||
return pK===capi.sqlite3_vfs_find(0) ? pK : false;
|
return pK===capi.sqlite3_vfs_find(0) ? pK : false;
|
||||||
}else{
|
}else{
|
||||||
return pK===capi.sqlite3_js_db_vfs(pDb) ? pK : false;
|
return pK===capi.sqlite3_js_db_vfs(pDb,dbName) ? pK : false;
|
||||||
}
|
}
|
||||||
}catch(e){
|
}catch(e){
|
||||||
/* Ignore - probably bad args to a wasm-bound function. */
|
/* Ignore - probably bad args to a wasm-bound function. */
|
||||||
|
@ -188,6 +188,8 @@
|
|||||||
See the sqlite3.oo1.DB constructor for peculiarities and
|
See the sqlite3.oo1.DB constructor for peculiarities and
|
||||||
transformations,
|
transformations,
|
||||||
|
|
||||||
|
vfs: sqlite3_vfs name. Ignored if filename is ":memory:" or "".
|
||||||
|
This may change how the given filename is resolved.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -212,6 +214,7 @@
|
|||||||
persistent: true if the given filename resides in the
|
persistent: true if the given filename resides in the
|
||||||
known-persistent storage, else false.
|
known-persistent storage, else false.
|
||||||
|
|
||||||
|
vfs: name of the VFS the "main" db is using.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -362,7 +365,7 @@ sqlite3.initWorker1API = function(){
|
|||||||
/** Temp holder for "transferable" postMessage() state. */
|
/** Temp holder for "transferable" postMessage() state. */
|
||||||
xfer: [],
|
xfer: [],
|
||||||
open: function(opt){
|
open: function(opt){
|
||||||
const db = new DB(opt.filename);
|
const db = new DB(opt);
|
||||||
this.dbs[getDbId(db)] = db;
|
this.dbs[getDbId(db)] = db;
|
||||||
if(this.dbList.indexOf(db)<0) this.dbList.push(db);
|
if(this.dbList.indexOf(db)<0) this.dbList.push(db);
|
||||||
return db;
|
return db;
|
||||||
@ -442,12 +445,14 @@ sqlite3.initWorker1API = function(){
|
|||||||
oargs.filename = args.filename || '';
|
oargs.filename = args.filename || '';
|
||||||
}else{
|
}else{
|
||||||
oargs.filename = args.filename;
|
oargs.filename = args.filename;
|
||||||
|
oargs.vfs = args.vfs;
|
||||||
}
|
}
|
||||||
const db = wState.open(oargs);
|
const db = wState.open(oargs);
|
||||||
rc.filename = db.filename;
|
rc.filename = db.filename;
|
||||||
rc.persistent = (!!pDir && db.filename.startsWith(pDir+'/'))
|
rc.persistent = (!!pDir && db.filename.startsWith(pDir+'/'))
|
||||||
|| !!sqlite3.capi.sqlite3_js_db_uses_vfs(db.pointer, "opfs");
|
|| !!sqlite3.capi.sqlite3_js_db_uses_vfs(db.pointer, "opfs");
|
||||||
rc.dbId = getDbId(db);
|
rc.dbId = getDbId(db);
|
||||||
|
rc.vfs = db.dbVfsName();
|
||||||
return rc;
|
return rc;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -528,6 +533,7 @@ sqlite3.initWorker1API = function(){
|
|||||||
rc.wasmfsOpfsEnabled = !!sqlite3.capi.sqlite3_wasmfs_opfs_dir();
|
rc.wasmfsOpfsEnabled = !!sqlite3.capi.sqlite3_wasmfs_opfs_dir();
|
||||||
rc.version = sqlite3.version;
|
rc.version = sqlite3.version;
|
||||||
rc.vfsList = sqlite3.capi.sqlite3_js_vfs_list();
|
rc.vfsList = sqlite3.capi.sqlite3_js_vfs_list();
|
||||||
|
rc.opfsEnabled = !!sqlite3.opfs;
|
||||||
return rc;
|
return rc;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -542,11 +548,6 @@ sqlite3.initWorker1API = function(){
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
export: function(ev){
|
export: function(ev){
|
||||||
/**
|
|
||||||
We need to reimplement this to use the Emscripten FS
|
|
||||||
interface. That part used to be in the OO#1 API but that
|
|
||||||
dependency was removed from that level of the API.
|
|
||||||
*/
|
|
||||||
const db = getMsgDb(ev);
|
const db = getMsgDb(ev);
|
||||||
const response = {
|
const response = {
|
||||||
bytearray: sqlite3.capi.sqlite3_js_db_export(db.pointer),
|
bytearray: sqlite3.capi.sqlite3_js_db_export(db.pointer),
|
||||||
@ -559,17 +560,23 @@ sqlite3.initWorker1API = function(){
|
|||||||
|
|
||||||
toss: function(ev){
|
toss: function(ev){
|
||||||
toss("Testing worker exception");
|
toss("Testing worker exception");
|
||||||
|
},
|
||||||
|
|
||||||
|
'opfs-tree': async function(ev){
|
||||||
|
if(!sqlite3.opfs) toss("OPFS support is unavailable.");
|
||||||
|
const response = await sqlite3.opfs.treeList();
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
}/*wMsgHandler*/;
|
}/*wMsgHandler*/;
|
||||||
|
|
||||||
self.onmessage = function(ev){
|
self.onmessage = async function(ev){
|
||||||
ev = ev.data;
|
ev = ev.data;
|
||||||
let result, dbId = ev.dbId, evType = ev.type;
|
let result, dbId = ev.dbId, evType = ev.type;
|
||||||
const arrivalTime = performance.now();
|
const arrivalTime = performance.now();
|
||||||
try {
|
try {
|
||||||
if(wMsgHandler.hasOwnProperty(evType) &&
|
if(wMsgHandler.hasOwnProperty(evType) &&
|
||||||
wMsgHandler[evType] instanceof Function){
|
wMsgHandler[evType] instanceof Function){
|
||||||
result = wMsgHandler[evType](ev);
|
result = await wMsgHandler[evType](ev);
|
||||||
}else{
|
}else{
|
||||||
toss("Unknown db worker message type:",ev.type);
|
toss("Unknown db worker message type:",ev.type);
|
||||||
}
|
}
|
||||||
|
@ -377,6 +377,7 @@ const vfsAsyncImpls = {
|
|||||||
if(!filenamePart) break;
|
if(!filenamePart) break;
|
||||||
await hDir.removeEntry(filenamePart, {recursive});
|
await hDir.removeEntry(filenamePart, {recursive});
|
||||||
if(0x1234 !== syncDir) break;
|
if(0x1234 !== syncDir) break;
|
||||||
|
recursive = false;
|
||||||
filename = getResolvedPath(filename, true);
|
filename = getResolvedPath(filename, true);
|
||||||
filename.pop();
|
filename.pop();
|
||||||
filename = filename.join('/');
|
filename = filename.join('/');
|
||||||
|
@ -37,6 +37,8 @@ span.labeled-input {
|
|||||||
.strong { font-weight: 700 }
|
.strong { font-weight: 700 }
|
||||||
.warning { color: firebrick; }
|
.warning { color: firebrick; }
|
||||||
.green { color: darkgreen; }
|
.green { color: darkgreen; }
|
||||||
|
.tests-pass { background-color: green; color: white }
|
||||||
|
.tests-fail { background-color: red; color: yellow }
|
||||||
.faded { opacity: 0.5; }
|
.faded { opacity: 0.5; }
|
||||||
.group-start { color: blue; }
|
.group-start { color: blue; }
|
||||||
.group-end { color: blue; }
|
.group-end { color: blue; }
|
||||||
|
@ -91,7 +91,8 @@
|
|||||||
const r = ev.result;
|
const r = ev.result;
|
||||||
log("then open result",r);
|
log("then open result",r);
|
||||||
T.assert(ev.dbId === r.dbId)
|
T.assert(ev.dbId === r.dbId)
|
||||||
.assert(ev.messageId);
|
.assert(ev.messageId)
|
||||||
|
.assert('string' === typeof r.vfs);
|
||||||
promiserConfig.dbId = ev.dbId;
|
promiserConfig.dbId = ev.dbId;
|
||||||
}).then(runTests2);
|
}).then(runTests2);
|
||||||
};
|
};
|
||||||
|
@ -291,7 +291,8 @@
|
|||||||
log("open result",ev);
|
log("open result",ev);
|
||||||
T.assert('testing2.sqlite3'===ev.result.filename)
|
T.assert('testing2.sqlite3'===ev.result.filename)
|
||||||
.assert(ev.dbId)
|
.assert(ev.dbId)
|
||||||
.assert(ev.messageId);
|
.assert(ev.messageId)
|
||||||
|
.assert('string' === typeof ev.result.vfs);
|
||||||
DbState.id = ev.dbId;
|
DbState.id = ev.dbId;
|
||||||
if(waitForOpen) setTimeout(runTests2, 0);
|
if(waitForOpen) setTimeout(runTests2, 0);
|
||||||
});
|
});
|
||||||
|
@ -37,7 +37,7 @@ const tryOpfsVfs = async function(sqlite3){
|
|||||||
|
|
||||||
const urlArgs = new URL(self.location.href).searchParams;
|
const urlArgs = new URL(self.location.href).searchParams;
|
||||||
const dbFile = "my-persistent.db";
|
const dbFile = "my-persistent.db";
|
||||||
if(urlArgs.has('delete')) sqlite3.opfs.deleteEntry(dbFile);
|
if(urlArgs.has('delete')) sqlite3.opfs.unlink(dbFile);
|
||||||
|
|
||||||
const db = new opfs.OpfsDb(dbFile,'ct');
|
const db = new opfs.OpfsDb(dbFile,'ct');
|
||||||
log("db file:",db.filename);
|
log("db file:",db.filename);
|
||||||
@ -62,13 +62,14 @@ const tryOpfsVfs = async function(sqlite3){
|
|||||||
// Some sanity checks of the opfs utility functions...
|
// Some sanity checks of the opfs utility functions...
|
||||||
const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
|
const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
|
||||||
const aDir = testDir+'/test/dir';
|
const aDir = testDir+'/test/dir';
|
||||||
opfs.mkdir(aDir) || toss("mkdir failed");
|
await opfs.mkdir(aDir) || toss("mkdir failed");
|
||||||
opfs.mkdir(aDir) || toss("mkdir must pass if the dir exists");
|
await opfs.mkdir(aDir) || toss("mkdir must pass if the dir exists");
|
||||||
opfs.deleteEntry(testDir+'/test') && toss("delete 1 should have failed (dir not empty)");
|
await opfs.unlink(testDir+'/test') && toss("delete 1 should have failed (dir not empty)");
|
||||||
opfs.deleteEntry(testDir+'/test/dir') || toss("delete 2 failed");
|
//await opfs.entryExists(testDir)
|
||||||
opfs.deleteEntry(testDir+'/test/dir') && toss("delete 2b should have failed (dir already deleted)");
|
await opfs.unlink(testDir+'/test/dir') || toss("delete 2 failed");
|
||||||
opfs.deleteEntry(testDir,true) || toss("delete 3 failed");
|
await opfs.unlink(testDir+'/test/dir') && toss("delete 2b should have failed (dir already deleted)");
|
||||||
opfs.entryExists(testDir) && toss("entryExists(",testDir,") should have failed");
|
await opfs.unlink(testDir, true) || toss("delete 3 failed");
|
||||||
|
await opfs.entryExists(testDir) && toss("entryExists(",testDir,") should have failed");
|
||||||
}finally{
|
}finally{
|
||||||
db.close();
|
db.close();
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>sqlite3 WASM/JS tester #1 (Worker thread)</h1>
|
<h1 id='color-target'>sqlite3 WASM/JS tester #1 (Worker thread)</h1>
|
||||||
<div>See <a href='tester1.html' target='tester1.html'>tester1.html</a>
|
<div>See <a href='tester1.html' target='tester1.html'>tester1.html</a>
|
||||||
for the UI-thread variant.</div>
|
for the UI-thread variant.</div>
|
||||||
<div class='input-wrapper'>
|
<div class='input-wrapper'>
|
||||||
@ -46,6 +46,14 @@
|
|||||||
case 'log':
|
case 'log':
|
||||||
logHtml(data.payload.cssClass, ...data.payload.args);
|
logHtml(data.payload.cssClass, ...data.payload.args);
|
||||||
break;
|
break;
|
||||||
|
case 'error':
|
||||||
|
logHtml('error', ...data.payload.args);
|
||||||
|
break;
|
||||||
|
case 'test-result':
|
||||||
|
document.querySelector('#color-target').classList.add(
|
||||||
|
data.payload.pass ? 'tests-pass' : 'tests-fail'
|
||||||
|
);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
logHtml('error',"Unhandled message:",data.type);
|
logHtml('error',"Unhandled message:",data.type);
|
||||||
};
|
};
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>sqlite3 WASM/JS tester #1 (UI thread)</h1>
|
<h1 id='color-target'>sqlite3 WASM/JS tester #1 (UI thread)</h1>
|
||||||
<div>See <a href='tester1-worker.html' target='tester1-worker.html'>tester1-worker.html</a>
|
<div>See <a href='tester1-worker.html' target='tester1-worker.html'>tester1-worker.html</a>
|
||||||
for the Worker-thread variant.</div>
|
for the Worker-thread variant.</div>
|
||||||
<div class='input-wrapper'>
|
<div class='input-wrapper'>
|
||||||
|
@ -99,6 +99,14 @@
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const reportFinalTestStatus = function(pass){
|
||||||
|
if(isUIThread()){
|
||||||
|
const e = document.querySelector('#color-target');
|
||||||
|
e.classList.add(pass ? 'tests-pass' : 'tests-fail');
|
||||||
|
}else{
|
||||||
|
postMessage({type:'test-result', payload:{pass}});
|
||||||
|
}
|
||||||
|
};
|
||||||
const log = (...args)=>{
|
const log = (...args)=>{
|
||||||
//console.log(...args);
|
//console.log(...args);
|
||||||
logClass('',...args);
|
logClass('',...args);
|
||||||
@ -139,28 +147,19 @@
|
|||||||
toBool: function(expr){
|
toBool: function(expr){
|
||||||
return (expr instanceof Function) ? !!expr() : !!expr;
|
return (expr instanceof Function) ? !!expr() : !!expr;
|
||||||
},
|
},
|
||||||
/** abort() if expr is false. If expr is a function, it
|
/** Throws if expr is false. If expr is a function, it is called
|
||||||
is called and its result is evaluated.
|
and its result is evaluated. If passed multiple arguments,
|
||||||
|
those after the first are a message string which get applied
|
||||||
|
as an exception message if the assertion fails. The message
|
||||||
|
arguments are concatenated together with a space between each.
|
||||||
*/
|
*/
|
||||||
assert: function f(expr, msg){
|
assert: function f(expr, ...msg){
|
||||||
if(!f._){
|
|
||||||
f._ = ('undefined'===typeof abort
|
|
||||||
? (msg)=>{throw new Error(msg)}
|
|
||||||
: abort);
|
|
||||||
}
|
|
||||||
++this.counter;
|
++this.counter;
|
||||||
if(!this.toBool(expr)){
|
if(!this.toBool(expr)){
|
||||||
f._(msg || "Assertion failed.");
|
throw new Error(msg.length ? msg.join(' ') : "Assertion failed.");
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
/** Identical to assert() but throws instead of calling
|
|
||||||
abort(). */
|
|
||||||
affirm: function(expr, msg){
|
|
||||||
++this.counter;
|
|
||||||
if(!this.toBool(expr)) throw new Error(msg || "Affirmation failed.");
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
/** Calls f() and squelches any exception it throws. If it
|
/** Calls f() and squelches any exception it throws. If it
|
||||||
does not throw, this function throws. */
|
does not throw, this function throws. */
|
||||||
mustThrow: function(f, msg){
|
mustThrow: function(f, msg){
|
||||||
@ -301,9 +300,11 @@
|
|||||||
"Done running tests.",TestUtil.counter,"assertions in",
|
"Done running tests.",TestUtil.counter,"assertions in",
|
||||||
roundMs(runtime),'ms');
|
roundMs(runtime),'ms');
|
||||||
pok();
|
pok();
|
||||||
|
reportFinalTestStatus(true);
|
||||||
}catch(e){
|
}catch(e){
|
||||||
error(e);
|
error(e);
|
||||||
pnok(e);
|
pnok(e);
|
||||||
|
reportFinalTestStatus(false);
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
@ -1117,10 +1118,11 @@
|
|||||||
const dbFile = '/tester1.db';
|
const dbFile = '/tester1.db';
|
||||||
wasm.sqlite3_wasm_vfs_unlink(0, dbFile);
|
wasm.sqlite3_wasm_vfs_unlink(0, dbFile);
|
||||||
const db = this.db = new sqlite3.oo1.DB(dbFile);
|
const db = this.db = new sqlite3.oo1.DB(dbFile);
|
||||||
T.assert(Number.isInteger(db.pointer)).
|
T.assert(Number.isInteger(db.pointer))
|
||||||
mustThrowMatching(()=>db.pointer=1, /read-only/).
|
.mustThrowMatching(()=>db.pointer=1, /read-only/)
|
||||||
assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1)).
|
.assert(0===sqlite3.capi.sqlite3_extended_result_codes(db.pointer,1))
|
||||||
assert('main'===db.dbName(0));
|
.assert('main'===db.dbName(0))
|
||||||
|
.assert('string' === typeof db.dbVfsName());
|
||||||
// Custom db error message handling via sqlite3_prepare_v2/v3()
|
// Custom db error message handling via sqlite3_prepare_v2/v3()
|
||||||
let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
|
let rc = capi.sqlite3_prepare_v3(db.pointer, {/*invalid*/}, -1, 0, null, null);
|
||||||
T.assert(capi.SQLITE_MISUSE === rc)
|
T.assert(capi.SQLITE_MISUSE === rc)
|
||||||
@ -1737,13 +1739,14 @@
|
|||||||
(sqlite3)=>{return !!sqlite3.opfs})
|
(sqlite3)=>{return !!sqlite3.opfs})
|
||||||
.t({
|
.t({
|
||||||
name: 'OPFS sanity checks',
|
name: 'OPFS sanity checks',
|
||||||
test: function(sqlite3){
|
test: async function(sqlite3){
|
||||||
|
const opfs = sqlite3.opfs;
|
||||||
const filename = 'sqlite3-tester1.db';
|
const filename = 'sqlite3-tester1.db';
|
||||||
const pVfs = capi.sqlite3_vfs_find('opfs');
|
const pVfs = capi.sqlite3_vfs_find('opfs');
|
||||||
T.assert(pVfs);
|
T.assert(pVfs);
|
||||||
const unlink = (fn=filename)=>wasm.sqlite3_wasm_vfs_unlink(pVfs,fn);
|
const unlink = (fn=filename)=>wasm.sqlite3_wasm_vfs_unlink(pVfs,fn);
|
||||||
unlink();
|
unlink();
|
||||||
let db = new sqlite3.opfs.OpfsDb(filename);
|
let db = new opfs.OpfsDb(filename);
|
||||||
try {
|
try {
|
||||||
db.exec([
|
db.exec([
|
||||||
'create table p(a);',
|
'create table p(a);',
|
||||||
@ -1751,13 +1754,26 @@
|
|||||||
]);
|
]);
|
||||||
T.assert(3 === db.selectValue('select count(*) from p'));
|
T.assert(3 === db.selectValue('select count(*) from p'));
|
||||||
db.close();
|
db.close();
|
||||||
db = new sqlite3.opfs.OpfsDb(filename);
|
db = new opfs.OpfsDb(filename);
|
||||||
db.exec('insert into p(a) values(4),(5),(6)');
|
db.exec('insert into p(a) values(4),(5),(6)');
|
||||||
T.assert(6 === db.selectValue('select count(*) from p'));
|
T.assert(6 === db.selectValue('select count(*) from p'));
|
||||||
}finally{
|
}finally{
|
||||||
db.close();
|
db.close();
|
||||||
unlink();
|
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 sanity checks*/)
|
}/*OPFS sanity checks*/)
|
||||||
;/* end OPFS tests */
|
;/* end OPFS tests */
|
||||||
|
36
manifest
36
manifest
@ -1,5 +1,5 @@
|
|||||||
C Make\sthe\sUPDATE\smethod\sof\sthe\ssqlite_dbpage\svirtual\stable\srebust\sagainst\nOOM\serrors.\s\s[forum:/forumpost/bbcf0dd6ca|Forum\spost\sbbcf0dd6ca].\s\sTest\scase\nin\sTH3.
|
C Significant\scleanups\sand\sexpansion\sof\sthe\ssqlite3.opfs\sutilities.\sAdd\soo1.DB.dbVfsName().\sAdd\sVFS\sname\sto\sworker1:open's\sarguments\sand\sresult.
|
||||||
D 2022-10-31T18:01:05.280
|
D 2022-11-01T07:49:49.018
|
||||||
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
|
||||||
@ -500,12 +500,12 @@ F ext/wasm/api/post-js-header.js d6ab3dfef4a06960d28a7eaa338d4e2a1a5981e9b387181
|
|||||||
F ext/wasm/api/pre-js.js 287e462f969342b032c03900e668099fa1471d852df7a472de5bc349161d9c04
|
F ext/wasm/api/pre-js.js 287e462f969342b032c03900e668099fa1471d852df7a472de5bc349161d9c04
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js ecdc69dbfccfe26146f04799fcfd4a6f5790d46e7e3b9b6e9b0491f92ed8ae34
|
F ext/wasm/api/sqlite3-api-cleanup.js ecdc69dbfccfe26146f04799fcfd4a6f5790d46e7e3b9b6e9b0491f92ed8ae34
|
||||||
F ext/wasm/api/sqlite3-api-glue.js ebfd1d01b249c705482bfe3bdef3b1feaecf55821c46abf79b8105ec9b1c2b1a
|
F ext/wasm/api/sqlite3-api-glue.js ebfd1d01b249c705482bfe3bdef3b1feaecf55821c46abf79b8105ec9b1c2b1a
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 4028bc2bac7e3ae2d23b7c99828155b4a06da006b51dc2a929bc0db26337370d
|
F ext/wasm/api/sqlite3-api-oo1.js ce8db98ab7c394fd8fb99ae135c46269a1a0162250a70e39e7975b4317a03640
|
||||||
F ext/wasm/api/sqlite3-api-opfs.js 6880cc79a4d1b6075942298d9d1ab07e24d81fbd9e5fe6b7c797b86e4b2af596
|
F ext/wasm/api/sqlite3-api-opfs.js 59b278ed00764fc47ba88be0582ab3fc3ce725e02b6d86459464cc029b9ac356
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js 873986ca150c79510f647b910f8349bc71b14db21e444cab3b9fad9c4f39ffc7
|
F ext/wasm/api/sqlite3-api-prologue.js 850581aa0c759db25c04d64b340b0c5272f253fb195377acc8d851e376710ad3
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js 7de5160ba86ed216e8b99ba1ae0c39c1ff85c11a4818252bfc8dd0dc21109b84
|
F ext/wasm/api/sqlite3-api-worker1.js 4f920a54fb97d4ca50632d45bd7d011a55016eb5a5883725033abb450903bc6f
|
||||||
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
|
F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
|
||||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js b2264efef84c4a0af5dab426d7573d8b4ee5af3a25ba108b709a835a613c5e36
|
F ext/wasm/api/sqlite3-opfs-async-proxy.js 2627bf8dc04c24783a55de40d8a6d18da31e81a9bb926a5b672b402f582099b5
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||||
F ext/wasm/api/sqlite3-wasm.c 14ac9c03f6585332f882703f3427f11ffe8ffe8b6c0e252be2c518f7aac6ab6a
|
F ext/wasm/api/sqlite3-wasm.c 14ac9c03f6585332f882703f3427f11ffe8ffe8b6c0e252be2c518f7aac6ab6a
|
||||||
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
|
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
|
||||||
@ -514,7 +514,7 @@ F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d
|
|||||||
F ext/wasm/batch-runner.js 49609e89aaac9989d6c1ad3fae268e4878e1ad7bc5fd3e5c2f44959660780b2e
|
F ext/wasm/batch-runner.js 49609e89aaac9989d6c1ad3fae268e4878e1ad7bc5fd3e5c2f44959660780b2e
|
||||||
F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b
|
F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b
|
||||||
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
F ext/wasm/common/testing.css 739b58c44511f642f16f57b701c84dc9ee412d8bc47b3d8a99d947babfa69d9d
|
F ext/wasm/common/testing.css 35889709547d89a6109ff83b25c11bbc91d8dd43aab8722e428655ca98880a06
|
||||||
F ext/wasm/common/whwasmutil.js 77930367c2a65cf6fd6f99ad3644ede33e4d20466f5e506eb87b8d101a0a7655
|
F ext/wasm/common/whwasmutil.js 77930367c2a65cf6fd6f99ad3644ede33e4d20466f5e506eb87b8d101a0a7655
|
||||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||||
@ -522,9 +522,9 @@ F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb0
|
|||||||
F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e
|
F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e
|
||||||
F ext/wasm/demo-jsstorage.js 44e3ae7ec2483b6c511384c3c290beb6f305c721186bcf5398ca4e00004a06b8
|
F ext/wasm/demo-jsstorage.js 44e3ae7ec2483b6c511384c3c290beb6f305c721186bcf5398ca4e00004a06b8
|
||||||
F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98ab22f5786620b3354ed15f
|
F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98ab22f5786620b3354ed15f
|
||||||
F ext/wasm/demo-worker1-promiser.js f68ffbbe1c6086e18ce7961b8fc2b40dd88db174f59052e228c06b07484945ca
|
F ext/wasm/demo-worker1-promiser.js 988ce92220c1cf1dd95fcb6b59734f0ae677942469390ddd8a64f4bbb5f99821
|
||||||
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
|
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
|
||||||
F ext/wasm/demo-worker1.js 8ba51d94c4601fa5c313d9e59b63b238f5305b5d5739ad21f4782a0161e6682e
|
F ext/wasm/demo-worker1.js 117e4eedc62e103e287f0e4a694add7e13a200a4d7056e718645032288c4a8ab
|
||||||
F ext/wasm/dist.make 481289899a07958439d07ee4302ff86235fa0fbb72f17ea05db2be90a94abf90
|
F ext/wasm/dist.make 481289899a07958439d07ee4302ff86235fa0fbb72f17ea05db2be90a94abf90
|
||||||
F ext/wasm/fiddle.make e570ec1bfc7d803507a2e514fe32f673fe001b2114b85c73c3964a462ba8bcfc
|
F ext/wasm/fiddle.make e570ec1bfc7d803507a2e514fe32f673fe001b2114b85c73c3964a462ba8bcfc
|
||||||
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
@ -546,10 +546,10 @@ F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f129
|
|||||||
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
|
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
|
||||||
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
|
F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5
|
||||||
F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f
|
F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f
|
||||||
F ext/wasm/test-opfs-vfs.js 48fc59110e8775bb43c9be25b6d634fc07ebadab7da8fbd44889e8129c6e2548
|
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
|
||||||
F ext/wasm/tester1-worker.html d02b9d38876b023854cf8955e77a40912f7e516956b4dbe1ec7f215faac273ee
|
F ext/wasm/tester1-worker.html 51bf39e2b87f974ae3d5bc3086e2fb36d258f3698c54f6e21ba4b3b99636fa27
|
||||||
F ext/wasm/tester1.html c6c47e5a8071eb09cb1301104435c8e44fbb5719c92411f5b2384a461f9793c5
|
F ext/wasm/tester1.html 624ec41cd9f78a1f2b6d7df70aaa7a6394396b1f2455ecbd6de5775c1275b121
|
||||||
F ext/wasm/tester1.js 2427ac48e255f658ad81163b5dc6372a8609ab6ab60e295e371d1e5fe9a495ab
|
F ext/wasm/tester1.js 157eb499aad3365e33a7d95d6847c1d58d533335bc19d79bd3bc700b6350d1a5
|
||||||
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
|
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
|
||||||
F ext/wasm/wasmfs.make fb2d3c4a298b12cf1ec994ad1d0f1d027ae297449b364cde43d2eb807d68048f
|
F ext/wasm/wasmfs.make fb2d3c4a298b12cf1ec994ad1d0f1d027ae297449b364cde43d2eb807d68048f
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
@ -2054,8 +2054,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 c7750c101d9b7baa31496731bc34ea0a9b2bad0c11e2b3e92a8c7b327135c1bb
|
P d15c9a4a323b825eb80e706e12e9df95e5db458024f51e6e537940efc8234d8b
|
||||||
R 196f3951f65687c9f90c3fbde15932cd
|
R 095ddbe256b2c65febf55a9bc126a8d9
|
||||||
U drh
|
U stephan
|
||||||
Z 5dce30cfcdbfc3a472a813e27f5eb193
|
Z 25b125153b5de3e07d69ba6b59e3eede
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
d15c9a4a323b825eb80e706e12e9df95e5db458024f51e6e537940efc8234d8b
|
86a341d7e061f946b39e8647ddd4743013b851b33ae9e6e755d8dbc53fba5286
|
Reference in New Issue
Block a user