mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Expose sqlite3_vfs_unregister() to WASM and unregister kvvfs in Worker threads to avoid its unintended use there (in contexts other than local/sessionStorage). Correct registration of window functions, extend oo1.DB.createFunction() to support window functions, and add window function tests to tester1.js. Correct an incorrect 1-arg handling case for DB.exec(). Add per-test assertion counts to tester1.js.
FossilOrigin-Name: f07ce15479b7224b0d1ba9f147a433136e70c1461aa667d2737d4a918f778f55
This commit is contained in:
@ -443,10 +443,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
try{
|
||||
const funcArgs = __xWrapFuncs({xStep, xFinal, xValue, xInverse, xDestroy},
|
||||
uninstall);
|
||||
rc = sqlite3CreateFunction(pDb, funcName, nArg, eTextRep,
|
||||
pApp, ...funcArgs);
|
||||
rc = sqlite3CreateWindowFunction(pDb, funcName, nArg, eTextRep,
|
||||
pApp, ...funcArgs);
|
||||
}catch(e){
|
||||
console.error("sqlite3_create_function_v2() setup threw:",e);
|
||||
console.error("sqlite3_create_window_function() setup threw:",e);
|
||||
for(let v of uninstall){
|
||||
wasm.uninstallFunction(v);
|
||||
}
|
||||
@ -607,6 +607,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
// Structs NOT to register
|
||||
WasmTestStruct: true
|
||||
});
|
||||
if(!util.isUIThread()){
|
||||
/* We remove the kvvfs VFS from Worker threads below. */
|
||||
notThese.sqlite3_kvvfs_methods = true;
|
||||
}
|
||||
for(const s of wasm.ctype.structs){
|
||||
if(!notThese[s.name]){
|
||||
capi[s.name] = sqlite3.StructBinder(s);
|
||||
@ -614,89 +618,96 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
}
|
||||
}/*end C constant imports*/
|
||||
|
||||
if( util.isMainWindow()
|
||||
&& 0!==capi.sqlite3_vfs_find("kvvfs") ){/* kvvfs-specific glue */
|
||||
const kvvfsMethods = new capi.sqlite3_kvvfs_methods(
|
||||
wasm.exports.sqlite3_wasm_kvvfs_methods()
|
||||
);
|
||||
delete capi.sqlite3_kvvfs_methods;
|
||||
const pKvvfs = capi.sqlite3_vfs_find("kvvfs");
|
||||
if( pKvvfs ){/* kvvfs-specific glue */
|
||||
if(util.isUIThread()){
|
||||
const kvvfsMethods = new capi.sqlite3_kvvfs_methods(
|
||||
wasm.exports.sqlite3_wasm_kvvfs_methods()
|
||||
);
|
||||
delete capi.sqlite3_kvvfs_methods;
|
||||
|
||||
const kvvfsMakeKey = wasm.exports.sqlite3_wasm_kvvfsMakeKeyOnPstack,
|
||||
pstack = wasm.pstack,
|
||||
pAllocRaw = wasm.exports.sqlite3_wasm_pstack_alloc;
|
||||
const kvvfsMakeKey = wasm.exports.sqlite3_wasm_kvvfsMakeKeyOnPstack,
|
||||
pstack = wasm.pstack,
|
||||
pAllocRaw = wasm.exports.sqlite3_wasm_pstack_alloc;
|
||||
|
||||
const kvvfsStorage = (zClass)=>
|
||||
((115/*=='s'*/===wasm.getMemValue(zClass))
|
||||
? sessionStorage : localStorage);
|
||||
|
||||
const kvvfsImpls = {
|
||||
xRead: (zClass, zKey, zBuf, nBuf)=>{
|
||||
const stack = pstack.pointer,
|
||||
astack = wasm.scopedAllocPush();
|
||||
try {
|
||||
const zXKey = kvvfsMakeKey(zClass,zKey);
|
||||
if(!zXKey) return -3/*OOM*/;
|
||||
const jKey = wasm.cstringToJs(zXKey);
|
||||
const jV = kvvfsStorage(zClass).getItem(jKey);
|
||||
if(!jV) return -1;
|
||||
const nV = jV.length /* Note that we are relying 100% on v being
|
||||
ASCII so that jV.length is equal to the
|
||||
C-string's byte length. */;
|
||||
if(nBuf<=0) return nV;
|
||||
else if(1===nBuf){
|
||||
wasm.setMemValue(zBuf, 0);
|
||||
return nV;
|
||||
const kvvfsStorage = (zClass)=>
|
||||
((115/*=='s'*/===wasm.getMemValue(zClass))
|
||||
? sessionStorage : localStorage);
|
||||
|
||||
const kvvfsImpls = {
|
||||
xRead: (zClass, zKey, zBuf, nBuf)=>{
|
||||
const stack = pstack.pointer,
|
||||
astack = wasm.scopedAllocPush();
|
||||
try {
|
||||
const zXKey = kvvfsMakeKey(zClass,zKey);
|
||||
if(!zXKey) return -3/*OOM*/;
|
||||
const jKey = wasm.cstringToJs(zXKey);
|
||||
const jV = kvvfsStorage(zClass).getItem(jKey);
|
||||
if(!jV) return -1;
|
||||
const nV = jV.length /* Note that we are relying 100% on v being
|
||||
ASCII so that jV.length is equal to the
|
||||
C-string's byte length. */;
|
||||
if(nBuf<=0) return nV;
|
||||
else if(1===nBuf){
|
||||
wasm.setMemValue(zBuf, 0);
|
||||
return nV;
|
||||
}
|
||||
const zV = wasm.scopedAllocCString(jV);
|
||||
if(nBuf > nV + 1) nBuf = nV + 1;
|
||||
wasm.heap8u().copyWithin(zBuf, zV, zV + nBuf - 1);
|
||||
wasm.setMemValue(zBuf + nBuf - 1, 0);
|
||||
return nBuf - 1;
|
||||
}catch(e){
|
||||
console.error("kvstorageRead()",e);
|
||||
return -2;
|
||||
}finally{
|
||||
pstack.restore(stack);
|
||||
wasm.scopedAllocPop(astack);
|
||||
}
|
||||
},
|
||||
xWrite: (zClass, zKey, zData)=>{
|
||||
const stack = pstack.pointer;
|
||||
try {
|
||||
const zXKey = kvvfsMakeKey(zClass,zKey);
|
||||
if(!zXKey) return 1/*OOM*/;
|
||||
const jKey = wasm.cstringToJs(zXKey);
|
||||
kvvfsStorage(zClass).setItem(jKey, wasm.cstringToJs(zData));
|
||||
return 0;
|
||||
}catch(e){
|
||||
console.error("kvstorageWrite()",e);
|
||||
return capi.SQLITE_IOERR;
|
||||
}finally{
|
||||
pstack.restore(stack);
|
||||
}
|
||||
},
|
||||
xDelete: (zClass, zKey)=>{
|
||||
const stack = pstack.pointer;
|
||||
try {
|
||||
const zXKey = kvvfsMakeKey(zClass,zKey);
|
||||
if(!zXKey) return 1/*OOM*/;
|
||||
kvvfsStorage(zClass).removeItem(wasm.cstringToJs(zXKey));
|
||||
return 0;
|
||||
}catch(e){
|
||||
console.error("kvstorageDelete()",e);
|
||||
return capi.SQLITE_IOERR;
|
||||
}finally{
|
||||
pstack.restore(stack);
|
||||
}
|
||||
const zV = wasm.scopedAllocCString(jV);
|
||||
if(nBuf > nV + 1) nBuf = nV + 1;
|
||||
wasm.heap8u().copyWithin(zBuf, zV, zV + nBuf - 1);
|
||||
wasm.setMemValue(zBuf + nBuf - 1, 0);
|
||||
return nBuf - 1;
|
||||
}catch(e){
|
||||
console.error("kvstorageRead()",e);
|
||||
return -2;
|
||||
}finally{
|
||||
pstack.restore(stack);
|
||||
wasm.scopedAllocPop(astack);
|
||||
}
|
||||
},
|
||||
xWrite: (zClass, zKey, zData)=>{
|
||||
const stack = pstack.pointer;
|
||||
try {
|
||||
const zXKey = kvvfsMakeKey(zClass,zKey);
|
||||
if(!zXKey) return 1/*OOM*/;
|
||||
const jKey = wasm.cstringToJs(zXKey);
|
||||
kvvfsStorage(zClass).setItem(jKey, wasm.cstringToJs(zData));
|
||||
return 0;
|
||||
}catch(e){
|
||||
console.error("kvstorageWrite()",e);
|
||||
return capi.SQLITE_IOERR;
|
||||
}finally{
|
||||
pstack.restore(stack);
|
||||
}
|
||||
},
|
||||
xDelete: (zClass, zKey)=>{
|
||||
const stack = pstack.pointer;
|
||||
try {
|
||||
const zXKey = kvvfsMakeKey(zClass,zKey);
|
||||
if(!zXKey) return 1/*OOM*/;
|
||||
kvvfsStorage(zClass).removeItem(wasm.cstringToJs(zXKey));
|
||||
return 0;
|
||||
}catch(e){
|
||||
console.error("kvstorageDelete()",e);
|
||||
return capi.SQLITE_IOERR;
|
||||
}finally{
|
||||
pstack.restore(stack);
|
||||
}
|
||||
}/*kvvfsImpls*/;
|
||||
for(let k of Object.keys(kvvfsImpls)){
|
||||
kvvfsMethods[kvvfsMethods.memberKey(k)] =
|
||||
wasm.installFunction(
|
||||
kvvfsMethods.memberSignature(k),
|
||||
kvvfsImpls[k]
|
||||
);
|
||||
}
|
||||
}/*kvvfsImpls*/;
|
||||
for(let k of Object.keys(kvvfsImpls)){
|
||||
kvvfsMethods[kvvfsMethods.memberKey(k)] =
|
||||
wasm.installFunction(
|
||||
kvvfsMethods.memberSignature(k),
|
||||
kvvfsImpls[k]
|
||||
);
|
||||
}else{
|
||||
/* Worker thread: unregister kvvfs to avoid it being used
|
||||
for anything other than local/sessionStorage. It "can"
|
||||
be used that way but it's not really intended to be. */
|
||||
capi.sqlite3_vfs_unregister(pKvvfs);
|
||||
}
|
||||
}/*kvvfs*/
|
||||
}/*pKvvfs*/
|
||||
|
||||
});
|
||||
|
Reference in New Issue
Block a user