diff options
author | stephan <stephan@noemail.net> | 2023-08-30 13:07:35 +0000 |
---|---|---|
committer | stephan <stephan@noemail.net> | 2023-08-30 13:07:35 +0000 |
commit | 24c32c2e390de4116ba9e768cff9bcd3ad4f5dc6 (patch) | |
tree | 9561e6297623c6a2afa457483632fdf06e42be5b /ext/wasm/api | |
parent | a910f3f1c5b8d2e131949719b2985ed3f17e6e1d (diff) | |
parent | e621556724c044aa09e7c4fdab4e8407df83d216 (diff) | |
download | sqlite-24c32c2e390de4116ba9e768cff9bcd3ad4f5dc6.tar.gz sqlite-24c32c2e390de4116ba9e768cff9bcd3ad4f5dc6.zip |
Add a JS implementation of Java's SQLTester.
FossilOrigin-Name: b530792a514d95c4e8f93cf2170d9fc4de367055fa1704fc171551c946024fa9
Diffstat (limited to 'ext/wasm/api')
-rw-r--r-- | ext/wasm/api/sqlite3-api-prologue.js | 36 | ||||
-rw-r--r-- | ext/wasm/api/sqlite3-wasm.c | 112 |
2 files changed, 148 insertions, 0 deletions
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js index 5abb13b99..ef1154f6b 100644 --- a/ext/wasm/api/sqlite3-api-prologue.js +++ b/ext/wasm/api/sqlite3-api-prologue.js @@ -1135,7 +1135,23 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( return 1===n ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof) : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof); + }, + + /** + Records the current pstack position, calls the given function, + passing it the sqlite3 object, then restores the pstack + regardless of whether the function throws. Returns the result + of the call or propagates an exception on error. + + Added in 3.44. + */ + call: function(f){ + const stackPos = wasm.pstack.pointer; + try{ return f(sqlite3) } finally{ + wasm.pstack.restore(stackPos); + } } + })/*wasm.pstack*/; Object.defineProperties(wasm.pstack, { /** @@ -1543,6 +1559,26 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap( } }; + /** + Converts SQL input from a variety of convenient formats + to plain strings. + + If v is a string, it is returned as-is. If it is-a Array, its + join("") result is returned. If is is a Uint8Array, Int8Array, + or ArrayBuffer, it is assumed to hold UTF-8-encoded text and is + decoded to a string. If it looks like a WASM pointer, + wasm.cstrToJs(sql) is returned. Else undefined is returned. + + Added in 3.44 + */ + capi.sqlite3_js_sql_to_string = (sql)=>{ + if('string' === typeof sql){ + return sql; + } + const x = flexibleString(v); + return x===v ? undefined : x; + } + if( util.isUIThread() ){ /* Features specific to the main window thread... */ diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c index ff15e3b4f..db77010d9 100644 --- a/ext/wasm/api/sqlite3-wasm.c +++ b/ext/wasm/api/sqlite3-wasm.c @@ -1801,6 +1801,118 @@ char * sqlite3_wasm_test_str_hello(int fail){ } return s; } + +/* +** For testing using SQLTester scripts. +** +** Return non-zero if string z matches glob pattern zGlob and zero if the +** pattern does not match. +** +** To repeat: +** +** zero == no match +** non-zero == match +** +** Globbing rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. +** +** [^...] Matches one character not in the enclosed list. +** +** '#' Matches any sequence of one or more digits with an +** optional + or - sign in front, or a hexadecimal +** literal of the form 0x... +*/ +static int sqlite3_wasm_SQLTester_strnotglob(const char *zGlob, const char *z){ + int c, c2; + int invert; + int seen; + typedef int (*recurse_f)(const char *,const char *); + static const recurse_f recurse = sqlite3_wasm_SQLTester_strnotglob; + + while( (c = (*(zGlob++)))!=0 ){ + if( c=='*' ){ + while( (c=(*(zGlob++))) == '*' || c=='?' ){ + if( c=='?' && (*(z++))==0 ) return 0; + } + if( c==0 ){ + return 1; + }else if( c=='[' ){ + while( *z && recurse(zGlob-1,z)==0 ){ + z++; + } + return (*z)!=0; + } + while( (c2 = (*(z++)))!=0 ){ + while( c2!=c ){ + c2 = *(z++); + if( c2==0 ) return 0; + } + if( recurse(zGlob,z) ) return 1; + } + return 0; + }else if( c=='?' ){ + if( (*(z++))==0 ) return 0; + }else if( c=='[' ){ + int prior_c = 0; + seen = 0; + invert = 0; + c = *(z++); + if( c==0 ) return 0; + c2 = *(zGlob++); + if( c2=='^' ){ + invert = 1; + c2 = *(zGlob++); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = *(zGlob++); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ + c2 = *(zGlob++); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = *(zGlob++); + } + if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='#' ){ + if( z[0]=='0' + && (z[1]=='x' || z[1]=='X') + && sqlite3Isxdigit(z[2]) + ){ + z += 3; + while( sqlite3Isxdigit(z[0]) ){ z++; } + }else{ + if( (z[0]=='-' || z[0]=='+') && sqlite3Isdigit(z[1]) ) z++; + if( !sqlite3Isdigit(z[0]) ) return 0; + z++; + while( sqlite3Isdigit(z[0]) ){ z++; } + } + }else{ + if( c!=(*(z++)) ) return 0; + } + } + return *z==0; +} + +SQLITE_WASM_EXPORT +int sqlite3_wasm_SQLTester_strglob(const char *zGlob, const char *z){ + return !sqlite3_wasm_SQLTester_strnotglob(zGlob, z); +} + + #endif /* SQLITE_WASM_TESTS */ #undef SQLITE_WASM_EXPORT |