mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Add a JS implementation of Java's SQLTester.
FossilOrigin-Name: b530792a514d95c4e8f93cf2170d9fc4de367055fa1704fc171551c946024fa9
This commit is contained in:
@ -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... */
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user