mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
JS SQLTestRunner can now run the Java impl's core-most sanity tests, missing only support for directives.
FossilOrigin-Name: 5e798369375ce1b0c9cdf831f835d931fbd562ff7b4db09a06d1bdca2ac1b975
This commit is contained in:
@ -181,7 +181,7 @@ public class SQLTester {
|
|||||||
private int nTestFile = 0;
|
private int nTestFile = 0;
|
||||||
//! Number of scripts which were aborted.
|
//! Number of scripts which were aborted.
|
||||||
private int nAbortedScript = 0;
|
private int nAbortedScript = 0;
|
||||||
//! Per-script test counter.
|
//! Incremented by test case handlers
|
||||||
private int nTest = 0;
|
private int nTest = 0;
|
||||||
//! True to enable column name output from execSql()
|
//! True to enable column name output from execSql()
|
||||||
private boolean emitColNames;
|
private boolean emitColNames;
|
||||||
@ -582,6 +582,10 @@ public class SQLTester {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}finally{
|
}finally{
|
||||||
|
sqlite3_reset(stmt
|
||||||
|
/* In order to trigger an exception in the
|
||||||
|
INSERT...RETURNING locking scenario:
|
||||||
|
https://sqlite.org/forum/forumpost/36f7a2e7494897df */);
|
||||||
sqlite3_finalize(stmt);
|
sqlite3_finalize(stmt);
|
||||||
}
|
}
|
||||||
if( 0!=rc && throwOnError ){
|
if( 0!=rc && throwOnError ){
|
||||||
@ -926,8 +930,8 @@ class RunCommand extends Command {
|
|||||||
final sqlite3 db = (1==argv.length)
|
final sqlite3 db = (1==argv.length)
|
||||||
? t.getCurrentDb() : t.getDbById( Integer.parseInt(argv[1]) );
|
? t.getCurrentDb() : t.getDbById( Integer.parseInt(argv[1]) );
|
||||||
final String sql = t.takeInputBuffer();
|
final String sql = t.takeInputBuffer();
|
||||||
int rc = t.execSql(db, false, ResultBufferMode.NONE,
|
final int rc = t.execSql(db, false, ResultBufferMode.NONE,
|
||||||
ResultRowMode.ONELINE, sql);
|
ResultRowMode.ONELINE, sql);
|
||||||
if( 0!=rc && t.isVerbose() ){
|
if( 0!=rc && t.isVerbose() ){
|
||||||
String msg = sqlite3_errmsg(db);
|
String msg = sqlite3_errmsg(db);
|
||||||
ts.verbose1(argv[0]," non-fatal command error #",rc,": ",
|
ts.verbose1(argv[0]," non-fatal command error #",rc,": ",
|
||||||
@ -950,8 +954,7 @@ class TableResultCommand extends Command {
|
|||||||
if( !body.endsWith("\n--end") ){
|
if( !body.endsWith("\n--end") ){
|
||||||
ts.toss(argv[0], " must be terminated with --end.");
|
ts.toss(argv[0], " must be terminated with --end.");
|
||||||
}else{
|
}else{
|
||||||
int n = body.length();
|
body = body.substring(0, body.length()-6);
|
||||||
body = body.substring(0, n-6);
|
|
||||||
}
|
}
|
||||||
final String[] globs = body.split("\\s*\\n\\s*");
|
final String[] globs = body.split("\\s*\\n\\s*");
|
||||||
if( globs.length < 1 ){
|
if( globs.length < 1 ){
|
||||||
@ -1240,14 +1243,15 @@ class TestScript {
|
|||||||
final int oldPB = cur.putbackPos;
|
final int oldPB = cur.putbackPos;
|
||||||
final int oldPBL = cur.putbackLineNo;
|
final int oldPBL = cur.putbackLineNo;
|
||||||
final int oldLine = cur.lineNo;
|
final int oldLine = cur.lineNo;
|
||||||
final String rc = getLine();
|
try{ return getLine(); }
|
||||||
cur.peekedPos = cur.pos;
|
finally{
|
||||||
cur.peekedLineNo = cur.lineNo;
|
cur.peekedPos = cur.pos;
|
||||||
cur.pos = oldPos;
|
cur.peekedLineNo = cur.lineNo;
|
||||||
cur.lineNo = oldLine;
|
cur.pos = oldPos;
|
||||||
cur.putbackPos = oldPB;
|
cur.lineNo = oldLine;
|
||||||
cur.putbackLineNo = oldPBL;
|
cur.putbackPos = oldPB;
|
||||||
return rc;
|
cur.putbackLineNo = oldPBL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1374,11 +1378,10 @@ class TestScript {
|
|||||||
String line;
|
String line;
|
||||||
while( (null != (line = peekLine())) ){
|
while( (null != (line = peekLine())) ){
|
||||||
checkForDirective(tester, line);
|
checkForDirective(tester, line);
|
||||||
if( !isCommandLine(line, true) ){
|
if( isCommandLine(line, true) ) break;
|
||||||
|
else {
|
||||||
sb.append(line).append("\n");
|
sb.append(line).append("\n");
|
||||||
consumePeeked();
|
consumePeeked();
|
||||||
}else{
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line = sb.toString();
|
line = sb.toString();
|
||||||
|
@ -73,7 +73,7 @@ class DbException extends SQLTesterException {
|
|||||||
|
|
||||||
class TestScriptFailed extends SQLTesterException {
|
class TestScriptFailed extends SQLTesterException {
|
||||||
constructor(testScript, ...args){
|
constructor(testScript, ...args){
|
||||||
super(testScript.getPutputPrefix(),': ',...args);
|
super(testScript.getOutputPrefix(),': ',...args);
|
||||||
}
|
}
|
||||||
isFatal() { return true; }
|
isFatal() { return true; }
|
||||||
}
|
}
|
||||||
@ -103,6 +103,18 @@ const __utf8Encoder = new TextEncoder('utf-8');
|
|||||||
const __SAB = ('undefined'===typeof globalThis.SharedArrayBuffer)
|
const __SAB = ('undefined'===typeof globalThis.SharedArrayBuffer)
|
||||||
? function(){} : globalThis.SharedArrayBuffer;
|
? function(){} : globalThis.SharedArrayBuffer;
|
||||||
|
|
||||||
|
|
||||||
|
const Rx = newObj({
|
||||||
|
requiredProperties: / REQUIRED_PROPERTIES:[ \t]*(\S.*)\s*$/,
|
||||||
|
scriptModuleName: / SCRIPT_MODULE_NAME:[ \t]*(\S+)\s*$/,
|
||||||
|
mixedModuleName: / ((MIXED_)?MODULE_NAME):[ \t]*(\S+)\s*$/,
|
||||||
|
command: /^--(([a-z-]+)( .*)?)$/,
|
||||||
|
//! "Special" characters - we have to escape output if it contains any.
|
||||||
|
special: /[\x00-\x20\x22\x5c\x7b\x7d]/,
|
||||||
|
//! Either of '{' or '}'.
|
||||||
|
squiggly: /[{}]/
|
||||||
|
});
|
||||||
|
|
||||||
const Util = newObj({
|
const Util = newObj({
|
||||||
toss,
|
toss,
|
||||||
|
|
||||||
@ -110,7 +122,11 @@ const Util = newObj({
|
|||||||
return 0==sqlite3.wasm.sqlite3_wasm_vfs_unlink(0,fn);
|
return 0==sqlite3.wasm.sqlite3_wasm_vfs_unlink(0,fn);
|
||||||
},
|
},
|
||||||
|
|
||||||
argvToString: (list)=>list.join(" "),
|
argvToString: (list)=>{
|
||||||
|
const m = [...list];
|
||||||
|
m.shift();
|
||||||
|
return m.join(" ")
|
||||||
|
},
|
||||||
|
|
||||||
utf8Decode: function(arrayBuffer, begin, end){
|
utf8Decode: function(arrayBuffer, begin, end){
|
||||||
return __utf8Decoder.decode(
|
return __utf8Decoder.decode(
|
||||||
@ -120,7 +136,10 @@ const Util = newObj({
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
utf8Encode: (str)=>__utf8Encoder.encode(str)
|
utf8Encode: (str)=>__utf8Encoder.encode(str),
|
||||||
|
|
||||||
|
strglob: sqlite3.wasm.xWrap('sqlite3_wasm_SQLTester_strglob','int',
|
||||||
|
['string','string'])
|
||||||
})/*Util*/;
|
})/*Util*/;
|
||||||
|
|
||||||
class Outer {
|
class Outer {
|
||||||
@ -182,21 +201,39 @@ class Outer {
|
|||||||
|
|
||||||
class SQLTester {
|
class SQLTester {
|
||||||
|
|
||||||
|
//! Console output utility.
|
||||||
#outer = new Outer().outputPrefix( ()=>'SQLTester: ' );
|
#outer = new Outer().outputPrefix( ()=>'SQLTester: ' );
|
||||||
|
//! List of input script files.
|
||||||
#aFiles = [];
|
#aFiles = [];
|
||||||
|
//! Test input buffer.
|
||||||
#inputBuffer = [];
|
#inputBuffer = [];
|
||||||
|
//! Test result buffer.
|
||||||
#resultBuffer = [];
|
#resultBuffer = [];
|
||||||
|
//! Output representation of SQL NULL.
|
||||||
#nullView = "nil";
|
#nullView = "nil";
|
||||||
#metrics = newObj({
|
metrics = newObj({
|
||||||
nTotalTest: 0, nTestFile: 0, nAbortedScript: 0
|
//! Total tests run
|
||||||
|
nTotalTest: 0,
|
||||||
|
//! Total test script files run
|
||||||
|
nTestFile: 0,
|
||||||
|
//! Number of scripts which were aborted
|
||||||
|
nAbortedScript: 0,
|
||||||
|
//! Incremented by test case handlers
|
||||||
|
nTest: 0
|
||||||
});
|
});
|
||||||
#emitColNames = false;
|
#emitColNames = false;
|
||||||
|
//! True to keep going regardless of how a test fails.
|
||||||
#keepGoing = false;
|
#keepGoing = false;
|
||||||
#db = newObj({
|
#db = newObj({
|
||||||
|
//! The list of available db handles.
|
||||||
list: new Array(7),
|
list: new Array(7),
|
||||||
|
//! Index into this.list of the current db.
|
||||||
iCurrentDb: 0,
|
iCurrentDb: 0,
|
||||||
|
//! Name of the default db, re-created for each script.
|
||||||
initialDbName: "test.db",
|
initialDbName: "test.db",
|
||||||
|
//! Buffer for REQUIRED_PROPERTIES pragmas.
|
||||||
initSql: ['select 1;'],
|
initSql: ['select 1;'],
|
||||||
|
//! (sqlite3*) to the current db.
|
||||||
currentDb: function(){
|
currentDb: function(){
|
||||||
return this.list[this.iCurrentDb];
|
return this.list[this.iCurrentDb];
|
||||||
}
|
}
|
||||||
@ -208,12 +245,17 @@ class SQLTester {
|
|||||||
outln(...args){ return this.#outer.outln(...args); }
|
outln(...args){ return this.#outer.outln(...args); }
|
||||||
out(...args){ return this.#outer.out(...args); }
|
out(...args){ return this.#outer.out(...args); }
|
||||||
|
|
||||||
|
incrementTestCounter(){
|
||||||
|
++this.metrics.nTotalTest;
|
||||||
|
++this.metrics.nTest;
|
||||||
|
}
|
||||||
|
|
||||||
reset(){
|
reset(){
|
||||||
this.clearInputBuffer();
|
this.clearInputBuffer();
|
||||||
this.clearResultBuffer();
|
this.clearResultBuffer();
|
||||||
this.#clearBuffer(this.#db.initSql);
|
this.#clearBuffer(this.#db.initSql);
|
||||||
this.closeAllDbs();
|
this.closeAllDbs();
|
||||||
this.nTest = 0;
|
this.metrics.nTest = 0;
|
||||||
this.nullView = "nil";
|
this.nullView = "nil";
|
||||||
this.emitColNames = false;
|
this.emitColNames = false;
|
||||||
this.#db.iCurrentDb = 0;
|
this.#db.iCurrentDb = 0;
|
||||||
@ -365,7 +407,7 @@ class SQLTester {
|
|||||||
Util.unlink(this.#db.initialDbName);
|
Util.unlink(this.#db.initialDbName);
|
||||||
this.openDb(0, this.#db.initialDbName, true);
|
this.openDb(0, this.#db.initialDbName, true);
|
||||||
}else{
|
}else{
|
||||||
this.#outer.outln("WARNING: setupInitialDb() unexpectedly ",
|
this.#outer.outln("WARNING: setupInitialDb() was unexpectedly ",
|
||||||
"triggered while it is opened.");
|
"triggered while it is opened.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,17 +447,107 @@ class SQLTester {
|
|||||||
#appendDbErr(pDb, sb, rc){
|
#appendDbErr(pDb, sb, rc){
|
||||||
sb.push(sqlite3.capi.sqlite3_js_rc_str(rc), ' ');
|
sb.push(sqlite3.capi.sqlite3_js_rc_str(rc), ' ');
|
||||||
const msg = this.#escapeSqlValue(sqlite3.capi.sqlite3_errmsg(pDb));
|
const msg = this.#escapeSqlValue(sqlite3.capi.sqlite3_errmsg(pDb));
|
||||||
if( '{' == msg.charAt(0) ){
|
if( '{' === msg.charAt(0) ){
|
||||||
sb.push(msg);
|
sb.push(msg);
|
||||||
}else{
|
}else{
|
||||||
sb.push('{', msg, '}');
|
sb.push('{', msg, '}');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#checkDbRc(pDb,rc){
|
||||||
|
sqlite3.oo1.DB.checkRc(pDb, rc);
|
||||||
|
}
|
||||||
|
|
||||||
execSql(pDb, throwOnError, appendMode, lineMode, sql){
|
execSql(pDb, throwOnError, appendMode, lineMode, sql){
|
||||||
sql = sqlite3.capi.sqlite3_js_sql_to_string(sql);
|
if( !pDb && !this.#db.list[0] ){
|
||||||
this.#outer.outln("execSql() is TODO. ",sql);
|
this.#setupInitialDb();
|
||||||
return 0;
|
}
|
||||||
|
if( !pDb ) pDb = this.#db.currentDb();
|
||||||
|
const wasm = sqlite3.wasm, capi = sqlite3.capi;
|
||||||
|
sql = (sql instanceof Uint8Array)
|
||||||
|
? sql
|
||||||
|
: new TextEncoder("utf-8").encode(capi.sqlite3_js_sql_to_string(sql));
|
||||||
|
const self = this;
|
||||||
|
const sb = (ResultBufferMode.NONE===appendMode) ? null : this.#resultBuffer;
|
||||||
|
let rc = 0;
|
||||||
|
wasm.scopedAllocCall(function(){
|
||||||
|
let sqlByteLen = sql.byteLength;
|
||||||
|
const ppStmt = wasm.scopedAlloc(
|
||||||
|
/* output (sqlite3_stmt**) arg and pzTail */
|
||||||
|
(2 * wasm.ptrSizeof) + (sqlByteLen + 1/* SQL + NUL */)
|
||||||
|
);
|
||||||
|
const pzTail = ppStmt + wasm.ptrSizeof /* final arg to sqlite3_prepare_v2() */;
|
||||||
|
let pSql = pzTail + wasm.ptrSizeof;
|
||||||
|
const pSqlEnd = pSql + sqlByteLen;
|
||||||
|
wasm.heap8().set(sql, pSql);
|
||||||
|
wasm.poke8(pSql + sqlByteLen, 0/*NUL terminator*/);
|
||||||
|
let pos = 0, n = 1, spacing = 0;
|
||||||
|
while( pSql && wasm.peek8(pSql) ){
|
||||||
|
wasm.pokePtr([ppStmt, pzTail], 0);
|
||||||
|
rc = capi.sqlite3_prepare_v3(
|
||||||
|
pDb, pSql, sqlByteLen, 0, ppStmt, pzTail
|
||||||
|
);
|
||||||
|
if( 0!==rc ){
|
||||||
|
if(throwOnError){
|
||||||
|
throw new DbException(pDb, rc);
|
||||||
|
}else if( sb ){
|
||||||
|
self.#appendDbErr(db, sb, rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const pStmt = wasm.peekPtr(ppStmt);
|
||||||
|
pSql = wasm.peekPtr(pzTail);
|
||||||
|
sqlByteLen = pSqlEnd - pSql;
|
||||||
|
if(!pStmt) continue /* only whitespace or comments */;
|
||||||
|
if( sb ){
|
||||||
|
const nCol = capi.sqlite3_column_count(pStmt);
|
||||||
|
let colName, val;
|
||||||
|
while( capi.SQLITE_ROW === (rc = capi.sqlite3_step(pStmt)) ) {
|
||||||
|
for( let i=0; i < nCol; ++i ){
|
||||||
|
if( spacing++ > 0 ) sb.push(' ');
|
||||||
|
if( self.#emitColNames ){
|
||||||
|
colName = capi.sqlite3_column_name(pStmt, i);
|
||||||
|
switch(appendMode){
|
||||||
|
case ResultBufferMode.ASIS: sb.push( colName ); break;
|
||||||
|
case ResultBufferMode.ESCAPED:
|
||||||
|
sb.push( self.#escapeSqlValue(colName) );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
self.toss("Unhandled ResultBufferMode.");
|
||||||
|
}
|
||||||
|
sb.push(' ');
|
||||||
|
}
|
||||||
|
val = capi.sqlite3_column_text(pStmt, i);
|
||||||
|
if( null===val ){
|
||||||
|
sb.push( self.#nullView );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch(appendMode){
|
||||||
|
case ResultBufferMode.ASIS: sb.push( val ); break;
|
||||||
|
case ResultBufferMode.ESCAPED:
|
||||||
|
sb.push( self.#escapeSqlValue(val) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}/* column loop */
|
||||||
|
}/* row loop */
|
||||||
|
if( ResultRowMode.NEWLINE === lineMode ){
|
||||||
|
spacing = 0;
|
||||||
|
sb.push('\n');
|
||||||
|
}
|
||||||
|
}else{ // no output but possibly other side effects
|
||||||
|
while( capi.SQLITE_ROW === (rc = capi.sqlite3_step(pStmt)) ) {}
|
||||||
|
}
|
||||||
|
capi.sqlite3_finalize(pStmt);
|
||||||
|
if( capi.SQLITE_ROW===rc || capi.SQLITE_DONE===rc) rc = 0;
|
||||||
|
else if( rc!=0 ){
|
||||||
|
if( sb ){
|
||||||
|
self.#appendDbErr(db, sb, rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}/* SQL script loop */;
|
||||||
|
})/*scopedAllocCall()*/;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
}/*SQLTester*/
|
}/*SQLTester*/
|
||||||
@ -469,17 +601,6 @@ class Cursor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Rx = newObj({
|
|
||||||
requiredProperties: / REQUIRED_PROPERTIES:[ \t]*(\S.*)\s*$/,
|
|
||||||
scriptModuleName: / SCRIPT_MODULE_NAME:[ \t]*(\S+)\s*$/,
|
|
||||||
mixedModuleName: / ((MIXED_)?MODULE_NAME):[ \t]*(\S+)\s*$/,
|
|
||||||
command: /^--(([a-z-]+)( .*)?)$/,
|
|
||||||
//! "Special" characters - we have to escape output if it contains any.
|
|
||||||
special: /[\x00-\x20\x22\x5c\x7b\x7d]/,
|
|
||||||
//! Either of '{' or '}'.
|
|
||||||
squiggly: /[{}]/
|
|
||||||
});
|
|
||||||
|
|
||||||
class TestScript {
|
class TestScript {
|
||||||
#cursor = new Cursor();
|
#cursor = new Cursor();
|
||||||
#moduleName = null;
|
#moduleName = null;
|
||||||
@ -529,6 +650,28 @@ class TestScript {
|
|||||||
return m ? m[1].trim().split(/\s+/) : null;
|
return m ? m[1].trim().split(/\s+/) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#isCommandLine(line, checkForImpl){
|
||||||
|
let m = Rx.command.exec(line);
|
||||||
|
if( m && checkForImpl ){
|
||||||
|
m = !!CommandDispatcher.getCommandByName(m[2]);
|
||||||
|
}
|
||||||
|
return !!m;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchCommandBody(tester){
|
||||||
|
const sb = [];
|
||||||
|
let line;
|
||||||
|
while( (null !== (line = this.peekLine())) ){
|
||||||
|
this.#checkForDirective(tester, line);
|
||||||
|
if( this.#isCommandLine(line, true) ) break;
|
||||||
|
sb.push(line,"\n");
|
||||||
|
this.consumePeeked();
|
||||||
|
}
|
||||||
|
line = sb.join('');
|
||||||
|
return !!line.trim() ? line : null;
|
||||||
|
}
|
||||||
|
|
||||||
run(tester){
|
run(tester){
|
||||||
this.reset();
|
this.reset();
|
||||||
this.#outer.verbosity(tester.verbosity());
|
this.#outer.verbosity(tester.verbosity());
|
||||||
@ -621,14 +764,16 @@ class TestScript {
|
|||||||
const oldPB = cur.putbackPos;
|
const oldPB = cur.putbackPos;
|
||||||
const oldPBL = cur.putbackLineNo;
|
const oldPBL = cur.putbackLineNo;
|
||||||
const oldLine = cur.lineNo;
|
const oldLine = cur.lineNo;
|
||||||
const rc = this.getLine();
|
try {
|
||||||
cur.peekedPos = cur.pos;
|
return this.getLine();
|
||||||
cur.peekedLineNo = cur.lineNo;
|
}finally{
|
||||||
cur.pos = oldPos;
|
cur.peekedPos = cur.pos;
|
||||||
cur.lineNo = oldLine;
|
cur.peekedLineNo = cur.lineNo;
|
||||||
cur.putbackPos = oldPB;
|
cur.pos = oldPos;
|
||||||
cur.putbackLineNo = oldPBL;
|
cur.lineNo = oldLine;
|
||||||
return rc;
|
cur.putbackPos = oldPB;
|
||||||
|
cur.putbackLineNo = oldPBL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -667,7 +812,7 @@ class CloseDbCommand extends Command {
|
|||||||
let id;
|
let id;
|
||||||
if(argv.length>1){
|
if(argv.length>1){
|
||||||
const arg = argv[1];
|
const arg = argv[1];
|
||||||
if("all".equals(arg)){
|
if( "all" === arg ){
|
||||||
t.closeAllDbs();
|
t.closeAllDbs();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -697,6 +842,36 @@ class DbCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! --glob command
|
||||||
|
class GlobCommand extends Command {
|
||||||
|
#negate = false;
|
||||||
|
constructor(negate=false){
|
||||||
|
super();
|
||||||
|
this.#negate = negate;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(t, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,1,-1);
|
||||||
|
t.incrementTestCounter();
|
||||||
|
const sql = t.takeInputBuffer();
|
||||||
|
let rc = t.execSql(null, true, ResultBufferMode.ESCAPED,
|
||||||
|
ResultRowMode.ONELINE, sql);
|
||||||
|
const result = t.getResultText();
|
||||||
|
const sArgs = Util.argvToString(argv);
|
||||||
|
//t2.verbose2(argv[0]," rc = ",rc," result buffer:\n", result,"\nargs:\n",sArgs);
|
||||||
|
const glob = Util.argvToString(argv);
|
||||||
|
rc = Util.strglob(glob, result);
|
||||||
|
if( (this.#negate && 0===rc) || (!this.#negate && 0!==rc) ){
|
||||||
|
ts.toss(argv[0], " mismatch: ", glob," vs input: ",result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --notglob command
|
||||||
|
class NotGlobCommand extends GlobCommand {
|
||||||
|
constructor(){super(true);}
|
||||||
|
}
|
||||||
|
|
||||||
//! --open command
|
//! --open command
|
||||||
class OpenDbCommand extends Command {
|
class OpenDbCommand extends Command {
|
||||||
#createIfNeeded = false;
|
#createIfNeeded = false;
|
||||||
@ -740,6 +915,107 @@ class PrintCommand extends Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! --result command
|
||||||
|
class ResultCommand extends Command {
|
||||||
|
#bufferMode;
|
||||||
|
constructor(resultBufferMode = ResultBufferMode.ESCAPED){
|
||||||
|
super();
|
||||||
|
this.#bufferMode = resultBufferMode;
|
||||||
|
}
|
||||||
|
process(t, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,0,-1);
|
||||||
|
t.incrementTestCounter();
|
||||||
|
const sql = t.takeInputBuffer();
|
||||||
|
//ts.verbose2(argv[0]," SQL =\n",sql);
|
||||||
|
t.execSql(null, false, this.#bufferMode, ResultRowMode.ONELINE, sql);
|
||||||
|
const result = t.getResultText().trim();
|
||||||
|
const sArgs = argv.length>1 ? Util.argvToString(argv) : "";
|
||||||
|
if( result !== sArgs ){
|
||||||
|
t.outln(argv[0]," FAILED comparison. Result buffer:\n",
|
||||||
|
result,"\nExpected result:\n",sArgs);
|
||||||
|
ts.toss(argv[0]+" comparison failed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --json command
|
||||||
|
class JsonCommand extends ResultCommand {
|
||||||
|
constructor(){ super(ResultBufferMode.ASIS); }
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --run command
|
||||||
|
class RunCommand extends Command {
|
||||||
|
process(t, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,0,1);
|
||||||
|
const pDb = (1==argv.length)
|
||||||
|
? t.currentDb() : t.getDbById( parseInt(argv[1]) );
|
||||||
|
const sql = t.takeInputBuffer();
|
||||||
|
const rc = t.execSql(pDb, false, ResultBufferMode.NONE,
|
||||||
|
ResultRowMode.ONELINE, sql);
|
||||||
|
if( 0!==rc && t.verbosity()>0 ){
|
||||||
|
const msg = sqlite3.capi.sqlite3_errmsg(pDb);
|
||||||
|
ts.verbose1(argv[0]," non-fatal command error #",rc,": ",
|
||||||
|
msg,"\nfor SQL:\n",sql);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --tableresult command
|
||||||
|
class TableResultCommand extends Command {
|
||||||
|
#jsonMode;
|
||||||
|
constructor(jsonMode=false){
|
||||||
|
super();
|
||||||
|
this.#jsonMode = jsonMode;
|
||||||
|
}
|
||||||
|
process(t, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,0);
|
||||||
|
t.incrementTestCounter();
|
||||||
|
let body = ts.fetchCommandBody(t);
|
||||||
|
log("TRC fetchCommandBody: ",body);
|
||||||
|
if( null===body ) ts.toss("Missing ",argv[0]," body.");
|
||||||
|
body = body.trim();
|
||||||
|
if( !body.endsWith("\n--end") ){
|
||||||
|
ts.toss(argv[0], " must be terminated with --end\\n");
|
||||||
|
}else{
|
||||||
|
body = body.substring(0, body.length-6);
|
||||||
|
log("TRC fetchCommandBody reshaped:",body);
|
||||||
|
}
|
||||||
|
const globs = body.split(/\s*\n\s*/);
|
||||||
|
if( globs.length < 1 ){
|
||||||
|
ts.toss(argv[0], " requires 1 or more ",
|
||||||
|
(this.#jsonMode ? "json snippets" : "globs"),".");
|
||||||
|
}
|
||||||
|
log("TRC fetchCommandBody globs:",globs);
|
||||||
|
const sql = t.takeInputBuffer();
|
||||||
|
t.execSql(null, true,
|
||||||
|
this.#jsonMode ? ResultBufferMode.ASIS : ResultBufferMode.ESCAPED,
|
||||||
|
ResultRowMode.NEWLINE, sql);
|
||||||
|
const rbuf = t.getResultText().trim();
|
||||||
|
const res = rbuf.split(/\r?\n/);
|
||||||
|
log("TRC fetchCommandBody rbuf, res:",rbuf, res);
|
||||||
|
if( res.length !== globs.length ){
|
||||||
|
ts.toss(argv[0], " failure: input has ", res.length,
|
||||||
|
" row(s) but expecting ",globs.length);
|
||||||
|
}
|
||||||
|
for(let i = 0; i < res.length; ++i){
|
||||||
|
const glob = globs[i].replaceAll(/\s+/g," ").trim();
|
||||||
|
//ts.verbose2(argv[0]," <<",glob,">> vs <<",res[i],">>");
|
||||||
|
if( this.#jsonMode ){
|
||||||
|
if( glob!==res[i] ){
|
||||||
|
ts.toss(argv[0], " json <<",glob, ">> does not match: <<",
|
||||||
|
res[i],">>");
|
||||||
|
}
|
||||||
|
}else if( 0!=Util.strglob(glob, res[i]) ){
|
||||||
|
ts.toss(argv[0], " glob <<",glob,">> does not match: <<",res[i],">>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --json-block command
|
||||||
|
class JsonBlockCommand extends TableResultCommand {
|
||||||
|
constructor(){ super(true); }
|
||||||
|
}
|
||||||
|
|
||||||
//! --testcase command
|
//! --testcase command
|
||||||
class TestCaseCommand extends Command {
|
class TestCaseCommand extends Command {
|
||||||
@ -770,18 +1046,18 @@ class CommandDispatcher {
|
|||||||
case "close": rv = new CloseDbCommand(); break;
|
case "close": rv = new CloseDbCommand(); break;
|
||||||
case "column-names": rv = new ColumnNamesCommand(); break;
|
case "column-names": rv = new ColumnNamesCommand(); break;
|
||||||
case "db": rv = new DbCommand(); break;
|
case "db": rv = new DbCommand(); break;
|
||||||
//case "glob": rv = new GlobCommand(); break;
|
case "glob": rv = new GlobCommand(); break;
|
||||||
//case "json": rv = new JsonCommand(); break;
|
case "json": rv = new JsonCommand(); break;
|
||||||
//case "json-block": rv = new JsonBlockCommand(); break;
|
case "json-block": rv = new JsonBlockCommand(); break;
|
||||||
case "new": rv = new NewDbCommand(); break;
|
case "new": rv = new NewDbCommand(); break;
|
||||||
//case "notglob": rv = new NotGlobCommand(); break;
|
case "notglob": rv = new NotGlobCommand(); break;
|
||||||
case "null": rv = new NullCommand(); break;
|
case "null": rv = new NullCommand(); break;
|
||||||
case "oom": rv = new NoopCommand(); break;
|
case "oom": rv = new NoopCommand(); break;
|
||||||
case "open": rv = new OpenDbCommand(); break;
|
case "open": rv = new OpenDbCommand(); break;
|
||||||
case "print": rv = new PrintCommand(); break;
|
case "print": rv = new PrintCommand(); break;
|
||||||
//case "result": rv = new ResultCommand(); break;
|
case "result": rv = new ResultCommand(); break;
|
||||||
//case "run": rv = new RunCommand(); break;
|
case "run": rv = new RunCommand(); break;
|
||||||
//case "tableresult": rv = new TableResultCommand(); break;
|
case "tableresult": rv = new TableResultCommand(); break;
|
||||||
case "testcase": rv = new TestCaseCommand(); break;
|
case "testcase": rv = new TestCaseCommand(); break;
|
||||||
case "verbosity": rv = new VerbosityCommand(); break;
|
case "verbosity": rv = new VerbosityCommand(); break;
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,46 @@ log("ns =",ns);
|
|||||||
out("Hi there. ").outln("SQLTester is ostensibly ready.");
|
out("Hi there. ").outln("SQLTester is ostensibly ready.");
|
||||||
|
|
||||||
let ts = new ns.TestScript('/foo.test', ns.Util.utf8Encode(
|
let ts = new ns.TestScript('/foo.test', ns.Util.utf8Encode(
|
||||||
`# comment line
|
`
|
||||||
--print Starting up...
|
--close all
|
||||||
--null NIL
|
--oom
|
||||||
--new :memory:
|
--db 0
|
||||||
--testcase 0.0.1
|
--new my.db
|
||||||
select '0.0.1';
|
--null zilch
|
||||||
#--result 0.0.1
|
--testcase 1.0
|
||||||
--print done
|
SELECT 1, null;
|
||||||
|
--result 1 zilch
|
||||||
|
--glob *zil*
|
||||||
|
--notglob *ZIL*
|
||||||
|
SELECT 1, 2;
|
||||||
|
intentional error;
|
||||||
|
--run
|
||||||
|
--testcase json-1
|
||||||
|
SELECT json_array(1,2,3)
|
||||||
|
--json [1,2,3]
|
||||||
|
--testcase tableresult-1
|
||||||
|
select 1, 'a';
|
||||||
|
select 2, 'b';
|
||||||
|
--tableresult
|
||||||
|
# [a-z]
|
||||||
|
2 b
|
||||||
|
--end
|
||||||
|
--testcase json-block-1
|
||||||
|
select json_array(1,2,3);
|
||||||
|
select json_object('a',1,'b',2);
|
||||||
|
--json-block
|
||||||
|
[1,2,3]
|
||||||
|
{"a":1,"b":2}
|
||||||
|
--end
|
||||||
|
--testcase col-names-on
|
||||||
|
--column-names 1
|
||||||
|
select 1 as 'a', 2 as 'b';
|
||||||
|
--result a 1 b 2
|
||||||
|
--testcase col-names-off
|
||||||
|
--column-names 0
|
||||||
|
select 1 as 'a', 2 as 'b';
|
||||||
|
--result 1 2
|
||||||
|
--close
|
||||||
`));
|
`));
|
||||||
|
|
||||||
const sqt = new ns.SQLTester();
|
const sqt = new ns.SQLTester();
|
||||||
@ -41,11 +73,12 @@ try{
|
|||||||
sqt.openDb('/foo.db', true);
|
sqt.openDb('/foo.db', true);
|
||||||
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
||||||
sqt.verbosity(0);
|
sqt.verbosity(0);
|
||||||
affirm( 'NIL' !== sqt.nullValue() );
|
affirm( 'zilch' !== sqt.nullValue() );
|
||||||
ts.run(sqt);
|
ts.run(sqt);
|
||||||
affirm( 'NIL' === sqt.nullValue() );
|
affirm( 'zilch' === sqt.nullValue() );
|
||||||
}finally{
|
}finally{
|
||||||
sqt.reset();
|
sqt.reset();
|
||||||
}
|
}
|
||||||
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
||||||
|
log( "Metrics:", sqt.metrics );
|
||||||
|
|
||||||
|
@ -1139,15 +1139,15 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
Records the current pstack position, calls the given function,
|
Records the current pstack position, calls the given function,
|
||||||
and restores the pstack regardless of whether the function
|
passing it the sqlite3 object, then restores the pstack
|
||||||
throws. Returns the result of the call or propagates an
|
regardless of whether the function throws. Returns the result
|
||||||
exception on error.
|
of the call or propagates an exception on error.
|
||||||
|
|
||||||
Added in 3.44.
|
Added in 3.44.
|
||||||
*/
|
*/
|
||||||
call: function(f){
|
call: function(f){
|
||||||
const stackPos = wasm.pstack.pointer;
|
const stackPos = wasm.pstack.pointer;
|
||||||
try{ return f() }finally{
|
try{ return f(sqlite3) } finally{
|
||||||
wasm.pstack.restore(stackPos);
|
wasm.pstack.restore(stackPos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1801,6 +1801,118 @@ char * sqlite3_wasm_test_str_hello(int fail){
|
|||||||
}
|
}
|
||||||
return s;
|
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 */
|
#endif /* SQLITE_WASM_TESTS */
|
||||||
|
|
||||||
#undef SQLITE_WASM_EXPORT
|
#undef SQLITE_WASM_EXPORT
|
||||||
|
20
manifest
20
manifest
@ -1,5 +1,5 @@
|
|||||||
C Get\sthe\sJS\sSQLTester\scommand\shandlers\sin\splace\ssans\sthose\swhich\shave\sto\srun\sSQL.
|
C JS\sSQLTestRunner\scan\snow\srun\sthe\sJava\simpl's\score-most\ssanity\stests,\smissing\sonly\ssupport\sfor\sdirectives.
|
||||||
D 2023-08-29T15:39:57.155
|
D 2023-08-29T20:01:01.586
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@ -283,7 +283,7 @@ F ext/jni/src/org/sqlite/jni/sqlite3.java 62b1b81935ccf3393472d17cb883dc5ff39c38
|
|||||||
F ext/jni/src/org/sqlite/jni/sqlite3_context.java 66ca95ce904044263a4aff684abe262d56f73e6b06bca6cf650761d79d7779ad
|
F ext/jni/src/org/sqlite/jni/sqlite3_context.java 66ca95ce904044263a4aff684abe262d56f73e6b06bca6cf650761d79d7779ad
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
|
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
||||||
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java c8a9f20694e66f4d7ed677cd6d1f0d829f802c347a1f413ac2446c62e4cba23d
|
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java a9f4b9e12109645b21fef15807973706dd958aad9fe1c835693fcb8e95abe949
|
||||||
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
|
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
|
||||||
F ext/jni/src/tests/000-000-sanity.test cfe6dc1b950751d6096e3f5695becaadcdaa048bfe9567209d6eb676e693366d
|
F ext/jni/src/tests/000-000-sanity.test cfe6dc1b950751d6096e3f5695becaadcdaa048bfe9567209d6eb676e693366d
|
||||||
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
|
||||||
@ -548,8 +548,8 @@ F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34ce
|
|||||||
F ext/wasm/GNUmakefile 0e362f3fc04eab6628cbe4f1e35f4ab4a200881f6b5f753b27fb45eabeddd9d2
|
F ext/wasm/GNUmakefile 0e362f3fc04eab6628cbe4f1e35f4ab4a200881f6b5f753b27fb45eabeddd9d2
|
||||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||||
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
|
F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193
|
||||||
F ext/wasm/SQLTester/SQLTester.mjs 90fc3d2eb831afed237c18b78c22b8871d8f855a742715ebee571a60b9fcd98e
|
F ext/wasm/SQLTester/SQLTester.mjs 345736d970dc56e2c1041f8583fc602eedd8a64d455864f312db7d3208e640ea
|
||||||
F ext/wasm/SQLTester/SQLTester.run.mjs 30a459ec400495cc52f1d693703f1629e141947a19eaf868a8e4c1fd3ef2a114
|
F ext/wasm/SQLTester/SQLTester.run.mjs 2dfa1407f5f188dadafe6f21f7a6740b4f07d59c594781a01eedadec16b2ddfe
|
||||||
F ext/wasm/SQLTester/index.html 88d87e3ccbc33e7ab3773a8e48c1172e876951c4be31d1307c3700671262cddf
|
F ext/wasm/SQLTester/index.html 88d87e3ccbc33e7ab3773a8e48c1172e876951c4be31d1307c3700671262cddf
|
||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab
|
||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||||
@ -563,14 +563,14 @@ F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057af
|
|||||||
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
|
F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e
|
||||||
F ext/wasm/api/sqlite3-api-glue.js b65e546568f1dfb35205b9792feb5146a6323d71b55cda58e2ed30def6dd52f3
|
F ext/wasm/api/sqlite3-api-glue.js b65e546568f1dfb35205b9792feb5146a6323d71b55cda58e2ed30def6dd52f3
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
|
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js 7fe51f06cd855634cb3765f830393f544fb532ead1cf95b5de3dd0befc81b92d
|
F ext/wasm/api/sqlite3-api-prologue.js 723908946bd624d367e4df7093e9a6c9725606dc526953ea601cad8d7ce88538
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
|
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
|
||||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
|
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
|
||||||
F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
|
F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 561463ac5380e4ccf1839a1922e6d7a5585660f32e3b9701a270b78cd35566cf
|
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 561463ac5380e4ccf1839a1922e6d7a5585660f32e3b9701a270b78cd35566cf
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js d9e62d42b86f7bb3143eb071628b24e2ba7dcc749e41a0e9d3e2451bfea1a6b6
|
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js d9e62d42b86f7bb3143eb071628b24e2ba7dcc749e41a0e9d3e2451bfea1a6b6
|
||||||
F ext/wasm/api/sqlite3-wasm.c 6773e949034369ddd2a1efdedc39b2808a10b7274b0769188905432e561feebe
|
F ext/wasm/api/sqlite3-wasm.c 65d60439671e24d50d9119ca805ac1c68fb36129e164377eb46f8d037bd88b07
|
||||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
|
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
|
||||||
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
|
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
|
||||||
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
||||||
@ -2111,8 +2111,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 8fcc2a553c1e26734902bbdee0c38183ee22b7b5c75f07405529bb79db34145a
|
P d21b1217964a53f33b7ba3958b34aa8560dff8ede33e66f54aa0afbab7099ec3
|
||||||
R 8ed29d2cdb1f79e88ba5ccad29a3151d
|
R 7266768b4057594984eb0965145c2068
|
||||||
U stephan
|
U stephan
|
||||||
Z 988ed72426998a455381761a89d498de
|
Z 703bcb5450951150eb9347fe40faa521
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
d21b1217964a53f33b7ba3958b34aa8560dff8ede33e66f54aa0afbab7099ec3
|
5e798369375ce1b0c9cdf831f835d931fbd562ff7b4db09a06d1bdca2ac1b975
|
Reference in New Issue
Block a user