aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorstephan <stephan@noemail.net>2022-12-09 12:12:49 +0000
committerstephan <stephan@noemail.net>2022-12-09 12:12:49 +0000
commit3ec44736b51d1f8ed7239654e1ee891e93fd7577 (patch)
treec3a0b2e954bfe3565ec52cfb5474445be95b906e /ext
parent81a368317456d9c1500e33949b214185e1e0b565 (diff)
downloadsqlite-3ec44736b51d1f8ed7239654e1ee891e93fd7577.tar.gz
sqlite-3ec44736b51d1f8ed7239654e1ee891e93fd7577.zip
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
Diffstat (limited to 'ext')
-rw-r--r--ext/wasm/api/sqlite3-api-glue.js83
-rw-r--r--ext/wasm/api/sqlite3-api-prologue.js10
-rw-r--r--ext/wasm/api/sqlite3-wasm.c6
-rw-r--r--ext/wasm/tester1.c-pp.js23
4 files changed, 115 insertions, 7 deletions
diff --git a/ext/wasm/api/sqlite3-api-glue.js b/ext/wasm/api/sqlite3-api-glue.js
index 80438e086..6d9d45cda 100644
--- a/ext/wasm/api/sqlite3-api-glue.js
+++ b/ext/wasm/api/sqlite3-api-glue.js
@@ -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", "*", "*", "**"]);
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js
index 22dd55e76..136d050c9 100644
--- a/ext/wasm/api/sqlite3-api-prologue.js
+++ b/ext/wasm/api/sqlite3-api-prologue.js
@@ -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*"],
diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c
index ec0f72f73..dbed1b684 100644
--- a/ext/wasm/api/sqlite3-wasm.c
+++ b/ext/wasm/api/sqlite3-wasm.c
@@ -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;
diff --git a/ext/wasm/tester1.c-pp.js b/ext/wasm/tester1.c-pp.js
index ddf60def9..1dc58983f 100644
--- a/ext/wasm/tester1.c-pp.js
+++ b/ext/wasm/tester1.c-pp.js
@@ -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(){