mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Remove some unused sqlite3_status() codes from the JS API. Add custom JS wrappers for sqlite3_create_collation/_v2() which accept JS functions (plus tests). Expand the argument options for sqlite3_wasm_db_error() to enable it to translate exception objects to C-level errors.
FossilOrigin-Name: 073a2f1eb006230ae0995a5ea6c789407bcaa819ec15b5064c66d8973ed4671a
This commit is contained in:
@ -158,9 +158,35 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
delete wasm.bindingSignatures;
|
||||
|
||||
if(wasm.exports.sqlite3_wasm_db_error){
|
||||
util.sqlite3_wasm_db_error = wasm.xWrap(
|
||||
const __db_err = wasm.xWrap(
|
||||
'sqlite3_wasm_db_error', 'int', 'sqlite3*', 'int', 'string'
|
||||
);
|
||||
/**
|
||||
Sets the given db's error state. Accepts:
|
||||
|
||||
- (sqlite3*, int code, string msg)
|
||||
- (sqlite3*, Error [,string msg])
|
||||
|
||||
If passed a WasmAllocError, the message is ingored and the
|
||||
result code is SQLITE_NOMEM. If passed any other Error type,
|
||||
the result code defaults to SQLITE_ERROR unless the Error
|
||||
object has a resultCode property, in which case that is used
|
||||
(e.g. SQLite3Error has that). If passed a non-WasmAllocError
|
||||
exception, the message string defaults to theError.message.
|
||||
|
||||
Returns the resulting code. Pass (pDb,0,0) to clear the error
|
||||
state.
|
||||
*/
|
||||
util.sqlite3_wasm_db_error = function(pDb, resultCode, message){
|
||||
if(resultCode instanceof sqlite3.WasmAllocError){
|
||||
resultCode = capi.SQLITE_NOMEM;
|
||||
message = 0 /*avoid allocating message string*/;
|
||||
}else if(resultCode instanceof Error){
|
||||
message = message || resultCode.message;
|
||||
resultCode = (resultCode.resultCode || capi.SQLITE_ERROR);
|
||||
}
|
||||
return __db_err(pDb, resultCode, message);
|
||||
};
|
||||
}else{
|
||||
util.sqlite3_wasm_db_error = function(pDb,errCode,msg){
|
||||
console.warn("sqlite3_wasm_db_error() is not exported.",arguments);
|
||||
@ -180,6 +206,61 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
(1===n?"":'s')+".");
|
||||
};
|
||||
|
||||
if(1){/* Bindings for sqlite3_create_collation() */
|
||||
|
||||
const __ccv2 = wasm.xWrap(
|
||||
'sqlite3_create_collation_v2', 'int',
|
||||
'sqlite3*','string','int','*','*','*'
|
||||
/* int(*xCompare)(void*,int,const void*,int,const void*) */
|
||||
/* void(*xDestroy(void*) */);
|
||||
|
||||
/**
|
||||
Works exactly like C's sqlite3_create_collation_v2() except that:
|
||||
|
||||
1) It permits its two function arguments to be JS functions,
|
||||
for which it will install WASM-bound proxies.
|
||||
|
||||
2) It returns capi.SQLITE_FORMAT if the 3rd argument is not
|
||||
capi.SQLITE_UTF8. No other encodings are supported.
|
||||
|
||||
Returns 0 on success, non-0 on error, in which case the error
|
||||
state of pDb (of type `sqlite3*` or argument-convertible to it)
|
||||
may contain more information.
|
||||
*/
|
||||
capi.sqlite3_create_collation_v2 = function(pDb,zName,eTextRep,pArg,xCompare,xDestroy){
|
||||
if(6!==arguments.length) return __dbArgcMismatch(pDb, 'sqlite3_create_collation_v2', 6);
|
||||
else if(capi.SQLITE_UTF8!==eTextRep){
|
||||
return util.sqlite3_wasm_db_error(
|
||||
pDb, capi.SQLITE_FORMAT, "SQLITE_UTF8 is the only supported encoding."
|
||||
);
|
||||
}
|
||||
let rc, pfCompare, pfDestroy;
|
||||
try{
|
||||
if(xCompare instanceof Function){
|
||||
pfCompare = wasm.installFunction(xCompare, 'i(pipip)');
|
||||
}
|
||||
if(xDestroy instanceof Function){
|
||||
pfDestroy = wasm.installFunction(xDestroy, 'v(p)');
|
||||
}
|
||||
rc = __ccv2(pDb, zName, eTextRep, pArg,
|
||||
pfCompare || xCompare, pfDestroy || xDestroy);
|
||||
}catch(e){
|
||||
if(pfCompare) wasm.uninstallFunction(pfCompare);
|
||||
if(pfDestroy) wasm.uninstallFunction(pfDestroy);
|
||||
rc = util.sqlite3_wasm_db_error(pDb, e);
|
||||
}
|
||||
return rc;
|
||||
};
|
||||
|
||||
capi.sqlite3_create_collation = (pDb,zName,eTextRep,pArg,xCompare)=>{
|
||||
return (5===arguments.length)
|
||||
? capi.sqlite3_create_collation_v2(pDb,zName,eTextRep,pArg,xCompare,0)
|
||||
: __dbArgcMismatch(pDb, 'sqlite3_create_collation', 5);
|
||||
}
|
||||
|
||||
|
||||
}/*sqlite3_create_collation() and friends*/
|
||||
|
||||
if(1){/* Special-case handling of sqlite3_exec() */
|
||||
const __exec = wasm.xWrap("sqlite3_exec", "int",
|
||||
["sqlite3*", "string:flexible", "*", "*", "**"]);
|
||||
|
@ -936,12 +936,16 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
/* sqlite3_create_function(), sqlite3_create_function_v2(), and
|
||||
sqlite3_create_window_function() use hand-written bindings to
|
||||
simplify handling of their function-type arguments. */
|
||||
["sqlite3_create_collation", "int",
|
||||
"sqlite3*", "string", "int"/*SQLITE_UTF8 is the only legal value*/,
|
||||
/* sqlite3_create_collation() and sqlite3_create_collation_v2()
|
||||
use hand-written bindings to simplify passing of the callback
|
||||
function.
|
||||
["sqlite3_create_collation", "int",
|
||||
"sqlite3*", "string", "int",//SQLITE_UTF8 is the only legal value
|
||||
"*", "*"],
|
||||
["sqlite3_create_collation_v2", "int",
|
||||
"sqlite3*", "string", "int"/*SQLITE_UTF8 is the only legal value*/,
|
||||
"sqlite3*", "string", "int",//SQLITE_UTF8 is the only legal value
|
||||
"*", "*", "*"],
|
||||
*/
|
||||
["sqlite3_data_count", "int", "sqlite3_stmt*"],
|
||||
["sqlite3_db_filename", "string", "sqlite3*", "string"],
|
||||
["sqlite3_db_handle", "sqlite3*", "sqlite3_stmt*"],
|
||||
|
@ -706,12 +706,12 @@ const char * sqlite3_wasm_enum_json(void){
|
||||
DefInt(SQLITE_STATUS_MEMORY_USED);
|
||||
DefInt(SQLITE_STATUS_PAGECACHE_USED);
|
||||
DefInt(SQLITE_STATUS_PAGECACHE_OVERFLOW);
|
||||
DefInt(SQLITE_STATUS_SCRATCH_USED) /* NOT USED */;
|
||||
DefInt(SQLITE_STATUS_SCRATCH_OVERFLOW) /* NOT USED */;
|
||||
//DefInt(SQLITE_STATUS_SCRATCH_USED) /* NOT USED */;
|
||||
//DefInt(SQLITE_STATUS_SCRATCH_OVERFLOW) /* NOT USED */;
|
||||
DefInt(SQLITE_STATUS_MALLOC_SIZE);
|
||||
DefInt(SQLITE_STATUS_PARSER_STACK);
|
||||
DefInt(SQLITE_STATUS_PAGECACHE_SIZE);
|
||||
DefInt(SQLITE_STATUS_SCRATCH_SIZE) /* NOT USED */;
|
||||
//DefInt(SQLITE_STATUS_SCRATCH_SIZE) /* NOT USED */;
|
||||
DefInt(SQLITE_STATUS_MALLOC_COUNT);
|
||||
} _DefGroup;
|
||||
|
||||
|
@ -2106,6 +2106,29 @@ self.sqlite3InitModule = sqlite3InitModule;
|
||||
.assert(2000===list[0][1]);
|
||||
}
|
||||
})/*custom vtab #2*/
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
.t('Custom collation', function(sqlite3){
|
||||
let myCmp = function(pArg,n1,p1,n2,p2){
|
||||
//int (*)(void*,int,const void*,int,const void*)
|
||||
const rc = wasm.exports.sqlite3_strnicmp(p1,p2,(n1<n2?n1:n2));
|
||||
return rc ? rc : (n1 - n2);
|
||||
};
|
||||
let rc = capi.sqlite3_create_collation_v2(this.db, "mycollation", capi.SQLITE_UTF8,
|
||||
0, myCmp, 0);
|
||||
this.db.checkRc(rc);
|
||||
rc = this.db.selectValue("select 'hi' = 'HI' collate mycollation");
|
||||
T.assert(1===rc);
|
||||
rc = this.db.selectValue("select 'hii' = 'HI' collate mycollation");
|
||||
T.assert(0===rc);
|
||||
rc = this.db.selectValue("select 'hi' = 'HIi' collate mycollation");
|
||||
T.assert(0===rc);
|
||||
rc = capi.sqlite3_create_collation(this.db,"hi",capi.SQLITE_UTF8/*not enough args*/);
|
||||
T.assert(capi.SQLITE_MISUSE === rc);
|
||||
rc = capi.sqlite3_create_collation_v2(this.db,"hi",0/*wrong encoding*/,0,0,0);
|
||||
T.assert(capi.SQLITE_FORMAT === rc)
|
||||
.mustThrowMatching(()=>this.db.checkRc(rc),
|
||||
/SQLITE_UTF8 is the only supported encoding./);
|
||||
})
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
.t('Close db', function(){
|
||||
|
Reference in New Issue
Block a user