mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
Get the JS SQLTester command handlers in place sans those which have to run SQL.
FossilOrigin-Name: d21b1217964a53f33b7ba3958b34aa8560dff8ede33e66f54aa0afbab7099ec3
This commit is contained in:
@ -336,7 +336,9 @@ public class SQLTester {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sqlite3 setCurrentDb(int n) throws Exception{
|
sqlite3 setCurrentDb(int n) throws Exception{
|
||||||
return affirmDbId(n).aDb[n];
|
affirmDbId(n);
|
||||||
|
iCurrentDb = n;
|
||||||
|
return this.aDb[n];
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; }
|
sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; }
|
||||||
@ -399,7 +401,7 @@ public class SQLTester {
|
|||||||
nullView = "nil";
|
nullView = "nil";
|
||||||
emitColNames = false;
|
emitColNames = false;
|
||||||
iCurrentDb = 0;
|
iCurrentDb = 0;
|
||||||
dbInitSql.append("SELECT 1;");
|
//dbInitSql.append("SELECT 1;");
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNullValue(String v){nullView = v;}
|
void setNullValue(String v){nullView = v;}
|
||||||
|
@ -64,11 +64,9 @@ SQLTesterException.toss = (...args)=>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DbException extends SQLTesterException {
|
class DbException extends SQLTesterException {
|
||||||
constructor(...args){
|
constructor(pDb, rc, closeDb){
|
||||||
super(...args);
|
super("DB error #"+rc+": "+sqlite3.capi.sqlite3_errmsg(pDb));
|
||||||
//TODO...
|
if( closeDb ) sqlite3.capi.sqlite3_close_v2(pDb);
|
||||||
//const db = args[0];
|
|
||||||
//if( db instanceof sqlite3.oo1.DB )
|
|
||||||
}
|
}
|
||||||
isFatal() { return true; }
|
isFatal() { return true; }
|
||||||
}
|
}
|
||||||
@ -150,9 +148,14 @@ class Outer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
setOutputPrefix( func ){
|
outputPrefix(){
|
||||||
this.getOutputPrefix = func;
|
if( 0==arguments.length ){
|
||||||
return this;
|
return (this.getOutputPrefix
|
||||||
|
? (this.getOutputPrefix() ?? '') : '');
|
||||||
|
}else{
|
||||||
|
this.getOutputPrefix = arguments[0];
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
verboseN(lvl, argv){
|
verboseN(lvl, argv){
|
||||||
@ -179,7 +182,7 @@ class Outer {
|
|||||||
|
|
||||||
class SQLTester {
|
class SQLTester {
|
||||||
|
|
||||||
#outer = new Outer().setOutputPrefix( ()=>'SQLTester: ' );
|
#outer = new Outer().outputPrefix( ()=>'SQLTester: ' );
|
||||||
#aFiles = [];
|
#aFiles = [];
|
||||||
#inputBuffer = [];
|
#inputBuffer = [];
|
||||||
#resultBuffer = [];
|
#resultBuffer = [];
|
||||||
@ -189,16 +192,34 @@ class SQLTester {
|
|||||||
});
|
});
|
||||||
#emitColNames = false;
|
#emitColNames = false;
|
||||||
#keepGoing = false;
|
#keepGoing = false;
|
||||||
#aDb = [];
|
|
||||||
#db = newObj({
|
#db = newObj({
|
||||||
list: [],
|
list: new Array(7),
|
||||||
iCurrent: 0,
|
iCurrentDb: 0,
|
||||||
initialDbName: "test.db",
|
initialDbName: "test.db",
|
||||||
|
initSql: ['select 1;'],
|
||||||
|
currentDb: function(){
|
||||||
|
return this.list[this.iCurrentDb];
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
constructor(){
|
constructor(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outln(...args){ return this.#outer.outln(...args); }
|
||||||
|
out(...args){ return this.#outer.out(...args); }
|
||||||
|
|
||||||
|
reset(){
|
||||||
|
this.clearInputBuffer();
|
||||||
|
this.clearResultBuffer();
|
||||||
|
this.#clearBuffer(this.#db.initSql);
|
||||||
|
this.closeAllDbs();
|
||||||
|
this.nTest = 0;
|
||||||
|
this.nullView = "nil";
|
||||||
|
this.emitColNames = false;
|
||||||
|
this.#db.iCurrentDb = 0;
|
||||||
|
this.#db.initSql.push("SELECT 1;");
|
||||||
|
}
|
||||||
|
|
||||||
appendInput(line, addNL){
|
appendInput(line, addNL){
|
||||||
this.#inputBuffer.push(line);
|
this.#inputBuffer.push(line);
|
||||||
if( addNL ) this.#inputBuffer.push('\n');
|
if( addNL ) this.#inputBuffer.push('\n');
|
||||||
@ -208,20 +229,195 @@ class SQLTester {
|
|||||||
if( addNL ) this.#resultBuffer.push('\n');
|
if( addNL ) this.#resultBuffer.push('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
clearInputBuffer(){
|
#clearBuffer(buffer){
|
||||||
this.#inputBuffer.length = 0;
|
buffer.length = 0;
|
||||||
return this.#inputBuffer;
|
return buffer;
|
||||||
}
|
|
||||||
clearResultBuffer(){
|
|
||||||
this.#resultBuffer.length = 0;
|
|
||||||
return this.#resultBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clearInputBuffer(){ return this.#clearBuffer(this.#inputBuffer); }
|
||||||
|
clearResultBuffer(){return this.#clearBuffer(this.#resultBuffer); }
|
||||||
|
|
||||||
getInputText(){ return this.#inputBuffer.join(''); }
|
getInputText(){ return this.#inputBuffer.join(''); }
|
||||||
getResultText(){ return this.#resultBuffer.join(''); }
|
getResultText(){ return this.#resultBuffer.join(''); }
|
||||||
|
|
||||||
|
#takeBuffer(buffer){
|
||||||
|
const s = buffer.join('');
|
||||||
|
buffer.length = 0;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
takeInputBuffer(){
|
||||||
|
return this.#takeBuffer(this.#inputBuffer);
|
||||||
|
}
|
||||||
|
takeResultBuffer(){
|
||||||
|
return this.#takeBuffer(this.#resultBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
verbosity(...args){ return this.#outer.verbosity(...args); }
|
verbosity(...args){ return this.#outer.verbosity(...args); }
|
||||||
|
|
||||||
|
nullValue(){
|
||||||
|
if( 0==arguments.length ){
|
||||||
|
return this.#nullView;
|
||||||
|
}else{
|
||||||
|
this.#nullView = ''+arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
outputColumnNames(){
|
||||||
|
if( 0==arguments.length ){
|
||||||
|
return this.#emitColNames;
|
||||||
|
}else{
|
||||||
|
this.#emitColNames = !!arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDbId(){
|
||||||
|
if( 0==arguments.length ){
|
||||||
|
return this.#db.iCurrentDb;
|
||||||
|
}else{
|
||||||
|
this.#affirmDbId(arguments[0]).#db.iCurrentDb = arguments[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#affirmDbId(id){
|
||||||
|
if(id<0 || id>=this.#db.list.length){
|
||||||
|
toss(SQLTesterException, "Database index ",id," is out of range.");
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentDb(...args){
|
||||||
|
if( 0!=args.length ){
|
||||||
|
this.#affirmDbId(id).#db.iCurrentDb = id;
|
||||||
|
}
|
||||||
|
return this.#db.currentDb();
|
||||||
|
}
|
||||||
|
|
||||||
|
getDbById(id){
|
||||||
|
return this.#affirmDbId(id).#db.list[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
getCurrentDb(){ return this.#db.list[this.#db.iCurrentDb]; }
|
||||||
|
|
||||||
|
|
||||||
|
closeDb(id) {
|
||||||
|
if( 0==arguments.length ){
|
||||||
|
id = this.#db.iCurrentDb;
|
||||||
|
}
|
||||||
|
const db = this.#affirmDbId(id).#db.list[id];
|
||||||
|
if( db ){
|
||||||
|
sqlite3.capi.sqlite3_close_v2(db);
|
||||||
|
this.#db.list[id] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closeAllDbs(){
|
||||||
|
for(let i = 0; i<this.#db.list.length; ++i){
|
||||||
|
if(this.#db.list[i]){
|
||||||
|
sqlite3.capi.sqlite3_close_v2(this.#db.list[i]);
|
||||||
|
this.#db.list[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.#db.iCurrentDb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
openDb(name, createIfNeeded){
|
||||||
|
if( 3===arguments.length ){
|
||||||
|
const slot = arguments[0];
|
||||||
|
this.#affirmDbId(slot).#db.iCurrentDb = slot;
|
||||||
|
name = arguments[1];
|
||||||
|
createIfNeeded = arguments[2];
|
||||||
|
}
|
||||||
|
this.closeDb();
|
||||||
|
const capi = sqlite3.capi, wasm = sqlite3.wasm;
|
||||||
|
let pDb = 0;
|
||||||
|
let flags = capi.SQLITE_OPEN_READWRITE;
|
||||||
|
if( createIfNeeded ) flags |= capi.SQLITE_OPEN_CREATE;
|
||||||
|
try{
|
||||||
|
let rc;
|
||||||
|
wasm.pstack.call(function(){
|
||||||
|
let ppOut = wasm.pstack.allocPtr();
|
||||||
|
rc = sqlite3.capi.sqlite3_open_v2(name, ppOut, flags, null);
|
||||||
|
pDb = wasm.peekPtr(ppOut);
|
||||||
|
});
|
||||||
|
if( 0==rc && this.#db.initSql.length > 0){
|
||||||
|
//this.#outer.verbose2("RUNNING DB INIT CODE: ",this.#db.initSql.toString());
|
||||||
|
rc = this.execSql(pDb, false, ResultBufferMode.NONE,
|
||||||
|
null, this.#db.initSql.join(''));
|
||||||
|
}
|
||||||
|
if( 0!=rc ){
|
||||||
|
sqlite3.SQLite3Error.toss(
|
||||||
|
rc,
|
||||||
|
"sqlite3 result code",rc+":",
|
||||||
|
(pDb ? sqlite3.capi.sqlite3_errmsg(pDb)
|
||||||
|
: sqlite3.capi.sqlite3_errstr(rc))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return this.#db.list[this.#db.iCurrentDb] = pDb;
|
||||||
|
}catch(e){
|
||||||
|
sqlite3.capi.sqlite3_close_v2(pDb);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#setupInitialDb(){
|
||||||
|
if( !this.#db.list[0] ){
|
||||||
|
Util.unlink(this.#db.initialDbName);
|
||||||
|
this.openDb(0, this.#db.initialDbName, true);
|
||||||
|
}else{
|
||||||
|
this.#outer.outln("WARNING: setupInitialDb() unexpectedly ",
|
||||||
|
"triggered while it is opened.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns v or some escaped form of v, as defined in the tester's
|
||||||
|
spec doc.
|
||||||
|
*/
|
||||||
|
#escapeSqlValue(v){
|
||||||
|
if( !v ) return "{}";
|
||||||
|
if( !Rx.special.test(v) ){
|
||||||
|
return v /* no escaping needed */;
|
||||||
|
}
|
||||||
|
if( !Rx.squiggly.test(v) ){
|
||||||
|
return "{"+v+"}";
|
||||||
|
}
|
||||||
|
const sb = ["\""];
|
||||||
|
const n = v.length;
|
||||||
|
for(let i = 0; i < n; ++i){
|
||||||
|
const ch = v.charAt(i);
|
||||||
|
switch(ch){
|
||||||
|
case '\\': sb.push("\\\\"); break;
|
||||||
|
case '"': sb.push("\\\""); break;
|
||||||
|
default:{
|
||||||
|
//verbose("CHAR ",(int)ch," ",ch," octal=",String.format("\\%03o", (int)ch));
|
||||||
|
const ccode = ch.charCodeAt(i);
|
||||||
|
if( ccode < 32 ) sb.push('\\',ccode.toString(8),'o');
|
||||||
|
else sb.push(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("\"");
|
||||||
|
return sb.join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
#appendDbErr(pDb, sb, rc){
|
||||||
|
sb.push(sqlite3.capi.sqlite3_js_rc_str(rc), ' ');
|
||||||
|
const msg = this.#escapeSqlValue(sqlite3.capi.sqlite3_errmsg(pDb));
|
||||||
|
if( '{' == msg.charAt(0) ){
|
||||||
|
sb.push(msg);
|
||||||
|
}else{
|
||||||
|
sb.push('{', msg, '}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
execSql(pDb, throwOnError, appendMode, lineMode, sql){
|
||||||
|
sql = sqlite3.capi.sqlite3_js_sql_to_string(sql);
|
||||||
|
this.#outer.outln("execSql() is TODO. ",sql);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}/*SQLTester*/
|
}/*SQLTester*/
|
||||||
|
|
||||||
class Command {
|
class Command {
|
||||||
@ -246,16 +442,6 @@ class Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestCase extends Command {
|
|
||||||
|
|
||||||
process(tester, script, argv){
|
|
||||||
this.argcCheck(script, argv,1);
|
|
||||||
script.testCaseName(argv[1]);
|
|
||||||
tester.clearResultBuffer();
|
|
||||||
tester.clearInputBuffer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Cursor {
|
class Cursor {
|
||||||
src;
|
src;
|
||||||
sb = [];
|
sb = [];
|
||||||
@ -287,7 +473,11 @@ const Rx = newObj({
|
|||||||
requiredProperties: / REQUIRED_PROPERTIES:[ \t]*(\S.*)\s*$/,
|
requiredProperties: / REQUIRED_PROPERTIES:[ \t]*(\S.*)\s*$/,
|
||||||
scriptModuleName: / SCRIPT_MODULE_NAME:[ \t]*(\S+)\s*$/,
|
scriptModuleName: / SCRIPT_MODULE_NAME:[ \t]*(\S+)\s*$/,
|
||||||
mixedModuleName: / ((MIXED_)?MODULE_NAME):[ \t]*(\S+)\s*$/,
|
mixedModuleName: / ((MIXED_)?MODULE_NAME):[ \t]*(\S+)\s*$/,
|
||||||
command: /^--(([a-z-]+)( .*)?)$/
|
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 {
|
||||||
@ -295,7 +485,7 @@ class TestScript {
|
|||||||
#moduleName = null;
|
#moduleName = null;
|
||||||
#filename = null;
|
#filename = null;
|
||||||
#testCaseName = null;
|
#testCaseName = null;
|
||||||
#outer = new Outer().setOutputPrefix( ()=>this.getOutputPrefix() );
|
#outer = new Outer().outputPrefix( ()=>this.getOutputPrefix()+': ' );
|
||||||
|
|
||||||
constructor(...args){
|
constructor(...args){
|
||||||
let content, filename;
|
let content, filename;
|
||||||
@ -307,7 +497,6 @@ class TestScript {
|
|||||||
}
|
}
|
||||||
this.#filename = filename;
|
this.#filename = filename;
|
||||||
this.#cursor.src = content;
|
this.#cursor.src = content;
|
||||||
this.#outer.outputPrefix = ()=>this.getOutputPrefix();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
testCaseName(){
|
testCaseName(){
|
||||||
@ -318,7 +507,7 @@ class TestScript {
|
|||||||
getOutputPrefix() {
|
getOutputPrefix() {
|
||||||
let rc = "["+(this.#moduleName || this.#filename)+"]";
|
let rc = "["+(this.#moduleName || this.#filename)+"]";
|
||||||
if( this.#testCaseName ) rc += "["+this.#testCaseName+"]";
|
if( this.#testCaseName ) rc += "["+this.#testCaseName+"]";
|
||||||
return rc + " line "+ this.#cursor.lineNo +" ";
|
return rc + " line "+ this.#cursor.lineNo;
|
||||||
}
|
}
|
||||||
|
|
||||||
reset(){
|
reset(){
|
||||||
@ -471,6 +660,106 @@ class TestScript {
|
|||||||
|
|
||||||
}/*TestScript*/;
|
}/*TestScript*/;
|
||||||
|
|
||||||
|
//! --close command
|
||||||
|
class CloseDbCommand extends Command {
|
||||||
|
process(t, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,0,1);
|
||||||
|
let id;
|
||||||
|
if(argv.length>1){
|
||||||
|
const arg = argv[1];
|
||||||
|
if("all".equals(arg)){
|
||||||
|
t.closeAllDbs();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
id = parseInt(arg);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
id = t.currentDbId();
|
||||||
|
}
|
||||||
|
t.closeDb(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --column-names command
|
||||||
|
class ColumnNamesCommand extends Command {
|
||||||
|
process( st, ts, argv ){
|
||||||
|
this.argcCheck(ts,argv,1);
|
||||||
|
st.outputColumnNames( !!parseInt(argv[1]) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --db command
|
||||||
|
class DbCommand extends Command {
|
||||||
|
process(t, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,1);
|
||||||
|
t.currentDbId( parseInt(argv[1]) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --open command
|
||||||
|
class OpenDbCommand extends Command {
|
||||||
|
#createIfNeeded = false;
|
||||||
|
constructor(createIfNeeded=false){
|
||||||
|
super();
|
||||||
|
this.#createIfNeeded = createIfNeeded;
|
||||||
|
}
|
||||||
|
process(t, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,1);
|
||||||
|
t.openDb(argv[1], this.#createIfNeeded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --new command
|
||||||
|
class NewDbCommand extends OpenDbCommand {
|
||||||
|
constructor(){ super(true); }
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Placeholder dummy/no-op commands
|
||||||
|
class NoopCommand extends Command {
|
||||||
|
process(t, ts, argv){}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --null command
|
||||||
|
class NullCommand extends Command {
|
||||||
|
process(st, ts, argv){
|
||||||
|
this.argcCheck(ts,argv,1);
|
||||||
|
st.nullValue( argv[1] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! --print command
|
||||||
|
class PrintCommand extends Command {
|
||||||
|
process(st, ts, argv){
|
||||||
|
st.out(ts.getOutputPrefix(),': ');
|
||||||
|
if( 1==argv.length ){
|
||||||
|
st.out( st.getInputText() );
|
||||||
|
}else{
|
||||||
|
st.outln( Util.argvToString(argv) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! --testcase command
|
||||||
|
class TestCaseCommand extends Command {
|
||||||
|
process(tester, script, argv){
|
||||||
|
this.argcCheck(script, argv,1);
|
||||||
|
script.testCaseName(argv[1]);
|
||||||
|
tester.clearResultBuffer();
|
||||||
|
tester.clearInputBuffer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! --verbosity command
|
||||||
|
class VerbosityCommand extends Command {
|
||||||
|
process(t, ts, argv){
|
||||||
|
t.argcCheck(ts,argv,1);
|
||||||
|
ts.verbosity( parseInt(argv[1]) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CommandDispatcher {
|
class CommandDispatcher {
|
||||||
static map = newObj();
|
static map = newObj();
|
||||||
|
|
||||||
@ -478,8 +767,23 @@ class CommandDispatcher {
|
|||||||
let rv = CommandDispatcher.map[name];
|
let rv = CommandDispatcher.map[name];
|
||||||
if( rv ) return rv;
|
if( rv ) return rv;
|
||||||
switch(name){
|
switch(name){
|
||||||
//todo: map name to Command instance
|
case "close": rv = new CloseDbCommand(); break;
|
||||||
case "testcase": rv = new TestCase(); break;
|
case "column-names": rv = new ColumnNamesCommand(); break;
|
||||||
|
case "db": rv = new DbCommand(); break;
|
||||||
|
//case "glob": rv = new GlobCommand(); break;
|
||||||
|
//case "json": rv = new JsonCommand(); break;
|
||||||
|
//case "json-block": rv = new JsonBlockCommand(); break;
|
||||||
|
case "new": rv = new NewDbCommand(); break;
|
||||||
|
//case "notglob": rv = new NotGlobCommand(); break;
|
||||||
|
case "null": rv = new NullCommand(); break;
|
||||||
|
case "oom": rv = new NoopCommand(); break;
|
||||||
|
case "open": rv = new OpenDbCommand(); break;
|
||||||
|
case "print": rv = new PrintCommand(); break;
|
||||||
|
//case "result": rv = new ResultCommand(); break;
|
||||||
|
//case "run": rv = new RunCommand(); break;
|
||||||
|
//case "tableresult": rv = new TableResultCommand(); break;
|
||||||
|
case "testcase": rv = new TestCaseCommand(); break;
|
||||||
|
case "verbosity": rv = new VerbosityCommand(); break;
|
||||||
}
|
}
|
||||||
if( rv ){
|
if( rv ){
|
||||||
CommandDispatcher.map[name] = rv;
|
CommandDispatcher.map[name] = rv;
|
||||||
@ -506,7 +810,8 @@ const namespace = newObj({
|
|||||||
TestScript,
|
TestScript,
|
||||||
TestScriptFailed,
|
TestScriptFailed,
|
||||||
UnknownCommand,
|
UnknownCommand,
|
||||||
Util
|
Util,
|
||||||
|
sqlite3
|
||||||
});
|
});
|
||||||
|
|
||||||
export {namespace as default};
|
export {namespace as default};
|
||||||
|
@ -1,26 +1,51 @@
|
|||||||
import {default as ns} from './SQLTester.mjs';
|
import {default as ns} from './SQLTester.mjs';
|
||||||
|
|
||||||
|
globalThis.sqlite3 = ns.sqlite3;
|
||||||
const log = function f(...args){
|
const log = function f(...args){
|
||||||
console.log('SQLTester.run:',...args);
|
console.log('SQLTester.run:',...args);
|
||||||
return f;
|
return f;
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log("Loaded",ns);
|
|
||||||
const out = function f(...args){ return f.outer.out(...args) };
|
const out = function f(...args){ return f.outer.out(...args) };
|
||||||
out.outer = new ns.Outer();
|
out.outer = new ns.Outer();
|
||||||
out.outer.getOutputPrefix = ()=>'SQLTester.run: ';
|
out.outer.getOutputPrefix = ()=>'SQLTester.run: ';
|
||||||
const outln = (...args)=>{ return out.outer.outln(...args) };
|
const outln = (...args)=>{ return out.outer.outln(...args) };
|
||||||
|
|
||||||
|
const affirm = function(expr, msg){
|
||||||
|
if( !expr ){
|
||||||
|
throw new Error(arguments[1]
|
||||||
|
? ("Assertion failed: "+arguments[1])
|
||||||
|
: "Assertion failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("Loaded",ns);
|
||||||
|
|
||||||
log("ns =",ns);
|
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
|
`# comment line
|
||||||
select 1;
|
--print Starting up...
|
||||||
--testcase 0.0
|
--null NIL
|
||||||
#--result 1
|
--new :memory:
|
||||||
|
--testcase 0.0.1
|
||||||
|
select '0.0.1';
|
||||||
|
#--result 0.0.1
|
||||||
|
--print done
|
||||||
`));
|
`));
|
||||||
|
|
||||||
const sqt = new ns.SQLTester();
|
const sqt = new ns.SQLTester();
|
||||||
sqt.verbosity(3);
|
try{
|
||||||
ts.run(sqt);
|
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
||||||
|
sqt.openDb('/foo.db', true);
|
||||||
|
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
||||||
|
sqt.verbosity(0);
|
||||||
|
affirm( 'NIL' !== sqt.nullValue() );
|
||||||
|
ts.run(sqt);
|
||||||
|
affirm( 'NIL' === sqt.nullValue() );
|
||||||
|
}finally{
|
||||||
|
sqt.reset();
|
||||||
|
}
|
||||||
|
log( 'sqt.getCurrentDb()', sqt.getCurrentDb() );
|
||||||
|
|
||||||
|
@ -1135,7 +1135,23 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
return 1===n
|
return 1===n
|
||||||
? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
|
? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof)
|
||||||
: wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
|
: wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
Records the current pstack position, calls the given function,
|
||||||
|
and 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() }finally{
|
||||||
|
wasm.pstack.restore(stackPos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
})/*wasm.pstack*/;
|
})/*wasm.pstack*/;
|
||||||
Object.defineProperties(wasm.pstack, {
|
Object.defineProperties(wasm.pstack, {
|
||||||
/**
|
/**
|
||||||
@ -1543,6 +1559,26 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
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.
|
||||||
|
|
||||||
|
The intent of this function is to convert SQL input text from a
|
||||||
|
variety of common forms to plain strings.
|
||||||
|
|
||||||
|
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() ){
|
if( util.isUIThread() ){
|
||||||
/* Features specific to the main window thread... */
|
/* Features specific to the main window thread... */
|
||||||
|
|
||||||
|
18
manifest
18
manifest
@ -1,5 +1,5 @@
|
|||||||
C Get\sthe\sbasic\sparsing\spieces\sand\scommand\sdispatching\sin\splace\sin\sthe\sJS\sSQLTester.
|
C Get\sthe\sJS\sSQLTester\scommand\shandlers\sin\splace\ssans\sthose\swhich\shave\sto\srun\sSQL.
|
||||||
D 2023-08-29T13:28:36.476
|
D 2023-08-29T15:39:57.155
|
||||||
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 bf350903abe04a9bed2d8a2a71692ed4291dbb4eece2d3329ed91d15b0321e6d
|
F ext/jni/src/org/sqlite/jni/tester/SQLTester.java c8a9f20694e66f4d7ed677cd6d1f0d829f802c347a1f413ac2446c62e4cba23d
|
||||||
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 2ea7d09f0c33e509aa3c4ca974be5705f59ddcd2173d4ff2721d7448c65be8bd
|
F ext/wasm/SQLTester/SQLTester.mjs 90fc3d2eb831afed237c18b78c22b8871d8f855a742715ebee571a60b9fcd98e
|
||||||
F ext/wasm/SQLTester/SQLTester.run.mjs 478f4d90951591decaa7e1e3fa1729f6ed0043ae4cb48b0a92056b9707d44185
|
F ext/wasm/SQLTester/SQLTester.run.mjs 30a459ec400495cc52f1d693703f1629e141947a19eaf868a8e4c1fd3ef2a114
|
||||||
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,7 +563,7 @@ 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 ef6f67c5ea718490806e5e17d2644b8b2f6e6ba5284d23dc1fbfd14d401c1ab5
|
F ext/wasm/api/sqlite3-api-prologue.js 7fe51f06cd855634cb3765f830393f544fb532ead1cf95b5de3dd0befc81b92d
|
||||||
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
|
||||||
@ -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 60eec5ceda80c64870713df8e9aeabeef933c007f2010792225a07d5ef36baef
|
P 8fcc2a553c1e26734902bbdee0c38183ee22b7b5c75f07405529bb79db34145a
|
||||||
R 0bdc268c3b78f235b9f50e80fcfe1a69
|
R 8ed29d2cdb1f79e88ba5ccad29a3151d
|
||||||
U stephan
|
U stephan
|
||||||
Z 00dd200744de92467554b7f23df0cf79
|
Z 988ed72426998a455381761a89d498de
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
8fcc2a553c1e26734902bbdee0c38183ee22b7b5c75f07405529bb79db34145a
|
d21b1217964a53f33b7ba3958b34aa8560dff8ede33e66f54aa0afbab7099ec3
|
Reference in New Issue
Block a user