mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Expand "sqlite3_vfs*" JS-to-WASM function argument conversions to accept VFS names (JS strings) and capi.sqlite3_vfs instances. Implement sqlite3_js_vfs_create_file() to facilitate creation of file-upload features which store the file in VFS-specific storage (where possible, e.g. "unix" and "opfs" VFSes). Correct an argument type check in the SQLite3Error and WasmAllocError constructors.
FossilOrigin-Name: e1009b16d351b23676ad7bffab0c91b373a92132eb855c9af61991b50cd237ed
This commit is contained in:
@ -73,8 +73,27 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
('sqlite3_stmt*', aPtr)
|
('sqlite3_stmt*', aPtr)
|
||||||
('sqlite3_context*', aPtr)
|
('sqlite3_context*', aPtr)
|
||||||
('sqlite3_value*', aPtr)
|
('sqlite3_value*', aPtr)
|
||||||
('sqlite3_vfs*', aPtr)
|
('void*', aPtr)
|
||||||
('void*', aPtr);
|
/**
|
||||||
|
`sqlite3_vfs*`:
|
||||||
|
|
||||||
|
- v is-a string: use the result of sqlite3_vfs_find(v) but
|
||||||
|
throw if it returns 0.
|
||||||
|
- v is-a capi.sqlite3_vfs: use v.pointer.
|
||||||
|
- Else return the same as the `'*'` argument conversion.
|
||||||
|
*/
|
||||||
|
('sqlite3_vfs*', (v)=>{
|
||||||
|
if('string'===typeof v){
|
||||||
|
const x = capi.sqlite3_vfs_find(v);
|
||||||
|
/* A NULL sqlite3_vfs pointer will be treated as the default
|
||||||
|
VFS in many contexts. We specifically do not want that
|
||||||
|
behavior here. */
|
||||||
|
if(!x) sqlite3.SQLite3Error.toss("Unknown sqlite3_vfs name:",v);
|
||||||
|
return x;
|
||||||
|
}else if(v instanceof sqlite3.capi.sqlite3_vfs) v = v.pointer;
|
||||||
|
return aPtr(v);
|
||||||
|
});
|
||||||
|
|
||||||
wasm.xWrap.resultAdapter('sqlite3*', aPtr)
|
wasm.xWrap.resultAdapter('sqlite3*', aPtr)
|
||||||
('sqlite3_context*', aPtr)
|
('sqlite3_context*', aPtr)
|
||||||
('sqlite3_stmt*', aPtr)
|
('sqlite3_stmt*', aPtr)
|
||||||
@ -588,8 +607,8 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
'version'
|
'version'
|
||||||
]){
|
]){
|
||||||
for(const e of Object.entries(wasm.ctype[t])){
|
for(const e of Object.entries(wasm.ctype[t])){
|
||||||
// ^^^ [k,v] there triggers a buggy code transormation via one
|
// ^^^ [k,v] there triggers a buggy code transformation via
|
||||||
// of the Emscripten-driven optimizers.
|
// one of the Emscripten-driven optimizers.
|
||||||
capi[e[0]] = e[1];
|
capi[e[0]] = e[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
constructor(...args){
|
constructor(...args){
|
||||||
if(1===args.length && __isInt(args[0])){
|
if(1===args.length && __isInt(args[0])){
|
||||||
super(__rcStr(args[0]));
|
super(__rcStr(args[0]));
|
||||||
}else if(2===args.length && 'object'===typeof args){
|
}else if(2===args.length && 'object'===typeof args[1]){
|
||||||
if(__isInt(args[0])) super(__rcStr(args[0]), args[1]);
|
if(__isInt(args[0])) super(__rcStr(args[0]), args[1]);
|
||||||
else super(...args);
|
else super(...args);
|
||||||
}else{
|
}else{
|
||||||
@ -354,7 +354,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
message.
|
message.
|
||||||
*/
|
*/
|
||||||
constructor(...args){
|
constructor(...args){
|
||||||
if(2===args.length && 'object'===typeof args){
|
if(2===args.length && 'object'===typeof args[1]){
|
||||||
super(...args);
|
super(...args);
|
||||||
}else if(args.length){
|
}else if(args.length){
|
||||||
super(args.join(' '));
|
super(args.join(' '));
|
||||||
@ -748,7 +748,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Reports info about compile-time options using
|
Reports info about compile-time options using
|
||||||
sqlite_compileoption_get() and sqlite3_compileoption_used(). It
|
sqlite3_compileoption_get() and sqlite3_compileoption_used(). It
|
||||||
has several distinct uses:
|
has several distinct uses:
|
||||||
|
|
||||||
If optName is an array then it is expected to be a list of
|
If optName is an array then it is expected to be a list of
|
||||||
@ -973,7 +973,6 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
["sqlite3_wasm_vfs_unlink", "int", "sqlite3_vfs*","string"]
|
["sqlite3_wasm_vfs_unlink", "int", "sqlite3_vfs*","string"]
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
sqlite3.wasm.pstack (pseudo-stack) holds a special-case
|
sqlite3.wasm.pstack (pseudo-stack) holds a special-case
|
||||||
stack-style allocator intended only for use with _small_ data of
|
stack-style allocator intended only for use with _small_ data of
|
||||||
@ -1327,6 +1326,76 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
"bytes for sqlite3_aggregate_context()")
|
"bytes for sqlite3_aggregate_context()")
|
||||||
: 0);
|
: 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates a file using the storage appropriate for the given
|
||||||
|
sqlite3_vfs. The first argument may be a VFS name (JS string
|
||||||
|
only, NOT a WASM C-string), WASM-managed `sqlite3_vfs*`, or
|
||||||
|
a capi.sqlite3_vfs instance. Pass 0 (a NULL pointer) to use the
|
||||||
|
default VFS. If passed a string which does not resolve using
|
||||||
|
sqlite3_vfs_find(), an exception is thrown. (Note that a WASM
|
||||||
|
C-string is not accepted because it is impossible to
|
||||||
|
distinguish from a C-level `sqlite3_vfs*`.)
|
||||||
|
|
||||||
|
The second argument, the filename, must be a JS or WASM C-string.
|
||||||
|
|
||||||
|
The 3rd may either be falsy, a valid WASM memory pointer, or a
|
||||||
|
Uint8Array. The 4th must be the length, in bytes, of the data
|
||||||
|
array to copy. If the 3rd argument is a Uint8Array and the 4th is
|
||||||
|
not a positive integer then the 4th defaults to the array's
|
||||||
|
byteLength value.
|
||||||
|
|
||||||
|
If data is falsy then a file is created with dataLen bytes filled
|
||||||
|
with uninitialized data (whatever truncate() leaves there). If
|
||||||
|
data is not falsy then a file is created or truncated and it is
|
||||||
|
filled with the first dataLen bytes of the data source.
|
||||||
|
|
||||||
|
Throws if any arguments are invalid or if creating or writing to
|
||||||
|
the file fails.
|
||||||
|
|
||||||
|
Note that most VFSes do _not_ automatically create directory
|
||||||
|
parts of filenames, nor do all VFSes have a concept of
|
||||||
|
directories. If the given filename is not valid for the given
|
||||||
|
VFS, an exception will be thrown. This function exists primarily
|
||||||
|
to assist in implementing file-upload capability, with the caveat
|
||||||
|
that clients must have some idea of the VFS into which they want
|
||||||
|
to upload and that VFS must support the operation.
|
||||||
|
|
||||||
|
VFS-specific notes:
|
||||||
|
|
||||||
|
- "memdb" and "kvvfs": results are undefined.
|
||||||
|
|
||||||
|
- "unix" and related: will use the WASM build's equivalent of the
|
||||||
|
POSIX I/O APIs.
|
||||||
|
|
||||||
|
- "opfs": if available, uses OPFS storage and _does_ create
|
||||||
|
directory parts of the filename.
|
||||||
|
*/
|
||||||
|
capi.sqlite3_js_vfs_create_file = function(vfs, filename, data, dataLen){
|
||||||
|
let pData;
|
||||||
|
if(!data) pData = 0;
|
||||||
|
else if(wasm.isPtr(data)){
|
||||||
|
pData = data;
|
||||||
|
}else if(data instanceof Uint8Array){
|
||||||
|
pData = wasm.allocFromTypedArray(data);
|
||||||
|
if(arguments.length<4 || !util.isInt32(dataLen) || dataLen<0){
|
||||||
|
dataLen = data.byteLength;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
SQLite3Error.toss("Invalid 3rd argument type for sqlite3_js_vfs_create_file().");
|
||||||
|
}
|
||||||
|
if(!util.isInt32(dataLen) || dataLen<0){
|
||||||
|
wasm.dealloc(pData);
|
||||||
|
SQLite3Error.toss("Invalid 4th argument for sqlite3_js_vfs_create_file().");
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
const rc = wasm.sqlite3_wasm_vfs_create_file(vfs, filename, pData, dataLen);
|
||||||
|
if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code",
|
||||||
|
capi.sqlite3_js_rc_str(rc));
|
||||||
|
}finally{
|
||||||
|
wasm.dealloc(pData);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if( util.isUIThread() ){
|
if( util.isUIThread() ){
|
||||||
/* Features specific to the main window thread... */
|
/* Features specific to the main window thread... */
|
||||||
|
@ -1313,7 +1313,7 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
|
|
||||||
const __xResultAdapterCheck =
|
const __xResultAdapterCheck =
|
||||||
(t)=>xcv.result[t] || toss("Result adapter not found:",t);
|
(t)=>xcv.result[t] || toss("Result adapter not found:",t);
|
||||||
|
|
||||||
cache.xWrap.convertArg = (t,v)=>__xArgAdapterCheck(t)(v);
|
cache.xWrap.convertArg = (t,v)=>__xArgAdapterCheck(t)(v);
|
||||||
cache.xWrap.convertResult =
|
cache.xWrap.convertResult =
|
||||||
(t,v)=>(null===t ? v : (t ? __xResultAdapterCheck(t)(v) : undefined));
|
(t,v)=>(null===t ? v : (t ? __xResultAdapterCheck(t)(v) : undefined));
|
||||||
@ -1442,7 +1442,7 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
exception.
|
exception.
|
||||||
|
|
||||||
Clients may map their own result and argument adapters using
|
Clients may map their own result and argument adapters using
|
||||||
xWrap.resultAdapter() and xWrap.argAdaptor(), noting that not all
|
xWrap.resultAdapter() and xWrap.argAdapter(), noting that not all
|
||||||
type conversions are valid for both arguments _and_ result types
|
type conversions are valid for both arguments _and_ result types
|
||||||
as they often have different memory ownership requirements.
|
as they often have different memory ownership requirements.
|
||||||
|
|
||||||
@ -1497,7 +1497,7 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
};
|
};
|
||||||
}/*xWrap()*/;
|
}/*xWrap()*/;
|
||||||
|
|
||||||
/** Internal impl for xWrap.resultAdapter() and argAdaptor(). */
|
/** Internal impl for xWrap.resultAdapter() and argAdapter(). */
|
||||||
const __xAdapter = function(func, argc, typeName, adapter, modeName, xcvPart){
|
const __xAdapter = function(func, argc, typeName, adapter, modeName, xcvPart){
|
||||||
if('string'===typeof typeName){
|
if('string'===typeof typeName){
|
||||||
if(1===argc) return xcvPart[typeName];
|
if(1===argc) return xcvPart[typeName];
|
||||||
@ -1575,7 +1575,7 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
*/
|
*/
|
||||||
target.xWrap.argAdapter = function f(typeName, adapter){
|
target.xWrap.argAdapter = function f(typeName, adapter){
|
||||||
return __xAdapter(f, arguments.length, typeName, adapter,
|
return __xAdapter(f, arguments.length, typeName, adapter,
|
||||||
'argAdaptor()', xcv.arg);
|
'argAdapter()', xcv.arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1601,6 +1601,33 @@ self.WhWasmUtilInstaller = function(target){
|
|||||||
return target.xWrap(fname, resultType, argTypes||[]).apply(null, args||[]);
|
return target.xWrap(fname, resultType, argTypes||[]).apply(null, args||[]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
This function is ONLY exposed in the public API to facilitate
|
||||||
|
testing. It should not be used in application-level code, only
|
||||||
|
in test code.
|
||||||
|
|
||||||
|
Expects to be given (typeName, value) and returns a conversion
|
||||||
|
of that value as has been registered using argAdapter().
|
||||||
|
It throws if no adapter is found.
|
||||||
|
|
||||||
|
ACHTUNG: the adapter may require that a scopedAllocPush() is
|
||||||
|
active and it may allocate memory within that scope.
|
||||||
|
*/
|
||||||
|
target.xWrap.testConvertArg = cache.xWrap.convertArg;
|
||||||
|
/**
|
||||||
|
This function is ONLY exposed in the public API to facilitate
|
||||||
|
testing. It should not be used in application-level code, only
|
||||||
|
in test code.
|
||||||
|
|
||||||
|
Expects to be given (typeName, value) and returns a conversion
|
||||||
|
of that value as has been registered using resultAdapter().
|
||||||
|
It throws if no adapter is found.
|
||||||
|
|
||||||
|
ACHTUNG: the adapter may allocate memory which the caller may need
|
||||||
|
to know how to free.
|
||||||
|
*/
|
||||||
|
target.xWrap.testConvertResult = cache.xWrap.convertResult;
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1236,8 +1236,19 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
//log("vfsList =",vfsList);
|
//log("vfsList =",vfsList);
|
||||||
for(const v of vfsList){
|
for(const v of vfsList){
|
||||||
T.assert('string' === typeof v)
|
T.assert('string' === typeof v)
|
||||||
.assert(capi.sqlite3_vfs_find(v) > 0);
|
.assert(wasm.isPtr(
|
||||||
|
capi.sqlite3_vfs_find(v)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
// While we have vfsList handy, let's verify...
|
||||||
|
wasm.scopedAllocCall(()=>{
|
||||||
|
const vfsArg = (v)=>wasm.xWrap.testConvertArg('sqlite3_vfs*',v);
|
||||||
|
T.assert(wasm.isPtr(vfsArg(vfsList[0])));
|
||||||
|
const pVfs = capi.sqlite3_vfs_find(vfsList[0]);
|
||||||
|
const vfs = new capi.sqlite3_vfs(pVfs);
|
||||||
|
T.assert(wasm.isPtr(vfsArg(vfs)));
|
||||||
|
vfs.dispose();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
Trivia: the magic db name ":memory:" does not actually use the
|
Trivia: the magic db name ":memory:" does not actually use the
|
||||||
@ -1784,14 +1795,15 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
T.g('OPFS (Worker thread only and only in supported browsers)',
|
T.g('OPFS (Worker thread only and only in supported browsers)',
|
||||||
(sqlite3)=>{return !!sqlite3.opfs})
|
(sqlite3)=>!!sqlite3.opfs)
|
||||||
.t({
|
.t({
|
||||||
name: 'OPFS sanity checks',
|
name: 'OPFS db sanity checks',
|
||||||
test: async function(sqlite3){
|
test: async function(sqlite3){
|
||||||
const filename = 'sqlite3-tester1.db';
|
const filename = this.opfsDbFile = 'sqlite3-tester1.db';
|
||||||
const pVfs = capi.sqlite3_vfs_find('opfs');
|
const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
|
||||||
T.assert(pVfs);
|
T.assert(pVfs);
|
||||||
const unlink = (fn=filename)=>wasm.sqlite3_wasm_vfs_unlink(pVfs,fn);
|
const unlink = this.opfsUnlink =
|
||||||
|
(fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)};
|
||||||
unlink();
|
unlink();
|
||||||
let db = new sqlite3.oo1.OpfsDb(filename);
|
let db = new sqlite3.oo1.OpfsDb(filename);
|
||||||
try {
|
try {
|
||||||
@ -1808,42 +1820,76 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
db.close();
|
db.close();
|
||||||
unlink();
|
unlink();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sqlite3.opfs){
|
|
||||||
// Sanity-test sqlite3_wasm_vfs_create_file()...
|
|
||||||
const opfs = sqlite3.opfs;
|
|
||||||
const fSize = 1379;
|
|
||||||
let sh;
|
|
||||||
try{
|
|
||||||
T.assert(!(await opfs.entryExists(filename)));
|
|
||||||
let rc = wasm.sqlite3_wasm_vfs_create_file(
|
|
||||||
pVfs, filename, null, fSize
|
|
||||||
);
|
|
||||||
T.assert(0===rc)
|
|
||||||
.assert(await opfs.entryExists(filename));
|
|
||||||
const fh = await opfs.rootDirectory.getFileHandle(filename);
|
|
||||||
sh = await fh.createSyncAccessHandle();
|
|
||||||
T.assert(fSize === await sh.getSize());
|
|
||||||
}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 sanity checks*/)
|
}/*OPFS db sanity checks*/)
|
||||||
|
.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);
|
||||||
|
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
|
||||||
|
);
|
||||||
|
}, "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 */
|
;/* end OPFS tests */
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
20
manifest
20
manifest
@ -1,5 +1,5 @@
|
|||||||
C Add\sa\stestcase()\smacro\sto\sverify\sthat\sthe\scase\sof\sa\sNOT\sNULL\serror\smessage\nhitting\sthe\sstring\slength\slimit.
|
C Expand\s"sqlite3_vfs*"\sJS-to-WASM\sfunction\sargument\sconversions\sto\saccept\sVFS\snames\s(JS\sstrings)\sand\scapi.sqlite3_vfs\sinstances.\sImplement\ssqlite3_js_vfs_create_file()\sto\sfacilitate\screation\sof\sfile-upload\sfeatures\swhich\sstore\sthe\sfile\sin\sVFS-specific\sstorage\s(where\spossible,\se.g.\s"unix"\sand\s"opfs"\sVFSes).\sCorrect\san\sargument\stype\scheck\sin\sthe\sSQLite3Error\sand\sWasmAllocError\sconstructors.
|
||||||
D 2022-11-30T21:18:23.655
|
D 2022-12-01T03:55:28.175
|
||||||
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
|
||||||
@ -503,9 +503,9 @@ F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08
|
|||||||
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
||||||
F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
|
F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
|
F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
|
||||||
F ext/wasm/api/sqlite3-api-glue.js 03c40b65530d67bb2748b7380aea5fd1534500f812b76a6b401066dcd7fc4116
|
F ext/wasm/api/sqlite3-api-glue.js 5468ba750e081c55ff3c572e3ae47dd415be73907ce40117fb121f37f4d0649e
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 06ad2079368e16cb9f182c18cd37bdc3932536856dff4f60582d0ca5f6c491a8
|
F ext/wasm/api/sqlite3-api-oo1.js 06ad2079368e16cb9f182c18cd37bdc3932536856dff4f60582d0ca5f6c491a8
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js e63bcd1d1942d3313bd11e76ac1fccdd3e34ba54a48b8c8296db8dd892705dbc
|
F ext/wasm/api/sqlite3-api-prologue.js 04f789bab878ea67be8b18dd4292011bbfeb78ebad79eb79c591136332bd469a
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
|
F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
|
||||||
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 9963c78bf6e5ccb5ba28e8597851bd9d980e86803b6d341cc985e586aef10c82
|
F ext/wasm/api/sqlite3-opfs-async-proxy.js 9963c78bf6e5ccb5ba28e8597851bd9d980e86803b6d341cc985e586aef10c82
|
||||||
@ -521,7 +521,7 @@ F ext/wasm/c-pp.c 92285f7bce67ed7b7020b40fde8ed0982c442b63dc33df9dfd4b658d4a6c07
|
|||||||
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 35889709547d89a6109ff83b25c11bbc91d8dd43aab8722e428655ca98880a06
|
F ext/wasm/common/testing.css 35889709547d89a6109ff83b25c11bbc91d8dd43aab8722e428655ca98880a06
|
||||||
F ext/wasm/common/whwasmutil.js 16a592d5c304a2d268ca1c28e08a5b029a2f3cbe10af78dbc3456cfc9e3559d1
|
F ext/wasm/common/whwasmutil.js dbe625a22bf0962cde1f958f2be604d27d2f97ee1b4e6ee0f19c6480aa36aeed
|
||||||
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
|
||||||
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
|
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
|
||||||
@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
|||||||
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
|
F ext/wasm/test-opfs-vfs.js 44363db07b2a20e73b0eb1808de4400ca71b703af718d0fa6d962f15e73bf2ac
|
||||||
F ext/wasm/tester1-worker.html 5ef353348c37cf2e4fd0b23da562d3275523e036260b510734e9a3239ba8c987
|
F ext/wasm/tester1-worker.html 5ef353348c37cf2e4fd0b23da562d3275523e036260b510734e9a3239ba8c987
|
||||||
F ext/wasm/tester1.c-pp.html 74aa9b31c75f12490653f814b53c3dd39f40cd3f70d6a53a716f4e8587107399
|
F ext/wasm/tester1.c-pp.html 74aa9b31c75f12490653f814b53c3dd39f40cd3f70d6a53a716f4e8587107399
|
||||||
F ext/wasm/tester1.c-pp.js c39594bb1a0272a08a1544277a29c1ed920b4c4877611591e7c3185744ae2431
|
F ext/wasm/tester1.c-pp.js b6a8b9d8e8b070d40c140a68072bf0aa41819fe37fb5bbb9391966a3cbc154fa
|
||||||
F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
|
F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
|
||||||
F ext/wasm/tests/opfs/concurrency/test.js bfc3d7e27b207f0827f12568986b8d516a744529550b449314f5c21c9e9faf4a
|
F ext/wasm/tests/opfs/concurrency/test.js bfc3d7e27b207f0827f12568986b8d516a744529550b449314f5c21c9e9faf4a
|
||||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||||
@ -2065,8 +2065,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 6ee61f8cede4998f0c838d6506b058c6b09f34b3d7f30ed296100785c93f8d00
|
P 91f50964c10fb12d889bda7d597d8edf475d97d2d8b534b4400e0fed1d753c6a
|
||||||
R ca2f65a200c7997e977e891739f47e7d
|
R e4bc31bd87c945bd19fac07fc1661145
|
||||||
U drh
|
U stephan
|
||||||
Z 02ee85efaa582407b1d21e8a02ad86a6
|
Z a323b013b8116acefa1b2ce6dcb45815
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
91f50964c10fb12d889bda7d597d8edf475d97d2d8b534b4400e0fed1d753c6a
|
e1009b16d351b23676ad7bffab0c91b373a92132eb855c9af61991b50cd237ed
|
Reference in New Issue
Block a user