mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Correct duplicate copies of sqlite3-api.js being embedded in the wasmfs-based builds.
FossilOrigin-Name: bbfcfba260f39a9c91e82d87e06b1c2cb297c03498b4530aa3e7e01ef9916012
This commit is contained in:
@@ -293,7 +293,7 @@ dir.sql := sql
|
|||||||
speedtest1 := ../../speedtest1
|
speedtest1 := ../../speedtest1
|
||||||
speedtest1.c := ../../test/speedtest1.c
|
speedtest1.c := ../../test/speedtest1.c
|
||||||
speedtest1.sql := $(dir.sql)/speedtest1.sql
|
speedtest1.sql := $(dir.sql)/speedtest1.sql
|
||||||
speedtest1.cliflags := --size 50 --big-transactions
|
speedtest1.cliflags := --size 25 --big-transactions
|
||||||
$(speedtest1):
|
$(speedtest1):
|
||||||
$(MAKE) -C ../.. speedtest1
|
$(MAKE) -C ../.. speedtest1
|
||||||
$(speedtest1.sql): $(speedtest1) $(MAKEFILE)
|
$(speedtest1.sql): $(speedtest1) $(MAKEFILE)
|
||||||
|
@@ -32,12 +32,16 @@
|
|||||||
<p id='warn-list' class='warning'>ACHTUNG: this file requires a generated input list
|
<p id='warn-list' class='warning'>ACHTUNG: this file requires a generated input list
|
||||||
file. Run "make batch" from this directory to generate it.
|
file. Run "make batch" from this directory to generate it.
|
||||||
</p>
|
</p>
|
||||||
<p id='warn-opfs' class='warning'>WARNING: if the WASMFS/OPFS layer crashes, this page may
|
<p id='warn-opfs' class='warning hidden'>WARNING: if the WASMFS/OPFS layer crashes, this page may
|
||||||
become completely unresponsive and need to be closed and
|
become completely unresponsive and need to be closed and reloaded to recover.
|
||||||
reloaded to recover.
|
</p>
|
||||||
|
<p id='warn-websql' class='warning hidden'>WARNING: WebSQL's limited API requires that
|
||||||
|
this app split up SQL batches into separate statements for execution. That will
|
||||||
|
only work so long as semicolon characters are <em>only</em> used to terminate
|
||||||
|
SQL statements, and not used within string literals or the like.
|
||||||
</p>
|
</p>
|
||||||
<hr>
|
<hr>
|
||||||
<div>
|
<div id='toolbar'>
|
||||||
<select class='disable-during-eval' id='sql-select'>
|
<select class='disable-during-eval' id='sql-select'>
|
||||||
<option disabled selected>Populated via script code</option>
|
<option disabled selected>Populated via script code</option>
|
||||||
</select>
|
</select>
|
||||||
@@ -47,19 +51,40 @@
|
|||||||
<button class='disable-during-eval' id='export-metrics'>Export metrics (WIP)</button>
|
<button class='disable-during-eval' id='export-metrics'>Export metrics (WIP)</button>
|
||||||
<button class='disable-during-eval' id='db-reset'>Reset db</button>
|
<button class='disable-during-eval' id='db-reset'>Reset db</button>
|
||||||
<button id='output-clear'>Clear output</button>
|
<button id='output-clear'>Clear output</button>
|
||||||
<span class='input-wrapper'>
|
<span class='input-wrapper flex-col'>
|
||||||
<input type='checkbox' class='disable-during-eval' id='cb-reverse-log-order' checked></input>
|
<label for='select-impl'>Storage impl:</label>
|
||||||
<label for='cb-reverse-log-order'>Reverse log order</label>
|
<select id='select-impl'>
|
||||||
|
<option value='virtualfs'>Virtual filesystem</option>
|
||||||
|
<option value='memdb'>:memory:</option>
|
||||||
|
<option value='wasmfs-opfs'>WASMFS OPFS</option>
|
||||||
|
<option value='websql'>WebSQL</option>
|
||||||
|
</select>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div id='reverse-log-notice' class='hidden'>(Log output is in reverse order, newest first!)</div>
|
<span class='input-wrapper'>
|
||||||
|
<input type='checkbox' class='disable-during-eval' id='cb-reverse-log-order' checked></input>
|
||||||
|
<label for='cb-reverse-log-order'>Reverse log order (newest first)</label>
|
||||||
|
</span>
|
||||||
<div id='test-output'></div>
|
<div id='test-output'></div>
|
||||||
<!-- batch-runner.js "should" work with sqlite3-kvvfs so long as
|
<!-- batch-runner.js "should" work with sqlite3-kvvfs so long as
|
||||||
its data sets don't violate the the storage limits. -->
|
its data sets don't violate the the storage limits. -->
|
||||||
<!--script src="sqlite3-kvvfs.js"></script-->
|
<script src="sqlite3-wasmfs.js"></script>
|
||||||
<script src="sqlite3.js"></script>
|
|
||||||
<script src="common/SqliteTestUtil.js"></script>
|
<script src="common/SqliteTestUtil.js"></script>
|
||||||
<script src="batch-runner.js"></script>
|
<script src="batch-runner.js"></script>
|
||||||
|
<style>
|
||||||
|
.flex-col {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
#toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
#toolbar > * {
|
||||||
|
margin: 0.25em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@@ -19,30 +19,110 @@
|
|||||||
const warn = console.warn.bind(console);
|
const warn = console.warn.bind(console);
|
||||||
let sqlite3;
|
let sqlite3;
|
||||||
|
|
||||||
|
/** Throws if the given sqlite3 result code is not 0. */
|
||||||
|
const checkSqliteRc = (dbh,rc)=>{
|
||||||
|
if(rc) toss("Prepare failed:",sqlite3.capi.sqlite3_errmsg(dbh));
|
||||||
|
};
|
||||||
|
|
||||||
|
const sqlToDrop = [
|
||||||
|
"SELECT type,name FROM sqlite_schema ",
|
||||||
|
"WHERE name NOT LIKE 'sqlite\\_%' escape '\\' ",
|
||||||
|
"AND name NOT LIKE '\\_%' escape '\\'"
|
||||||
|
].join('');
|
||||||
|
|
||||||
|
const clearDbWebSQL = function(db){
|
||||||
|
db.handle.transaction(function(tx){
|
||||||
|
const onErr = (e)=>console.error(e);
|
||||||
|
const callback = function(tx, result){
|
||||||
|
const rows = result.rows;
|
||||||
|
let i, n;
|
||||||
|
i = n = rows.length;
|
||||||
|
while(i--){
|
||||||
|
const row = rows.item(i);
|
||||||
|
const name = JSON.stringify(row.name);
|
||||||
|
const type = row.type;
|
||||||
|
switch(type){
|
||||||
|
case 'table': case 'view': case 'trigger':{
|
||||||
|
const sql2 = 'DROP '+type+' '+name;
|
||||||
|
warn(db.id,':',sql2);
|
||||||
|
tx.executeSql(sql2, [], atEnd, onErr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
warn("Unhandled db entry type:",type,name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
tx.executeSql(sqlToDrop, [], callback, onErr);
|
||||||
|
db.handle.changeVersion(db.handle.version, "", ()=>{}, onErr, ()=>{});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const clearDbSqlite = function(db){
|
||||||
|
// This would be SO much easier with the oo1 API, but we specifically want to
|
||||||
|
// inject metrics we can't get via that API, and we cannot reliably (OPFS)
|
||||||
|
// open the same DB twice to clear it using that API, so...
|
||||||
|
let pStmt = 0, pSqlBegin;
|
||||||
|
const capi = sqlite3.capi, wasm = capi.wasm;
|
||||||
|
const scope = wasm.scopedAllocPush();
|
||||||
|
try {
|
||||||
|
const toDrop = [];
|
||||||
|
const ppStmt = wasm.scopedAllocPtr();
|
||||||
|
let rc = capi.sqlite3_prepare_v2(db.handle, sqlToDrop, -1, ppStmt, null);
|
||||||
|
checkSqliteRc(db.handle,rc);
|
||||||
|
pStmt = wasm.getPtrValue(ppStmt);
|
||||||
|
while(capi.SQLITE_ROW===capi.sqlite3_step(pStmt)){
|
||||||
|
toDrop.push(capi.sqlite3_column_text(pStmt,0),
|
||||||
|
capi.sqlite3_column_text(pStmt,1));
|
||||||
|
}
|
||||||
|
capi.sqlite3_finalize(pStmt);
|
||||||
|
pStmt = 0;
|
||||||
|
while(toDrop.length){
|
||||||
|
const name = toDrop.pop();
|
||||||
|
const type = toDrop.pop();
|
||||||
|
let sql2;
|
||||||
|
switch(type){
|
||||||
|
case 'table': case 'view': case 'trigger':
|
||||||
|
sql2 = 'DROP '+type+' '+name;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
warn("Unhandled db entry type:",type,name);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
wasm.setPtrValue(ppStmt, 0);
|
||||||
|
warn(db.id,':',sql2);
|
||||||
|
rc = capi.sqlite3_prepare_v2(db.handle, sql2, -1, ppStmt, null);
|
||||||
|
checkSqliteRc(db.handle,rc);
|
||||||
|
pStmt = wasm.getPtrValue(ppStmt);
|
||||||
|
capi.sqlite3_step(pStmt);
|
||||||
|
capi.sqlite3_finalize(pStmt);
|
||||||
|
pStmt = 0;
|
||||||
|
}
|
||||||
|
}finally{
|
||||||
|
if(pStmt) capi.sqlite3_finalize(pStmt);
|
||||||
|
wasm.scopedAllocPop(scope);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const E = (s)=>document.querySelector(s);
|
||||||
const App = {
|
const App = {
|
||||||
e: {
|
e: {
|
||||||
output: document.querySelector('#test-output'),
|
output: E('#test-output'),
|
||||||
selSql: document.querySelector('#sql-select'),
|
selSql: E('#sql-select'),
|
||||||
btnRun: document.querySelector('#sql-run'),
|
btnRun: E('#sql-run'),
|
||||||
btnRunNext: document.querySelector('#sql-run-next'),
|
btnRunNext: E('#sql-run-next'),
|
||||||
btnRunRemaining: document.querySelector('#sql-run-remaining'),
|
btnRunRemaining: E('#sql-run-remaining'),
|
||||||
btnExportMetrics: document.querySelector('#export-metrics'),
|
btnExportMetrics: E('#export-metrics'),
|
||||||
btnClear: document.querySelector('#output-clear'),
|
btnClear: E('#output-clear'),
|
||||||
btnReset: document.querySelector('#db-reset'),
|
btnReset: E('#db-reset'),
|
||||||
cbReverseLog: document.querySelector('#cb-reverse-log-order')
|
cbReverseLog: E('#cb-reverse-log-order'),
|
||||||
|
selImpl: E('#select-impl')
|
||||||
},
|
},
|
||||||
db: Object.create(null),
|
db: Object.create(null),
|
||||||
|
dbs: Object.create(null),
|
||||||
cache:{},
|
cache:{},
|
||||||
metrics:{
|
|
||||||
/**
|
|
||||||
Map of sql-file to timing metrics. We currently only store
|
|
||||||
the most recent run of each file, but we really should store
|
|
||||||
all runs so that we can average out certain values which vary
|
|
||||||
significantly across runs. e.g. a mandelbrot-generating query
|
|
||||||
will have a wide range of runtimes when run 10 times in a
|
|
||||||
row.
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
log: console.log.bind(console),
|
log: console.log.bind(console),
|
||||||
warn: console.warn.bind(console),
|
warn: console.warn.bind(console),
|
||||||
cls: function(){this.e.output.innerHTML = ''},
|
cls: function(){this.e.output.innerHTML = ''},
|
||||||
@@ -62,45 +142,157 @@
|
|||||||
if(1) this.logHtml2('error', ...args);
|
if(1) this.logHtml2('error', ...args);
|
||||||
},
|
},
|
||||||
|
|
||||||
openDb: function(fn, unlinkFirst=true){
|
execSql: async function(name,sql){
|
||||||
if(this.db.ptr){
|
const db = this.getSelectedDb();
|
||||||
toss("Already have an opened db.");
|
const banner = "========================================";
|
||||||
}
|
this.logHtml(banner,
|
||||||
|
"Running",name,'('+sql.length,'bytes) using',db.id);
|
||||||
const capi = this.sqlite3.capi, wasm = capi.wasm;
|
const capi = this.sqlite3.capi, wasm = capi.wasm;
|
||||||
|
let pStmt = 0, pSqlBegin;
|
||||||
const stack = wasm.scopedAllocPush();
|
const stack = wasm.scopedAllocPush();
|
||||||
let pDb = 0;
|
const metrics = db.metrics = Object.create(null);
|
||||||
|
metrics.prepTotal = metrics.stepTotal = 0;
|
||||||
|
metrics.stmtCount = 0;
|
||||||
|
metrics.malloc = 0;
|
||||||
|
metrics.strcpy = 0;
|
||||||
|
this.blockControls(true);
|
||||||
|
if(this.gotErr){
|
||||||
|
this.logErr("Cannot run SQL: error cleanup is pending.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Run this async so that the UI can be updated for the above header...
|
||||||
|
const dumpMetrics = ()=>{
|
||||||
|
metrics.evalSqlEnd = performance.now();
|
||||||
|
metrics.evalTimeTotal = (metrics.evalSqlEnd - metrics.evalSqlStart);
|
||||||
|
this.logHtml(db.id,"metrics:");//,JSON.stringify(metrics, undefined, ' '));
|
||||||
|
this.logHtml("prepare() count:",metrics.stmtCount);
|
||||||
|
this.logHtml("Time in prepare_v2():",metrics.prepTotal,"ms",
|
||||||
|
"("+(metrics.prepTotal / metrics.stmtCount),"ms per prepare())");
|
||||||
|
this.logHtml("Time in step():",metrics.stepTotal,"ms",
|
||||||
|
"("+(metrics.stepTotal / metrics.stmtCount),"ms per step())");
|
||||||
|
this.logHtml("Total runtime:",metrics.evalTimeTotal,"ms");
|
||||||
|
this.logHtml("Overhead (time - prep - step):",
|
||||||
|
(metrics.evalTimeTotal - metrics.prepTotal - metrics.stepTotal)+"ms");
|
||||||
|
this.logHtml(banner,"End of",name);
|
||||||
|
};
|
||||||
|
|
||||||
|
let runner;
|
||||||
|
if('websql'===db.id){
|
||||||
|
runner = function(resolve, reject){
|
||||||
|
/* WebSQL cannot execute multiple statements, nor can it execute SQL without
|
||||||
|
an explicit transaction. Thus we have to do some fragile surgery on the
|
||||||
|
input SQL. Since we're only expecting carefully curated inputs, the hope is
|
||||||
|
that this will suffice. */
|
||||||
|
metrics.evalSqlStart = performance.now();
|
||||||
|
const sqls = sql.split(/;+\n/);
|
||||||
|
const rxBegin = /^BEGIN/i, rxCommit = /^COMMIT/i, rxComment = /^\s*--/;
|
||||||
try {
|
try {
|
||||||
if(unlinkFirst && fn){
|
const nextSql = ()=>{
|
||||||
if(':'!==fn[0]) capi.wasm.sqlite3_wasm_vfs_unlink(fn);
|
let x = sqls.shift();
|
||||||
this.clearStorage();
|
while(x && rxComment.test(x)) x = sqls.shift();
|
||||||
|
return x && x.trim();
|
||||||
|
};
|
||||||
|
const transaction = function(tx){
|
||||||
|
let s;
|
||||||
|
for(;s = nextSql(); s = s.nextSql()){
|
||||||
|
if(rxBegin.test(s)) continue;
|
||||||
|
else if(rxCommit.test(s)) break;
|
||||||
|
++metrics.stmtCount;
|
||||||
|
const t = performance.now();
|
||||||
|
tx.executeSql(s);
|
||||||
|
metrics.stepTotal += performance.now() - t;
|
||||||
}
|
}
|
||||||
const oFlags = capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE;
|
};
|
||||||
const ppDb = wasm.scopedAllocPtr();
|
while(sqls.length){
|
||||||
const rc = capi.sqlite3_open_v2(fn, ppDb, oFlags, null);
|
db.handle.transaction(transaction);
|
||||||
pDb = wasm.getPtrValue(ppDb)
|
|
||||||
if(rc){
|
|
||||||
if(pDb) capi.sqlite3_close_v2(pDb);
|
|
||||||
toss("sqlite3_open_v2() failed with code",rc);
|
|
||||||
}
|
}
|
||||||
|
resolve(this);
|
||||||
|
}catch(e){
|
||||||
|
this.gotErr = e;
|
||||||
|
reject(e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}.bind(this);
|
||||||
|
}else{/*sqlite3 db...*/
|
||||||
|
runner = function(resolve, reject){
|
||||||
|
metrics.evalSqlStart = performance.now();
|
||||||
|
try {
|
||||||
|
let t;
|
||||||
|
let sqlByteLen = sql.byteLength;
|
||||||
|
const [ppStmt, pzTail] = wasm.scopedAllocPtr(2);
|
||||||
|
t = performance.now();
|
||||||
|
pSqlBegin = wasm.scopedAlloc( sqlByteLen + 1/*SQL + NUL*/) || toss("alloc(",sqlByteLen,") failed");
|
||||||
|
metrics.malloc = performance.now() - t;
|
||||||
|
metrics.byteLength = sqlByteLen;
|
||||||
|
let pSql = pSqlBegin;
|
||||||
|
const pSqlEnd = pSqlBegin + sqlByteLen;
|
||||||
|
t = performance.now();
|
||||||
|
wasm.heap8().set(sql, pSql);
|
||||||
|
wasm.setMemValue(pSql + sqlByteLen, 0);
|
||||||
|
metrics.strcpy = performance.now() - t;
|
||||||
|
let breaker = 0;
|
||||||
|
while(pSql && wasm.getMemValue(pSql,'i8')){
|
||||||
|
wasm.setPtrValue(ppStmt, 0);
|
||||||
|
wasm.setPtrValue(pzTail, 0);
|
||||||
|
t = performance.now();
|
||||||
|
let rc = capi.sqlite3_prepare_v3(
|
||||||
|
db.handle, pSql, sqlByteLen, 0, ppStmt, pzTail
|
||||||
|
);
|
||||||
|
metrics.prepTotal += performance.now() - t;
|
||||||
|
checkSqliteRc(db.handle, rc);
|
||||||
|
pStmt = wasm.getPtrValue(ppStmt);
|
||||||
|
pSql = wasm.getPtrValue(pzTail);
|
||||||
|
sqlByteLen = pSqlEnd - pSql;
|
||||||
|
if(!pStmt) continue/*empty statement*/;
|
||||||
|
++metrics.stmtCount;
|
||||||
|
t = performance.now();
|
||||||
|
rc = capi.sqlite3_step(pStmt);
|
||||||
|
capi.sqlite3_finalize(pStmt);
|
||||||
|
pStmt = 0;
|
||||||
|
metrics.stepTotal += performance.now() - t;
|
||||||
|
switch(rc){
|
||||||
|
case capi.SQLITE_ROW:
|
||||||
|
case capi.SQLITE_DONE: break;
|
||||||
|
default: checkSqliteRc(db.handle, rc); toss("Not reached.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(this);
|
||||||
|
}catch(e){
|
||||||
|
if(pStmt) capi.sqlite3_finalize(pStmt);
|
||||||
|
this.gotErr = e;
|
||||||
|
reject(e);
|
||||||
|
return;
|
||||||
}finally{
|
}finally{
|
||||||
wasm.scopedAllocPop(stack);
|
wasm.scopedAllocPop(stack);
|
||||||
}
|
}
|
||||||
this.db.filename = fn;
|
}.bind(this);
|
||||||
this.db.ptr = pDb;
|
}
|
||||||
this.logHtml("Opened db:",fn);
|
let p;
|
||||||
return this.db.ptr;
|
if(1){
|
||||||
|
p = new Promise(function(res,rej){
|
||||||
|
setTimeout(()=>runner(res, rej), 50)/*give UI a chance to output the "running" banner*/;
|
||||||
|
});
|
||||||
|
}else{
|
||||||
|
p = new Promise(runner);
|
||||||
|
}
|
||||||
|
return p.catch(
|
||||||
|
(e)=>this.logErr("Error via execSql("+name+",...):",e.message)
|
||||||
|
).finally(()=>{
|
||||||
|
dumpMetrics();
|
||||||
|
this.blockControls(false);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
closeDb: function(unlink=false){
|
clearDb: function(){
|
||||||
if(this.db.ptr){
|
const db = this.getSelectedDb();
|
||||||
this.sqlite3.capi.sqlite3_close_v2(this.db.ptr);
|
if('websql'===db.id){
|
||||||
this.logHtml("Closed db",this.db.filename);
|
this.logErr("TODO: clear websql db.");
|
||||||
if(unlink){
|
return;
|
||||||
capi.wasm.sqlite3_wasm_vfs_unlink(this.db.filename);
|
|
||||||
this.clearStorage();
|
|
||||||
}
|
|
||||||
this.db.ptr = this.db.filename = undefined;
|
|
||||||
}
|
}
|
||||||
|
if(!db.handle) return;
|
||||||
|
const capi = this.sqlite3, wasm = capi.wasm;
|
||||||
|
//const scope = wasm.scopedAllocPush(
|
||||||
|
this.logErr("TODO: clear db");
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,7 +315,7 @@
|
|||||||
}
|
}
|
||||||
if(!r.ok) toss("Loading",infile,"failed:",r.statusText);
|
if(!r.ok) toss("Loading",infile,"failed:",r.statusText);
|
||||||
txt = await r.text();
|
txt = await r.text();
|
||||||
const warning = document.querySelector('#warn-list');
|
const warning = E('#warn-list');
|
||||||
if(warning) warning.remove();
|
if(warning) warning.remove();
|
||||||
}catch(e){
|
}catch(e){
|
||||||
this.logErr(e.message);
|
this.logErr(e.message);
|
||||||
@@ -169,13 +361,6 @@
|
|||||||
return sql;
|
return sql;
|
||||||
}/*fetchFile()*/,
|
}/*fetchFile()*/,
|
||||||
|
|
||||||
/** Throws if the given sqlite3 result code is not 0. */
|
|
||||||
checkRc: function(rc){
|
|
||||||
if(this.db.ptr && rc){
|
|
||||||
toss("Prepare failed:",this.sqlite3.capi.sqlite3_errmsg(this.db.ptr));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Disable or enable certain UI controls. */
|
/** Disable or enable certain UI controls. */
|
||||||
blockControls: function(disable){
|
blockControls: function(disable){
|
||||||
document.querySelectorAll('.disable-during-eval').forEach((e)=>e.disabled = disable);
|
document.querySelectorAll('.disable-during-eval').forEach((e)=>e.disabled = disable);
|
||||||
@@ -191,11 +376,11 @@
|
|||||||
const rc = [];
|
const rc = [];
|
||||||
Object.keys(this.metrics).sort().forEach((k)=>{
|
Object.keys(this.metrics).sort().forEach((k)=>{
|
||||||
const m = this.metrics[k];
|
const m = this.metrics[k];
|
||||||
delete m.evalFileStart;
|
delete m.evalSqlStart;
|
||||||
delete m.evalFileEnd;
|
delete m.evalSqlEnd;
|
||||||
const mk = Object.keys(m).sort();
|
const mk = Object.keys(m).sort();
|
||||||
if(!rc.length){
|
if(!rc.length){
|
||||||
rc.push(['file', ...mk]);
|
rc.push(['db', ...mk]);
|
||||||
}
|
}
|
||||||
const row = [k.split('/').pop()/*remove dir prefix from filename*/];
|
const row = [k.split('/').pop()/*remove dir prefix from filename*/];
|
||||||
rc.push(row);
|
rc.push(row);
|
||||||
@@ -205,6 +390,10 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
metricsToBlob: function(colSeparator='\t'){
|
metricsToBlob: function(colSeparator='\t'){
|
||||||
|
if(1){
|
||||||
|
this.logErr("TODO: re-do metrics dump");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const ar = [], ma = this.metricsToArrays();
|
const ar = [], ma = this.metricsToArrays();
|
||||||
if(!ma.length){
|
if(!ma.length){
|
||||||
this.logErr("Metrics are empty. Run something.");
|
this.logErr("Metrics are empty. Run something.");
|
||||||
@@ -239,114 +428,84 @@
|
|||||||
*/
|
*/
|
||||||
evalFile: async function(fn){
|
evalFile: async function(fn){
|
||||||
const sql = await this.fetchFile(fn);
|
const sql = await this.fetchFile(fn);
|
||||||
const banner = "========================================";
|
return this.execSql(fn,sql);
|
||||||
this.logHtml(banner,
|
|
||||||
"Running",fn,'('+sql.length,'bytes)...');
|
|
||||||
const capi = this.sqlite3.capi, wasm = capi.wasm;
|
|
||||||
let pStmt = 0, pSqlBegin;
|
|
||||||
const stack = wasm.scopedAllocPush();
|
|
||||||
const metrics = this.metrics[fn] = Object.create(null);
|
|
||||||
metrics.prepTotal = metrics.stepTotal = 0;
|
|
||||||
metrics.stmtCount = 0;
|
|
||||||
metrics.malloc = 0;
|
|
||||||
metrics.strcpy = 0;
|
|
||||||
this.blockControls(true);
|
|
||||||
if(this.gotErr){
|
|
||||||
this.logErr("Cannot run ["+fn+"]: error cleanup is pending.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Run this async so that the UI can be updated for the above header...
|
|
||||||
const ff = function(resolve, reject){
|
|
||||||
metrics.evalFileStart = performance.now();
|
|
||||||
try {
|
|
||||||
let t;
|
|
||||||
let sqlByteLen = sql.byteLength;
|
|
||||||
const [ppStmt, pzTail] = wasm.scopedAllocPtr(2);
|
|
||||||
t = performance.now();
|
|
||||||
pSqlBegin = wasm.alloc( sqlByteLen + 1/*SQL + NUL*/) || toss("alloc(",sqlByteLen,") failed");
|
|
||||||
metrics.malloc = performance.now() - t;
|
|
||||||
metrics.byteLength = sqlByteLen;
|
|
||||||
let pSql = pSqlBegin;
|
|
||||||
const pSqlEnd = pSqlBegin + sqlByteLen;
|
|
||||||
t = performance.now();
|
|
||||||
wasm.heap8().set(sql, pSql);
|
|
||||||
wasm.setMemValue(pSql + sqlByteLen, 0);
|
|
||||||
metrics.strcpy = performance.now() - t;
|
|
||||||
let breaker = 0;
|
|
||||||
while(pSql && wasm.getMemValue(pSql,'i8')){
|
|
||||||
wasm.setPtrValue(ppStmt, 0);
|
|
||||||
wasm.setPtrValue(pzTail, 0);
|
|
||||||
t = performance.now();
|
|
||||||
let rc = capi.sqlite3_prepare_v3(
|
|
||||||
this.db.ptr, pSql, sqlByteLen, 0, ppStmt, pzTail
|
|
||||||
);
|
|
||||||
metrics.prepTotal += performance.now() - t;
|
|
||||||
this.checkRc(rc);
|
|
||||||
pStmt = wasm.getPtrValue(ppStmt);
|
|
||||||
pSql = wasm.getPtrValue(pzTail);
|
|
||||||
sqlByteLen = pSqlEnd - pSql;
|
|
||||||
if(!pStmt) continue/*empty statement*/;
|
|
||||||
++metrics.stmtCount;
|
|
||||||
t = performance.now();
|
|
||||||
rc = capi.sqlite3_step(pStmt);
|
|
||||||
capi.sqlite3_finalize(pStmt);
|
|
||||||
pStmt = 0;
|
|
||||||
metrics.stepTotal += performance.now() - t;
|
|
||||||
switch(rc){
|
|
||||||
case capi.SQLITE_ROW:
|
|
||||||
case capi.SQLITE_DONE: break;
|
|
||||||
default: this.checkRc(rc); toss("Not reached.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}catch(e){
|
|
||||||
if(pStmt) capi.sqlite3_finalize(pStmt);
|
|
||||||
this.gotErr = e;
|
|
||||||
//throw e;
|
|
||||||
reject(e);
|
|
||||||
return;
|
|
||||||
}finally{
|
|
||||||
wasm.dealloc(pSqlBegin);
|
|
||||||
wasm.scopedAllocPop(stack);
|
|
||||||
this.blockControls(false);
|
|
||||||
}
|
|
||||||
metrics.evalFileEnd = performance.now();
|
|
||||||
metrics.evalTimeTotal = (metrics.evalFileEnd - metrics.evalFileStart);
|
|
||||||
this.logHtml("Metrics:");//,JSON.stringify(metrics, undefined, ' '));
|
|
||||||
this.logHtml("prepare() count:",metrics.stmtCount);
|
|
||||||
this.logHtml("Time in prepare_v2():",metrics.prepTotal,"ms",
|
|
||||||
"("+(metrics.prepTotal / metrics.stmtCount),"ms per prepare())");
|
|
||||||
this.logHtml("Time in step():",metrics.stepTotal,"ms",
|
|
||||||
"("+(metrics.stepTotal / metrics.stmtCount),"ms per step())");
|
|
||||||
this.logHtml("Total runtime:",metrics.evalTimeTotal,"ms");
|
|
||||||
this.logHtml("Overhead (time - prep - step):",
|
|
||||||
(metrics.evalTimeTotal - metrics.prepTotal - metrics.stepTotal)+"ms");
|
|
||||||
this.logHtml(banner,"End of",fn);
|
|
||||||
resolve(this);
|
|
||||||
}.bind(this);
|
|
||||||
let p;
|
|
||||||
if(1){
|
|
||||||
p = new Promise(function(res,rej){
|
|
||||||
setTimeout(()=>ff(res, rej), 50)/*give UI a chance to output the "running" banner*/;
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
p = new Promise(ff);
|
|
||||||
}
|
|
||||||
return p.catch((e)=>this.logErr("Error via evalFile("+fn+"):",e.message));
|
|
||||||
}/*evalFile()*/,
|
}/*evalFile()*/,
|
||||||
|
|
||||||
clearStorage: function(){
|
/**
|
||||||
const sz = sqlite3.capi.sqlite3_web_kvvfs_size();
|
Clears all DB tables in all _opened_ databases. Because of
|
||||||
const n = sqlite3.capi.sqlite3_web_kvvfs_clear(this.db.filename || '');
|
disparities between backends, we cannot simply "unlink" the
|
||||||
this.logHtml("Cleared kvvfs local/sessionStorage:",
|
databases to clean them up.
|
||||||
n,"entries totaling approximately",sz,"bytes.");
|
*/
|
||||||
|
clearStorage: function(onlySelectedDb=false){
|
||||||
|
const list = onlySelectDb
|
||||||
|
? [('boolean'===typeof onlySelectDb)
|
||||||
|
? this.dbs[this.e.selImpl.value]
|
||||||
|
: onlySelectDb]
|
||||||
|
: Object.values(this.dbs);
|
||||||
|
for(let db of list){
|
||||||
|
if(db && db.handle){
|
||||||
|
this.logHtml("Clearing db",db.id);
|
||||||
|
d.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
resetDb: function(){
|
/**
|
||||||
if(this.db.ptr){
|
Fetches the handle of the db associated with
|
||||||
const fn = this.db.filename;
|
this.e.selImpl.value, opening it if needed.
|
||||||
this.closeDb(true);
|
*/
|
||||||
this.openDb(fn,false);
|
getSelectedDb: function(){
|
||||||
|
if(!this.dbs.memdb){
|
||||||
|
for(let opt of this.e.selImpl.options){
|
||||||
|
const d = this.dbs[opt.value] = Object.create(null);
|
||||||
|
d.id = opt.value;
|
||||||
|
switch(d.id){
|
||||||
|
case 'virtualfs':
|
||||||
|
d.filename = 'file:/virtualfs.sqlite3?vfs=unix-none';
|
||||||
|
break;
|
||||||
|
case 'memdb':
|
||||||
|
d.filename = ':memory:';
|
||||||
|
break;
|
||||||
|
case 'wasmfs-opfs':
|
||||||
|
d.filename = 'file:'+(this.sqlite3.capi.sqlite3_wasmfs_opfs_dir())+'/wasmfs-opfs.sqlite3';
|
||||||
|
break;
|
||||||
|
case 'websql':
|
||||||
|
d.filename = 'websql.db';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.logErr("Unhandled db selection option (see details in the console).",opt);
|
||||||
|
toss("Unhandled db init option");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}/*first-time init*/
|
||||||
|
const dbId = this.e.selImpl.value;
|
||||||
|
const d = this.dbs[dbId];
|
||||||
|
if(d.handle) return d;
|
||||||
|
if('websql' === dbId){
|
||||||
|
d.handle = self.openDatabase('batch-runner', '0.1', 'foo', 1024 * 1024 * 50);
|
||||||
|
d.clear = ()=>clearDbWebSQL(d);
|
||||||
|
}else{
|
||||||
|
const capi = this.sqlite3.capi, wasm = capi.wasm;
|
||||||
|
const stack = wasm.scopedAllocPush();
|
||||||
|
let pDb = 0;
|
||||||
|
try{
|
||||||
|
const oFlags = capi.SQLITE_OPEN_CREATE | capi.SQLITE_OPEN_READWRITE;
|
||||||
|
const ppDb = wasm.scopedAllocPtr();
|
||||||
|
const rc = capi.sqlite3_open_v2(d.filename, ppDb, oFlags, null);
|
||||||
|
pDb = wasm.getPtrValue(ppDb)
|
||||||
|
if(rc) toss("sqlite3_open_v2() failed with code",rc);
|
||||||
|
}catch(e){
|
||||||
|
if(pDb) capi.sqlite3_close_v2(pDb);
|
||||||
|
}finally{
|
||||||
|
wasm.scopedAllocPop(stack);
|
||||||
|
}
|
||||||
|
d.handle = pDb;
|
||||||
|
d.clear = ()=>clearDbSqlite(d);
|
||||||
|
}
|
||||||
|
d.clear();
|
||||||
|
this.logHtml("Opened db:",dbId);
|
||||||
|
console.log("db =",d);
|
||||||
|
return d;
|
||||||
},
|
},
|
||||||
|
|
||||||
run: function(sqlite3){
|
run: function(sqlite3){
|
||||||
@@ -356,38 +515,24 @@
|
|||||||
this.logHtml("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
|
this.logHtml("Loaded module:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
|
||||||
this.logHtml("WASM heap size =",wasm.heap8().length);
|
this.logHtml("WASM heap size =",wasm.heap8().length);
|
||||||
this.loadSqlList();
|
this.loadSqlList();
|
||||||
let pDir, dbFile;
|
if(capi.sqlite3_wasmfs_opfs_dir()){
|
||||||
if(sqlite3.capi.sqlite3_vfs_find('kvvfs')){
|
E('#warn-opfs').classList.remove('hidden');
|
||||||
dbFile = 1 ? 'local' : 'session';
|
|
||||||
this.logHtml("Using KVVFS storage:",dbFile);
|
|
||||||
}else{
|
}else{
|
||||||
pDir = capi.sqlite3_wasmfs_opfs_dir();
|
E('#warn-opfs').remove();
|
||||||
if(pDir){
|
E('option[value=wasmfs-opfs]').disabled = true;
|
||||||
dbFile = pDir+"/speedtest.db";
|
}
|
||||||
this.logHtml("Using persistent storage:",dbFile);
|
if('function' === typeof self.openDatabase){
|
||||||
|
E('#warn-websql').classList.remove('hidden');
|
||||||
}else{
|
}else{
|
||||||
dbFile = ':memory:';
|
E('option[value=websql]').disabled = true;
|
||||||
this.logHtml("Using",dbFile,"storage.");
|
E('#warn-websql').remove();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if(!pDir){
|
|
||||||
document.querySelector('#warn-opfs').remove();
|
|
||||||
}
|
|
||||||
this.openDb(dbFile, true);
|
|
||||||
const who = this;
|
const who = this;
|
||||||
const eReverseLogNotice = document.querySelector('#reverse-log-notice');
|
|
||||||
if(this.e.cbReverseLog.checked){
|
if(this.e.cbReverseLog.checked){
|
||||||
eReverseLogNotice.classList.remove('hidden');
|
|
||||||
this.e.output.classList.add('reverse');
|
this.e.output.classList.add('reverse');
|
||||||
}
|
}
|
||||||
this.e.cbReverseLog.addEventListener('change', function(){
|
this.e.cbReverseLog.addEventListener('change', function(){
|
||||||
if(this.checked){
|
who.e.output.classList[this.checked ? 'add' : 'remove']('reverse');
|
||||||
who.e.output.classList.add('reverse');
|
|
||||||
eReverseLogNotice.classList.remove('hidden');
|
|
||||||
}else{
|
|
||||||
who.e.output.classList.remove('reverse');
|
|
||||||
eReverseLogNotice.classList.add('hidden');
|
|
||||||
}
|
|
||||||
}, false);
|
}, false);
|
||||||
this.e.btnClear.addEventListener('click', ()=>this.cls(), false);
|
this.e.btnClear.addEventListener('click', ()=>this.cls(), false);
|
||||||
this.e.btnRun.addEventListener('click', function(){
|
this.e.btnRun.addEventListener('click', function(){
|
||||||
@@ -400,7 +545,7 @@
|
|||||||
who.evalFile(who.e.selSql.value);
|
who.evalFile(who.e.selSql.value);
|
||||||
}, false);
|
}, false);
|
||||||
this.e.btnReset.addEventListener('click', function(){
|
this.e.btnReset.addEventListener('click', function(){
|
||||||
who.resetDb();
|
who.clearStorage(true);
|
||||||
}, false);
|
}, false);
|
||||||
this.e.btnExportMetrics.addEventListener('click', function(){
|
this.e.btnExportMetrics.addEventListener('click', function(){
|
||||||
who.logHtml2('warning',"Triggering download of metrics CSV. Check your downloads folder.");
|
who.logHtml2('warning',"Triggering download of metrics CSV. Check your downloads folder.");
|
||||||
@@ -408,6 +553,9 @@
|
|||||||
//const m = who.metricsToArrays();
|
//const m = who.metricsToArrays();
|
||||||
//console.log("Metrics:",who.metrics, m);
|
//console.log("Metrics:",who.metrics, m);
|
||||||
});
|
});
|
||||||
|
this.e.selImpl.addEventListener('change', function(){
|
||||||
|
who.getSelectedDb();
|
||||||
|
});
|
||||||
this.e.btnRunRemaining.addEventListener('click', async function(){
|
this.e.btnRunRemaining.addEventListener('click', async function(){
|
||||||
let v = who.e.selSql.value;
|
let v = who.e.selSql.value;
|
||||||
const timeStart = performance.now();
|
const timeStart = performance.now();
|
||||||
@@ -430,6 +578,7 @@
|
|||||||
self.sqlite3TestModule.initSqlite3().then(function(theEmccModule){
|
self.sqlite3TestModule.initSqlite3().then(function(theEmccModule){
|
||||||
self._MODULE = theEmccModule /* this is only to facilitate testing from the console */;
|
self._MODULE = theEmccModule /* this is only to facilitate testing from the console */;
|
||||||
sqlite3 = theEmccModule.sqlite3;
|
sqlite3 = theEmccModule.sqlite3;
|
||||||
|
console.log("App",App);
|
||||||
App.run(theEmccModule.sqlite3);
|
App.run(theEmccModule.sqlite3);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
@@ -83,7 +83,7 @@ $(sqlite3-wasmfs.js): $(sqlite3-wasmfs.wasm.c) $(sqlite3-wasm.c) $(sqlite3-wasmf
|
|||||||
$(post-js.js)
|
$(post-js.js)
|
||||||
@echo "Building $@ ..."
|
@echo "Building $@ ..."
|
||||||
$(emcc.bin) -o $@ $(emcc_opt) $(emcc.flags) \
|
$(emcc.bin) -o $@ $(emcc_opt) $(emcc.flags) \
|
||||||
$(sqlite3-wasmfs.cflags) $(speedtest1-common.eflags) $(sqlite3-wasmfs.jsflags) $(sqlite3-wasmfs.wasm.c) $(sqlite3-wasmfs.extra.c)
|
$(sqlite3-wasmfs.cflags) $(sqlite3-wasmfs.jsflags) $(sqlite3-wasmfs.wasm.c) $(sqlite3-wasmfs.extra.c)
|
||||||
chmod -x $(sqlite3-wasmfs.wasm)
|
chmod -x $(sqlite3-wasmfs.wasm)
|
||||||
$(maybe-wasm-strip) $(sqlite3-wasmfs.wasm)
|
$(maybe-wasm-strip) $(sqlite3-wasmfs.wasm)
|
||||||
@ls -la $@ $(sqlite3-wasmfs.wasm)
|
@ls -la $@ $(sqlite3-wasmfs.wasm)
|
||||||
@@ -99,7 +99,6 @@ speedtest1-wasmfs.js := speedtest1-wasmfs.js
|
|||||||
speedtest1-wasmfs.wasm := $(subst .js,.wasm,$(speedtest1-wasmfs.js))
|
speedtest1-wasmfs.wasm := $(subst .js,.wasm,$(speedtest1-wasmfs.js))
|
||||||
speedtest1-wasmfs.eflags := $(sqlite3-wasmfs.fsflags)
|
speedtest1-wasmfs.eflags := $(sqlite3-wasmfs.fsflags)
|
||||||
speedtest1-wasmfs.eflags += $(SQLITE_OPT) -DSQLITE_WASM_WASMFS
|
speedtest1-wasmfs.eflags += $(SQLITE_OPT) -DSQLITE_WASM_WASMFS
|
||||||
speedtest1-wasmfs.eflags += --post-js=$(sqlite3-wasmfs.js)
|
|
||||||
$(speedtest1-wasmfs.js): $(MAKEFILE) $(MAKEFILE.wasmfs)
|
$(speedtest1-wasmfs.js): $(MAKEFILE) $(MAKEFILE.wasmfs)
|
||||||
#$(speedtest1-wasmfs.js): $(sqlite3-wasmfs.js)
|
#$(speedtest1-wasmfs.js): $(sqlite3-wasmfs.js)
|
||||||
$(speedtest1-wasmfs.js): $(speedtest1.cs) $(sqlite3-wasmfs.js) \
|
$(speedtest1-wasmfs.js): $(speedtest1.cs) $(sqlite3-wasmfs.js) \
|
||||||
|
18
manifest
18
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Work\saround\sbroken\s-Os\swasm\sbuilds\sby\sadding\sthe\s-g3\sflag.\sUnrelated\sdocumentation\stweaks.
|
C Correct\sduplicate\scopies\sof\ssqlite3-api.js\sbeing\sembedded\sin\sthe\swasmfs-based\sbuilds.
|
||||||
D 2022-09-28T07:53:47.790
|
D 2022-09-28T13:01:49.194
|
||||||
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
|
||||||
@@ -474,7 +474,7 @@ F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
|||||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||||
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle 0e88c8cfc3719e4b7e74980d9da664c709e68acf863e48386cda376edfd3bfb0
|
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle 0e88c8cfc3719e4b7e74980d9da664c709e68acf863e48386cda376edfd3bfb0
|
||||||
F ext/wasm/GNUmakefile 984c33a37fa34786d6be2c79ef19421b3c1a054dfdb56ea09313077de4aa19f6
|
F ext/wasm/GNUmakefile 86ee7562063275779b108957db5bc7fdb18df4f6c506abbe28132b4fb071988e
|
||||||
F ext/wasm/README.md e1ee1e7c321c6a250bf78a84ca6f5882890a237a450ba5a0649c7a8399194c52
|
F ext/wasm/README.md e1ee1e7c321c6a250bf78a84ca6f5882890a237a450ba5a0649c7a8399194c52
|
||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 77a5ee8bd209b5e75dd0e822bc3f6e7319dc9b36431463d4175c775170f92126
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 77a5ee8bd209b5e75dd0e822bc3f6e7319dc9b36431463d4175c775170f92126
|
||||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||||
@@ -489,8 +489,8 @@ F ext/wasm/api/sqlite3-api-prologue.js 2a0dedb8127e8983d3199edea55151a45186b4626
|
|||||||
F ext/wasm/api/sqlite3-api-worker1.js d5d5b7fac4c4731c38c7e03f4f404b2a95c388a2a1d8bcf361caada572f107e0
|
F ext/wasm/api/sqlite3-api-worker1.js d5d5b7fac4c4731c38c7e03f4f404b2a95c388a2a1d8bcf361caada572f107e0
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||||
F ext/wasm/api/sqlite3-wasm.c b756b9c1fee9d0598f715e6df6bf089b750da24aa91bb7ef9277a037d81e7612
|
F ext/wasm/api/sqlite3-wasm.c b756b9c1fee9d0598f715e6df6bf089b750da24aa91bb7ef9277a037d81e7612
|
||||||
F ext/wasm/batch-runner.html 2857a6db7292ac83d1581af865d643fd34235db2df830d10b43b01388c599e04
|
F ext/wasm/batch-runner.html 168fda0f66369edec6427991683af3ed3919f3713158b70571d296f9a269a281
|
||||||
F ext/wasm/batch-runner.js b1f443bc63a779aac97ba6d54fc731a707ece2783b94e3b019abbfa79108e9a1
|
F ext/wasm/batch-runner.js c8d13f673a68e2094264a0284f8775dbda4a12e609d20c501316fe641a05c760
|
||||||
F ext/wasm/common/SqliteTestUtil.js c997c12188c97109f344701a58dd627b9c0f98f32cc6a88413f6171f2191531c
|
F ext/wasm/common/SqliteTestUtil.js c997c12188c97109f344701a58dd627b9c0f98f32cc6a88413f6171f2191531c
|
||||||
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
F ext/wasm/common/testing.css 3a5143699c2b73a85b962271e1a9b3241b30d90e30d895e4f55665e648572962
|
F ext/wasm/common/testing.css 3a5143699c2b73a85b962271e1a9b3241b30d90e30d895e4f55665e648572962
|
||||||
@@ -530,7 +530,7 @@ F ext/wasm/testing1.html 50575755e43232dbe4c2f97c9086b3118eb91ec2ee1fae931e6d766
|
|||||||
F ext/wasm/testing1.js 20b37766d29815180e2e932bfc6132b649403ece1f1bf612a4712db131287970
|
F ext/wasm/testing1.js 20b37766d29815180e2e932bfc6132b649403ece1f1bf612a4712db131287970
|
||||||
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
F ext/wasm/testing2.html a66951c38137ff1d687df79466351f3c734fa9c6d9cce71d3cf97c291b2167e3
|
||||||
F ext/wasm/testing2.js 34737da985c4cbd4812b2e7f200942662cae991c5a58ffa5d0350be089d0d410
|
F ext/wasm/testing2.js 34737da985c4cbd4812b2e7f200942662cae991c5a58ffa5d0350be089d0d410
|
||||||
F ext/wasm/wasmfs.make 52f24bc9c10e404d26bd0b0ee28d450269808a78e359d6ddedc45d31e7b9c29c
|
F ext/wasm/wasmfs.make fb4d0b4a6596ec2ed7815508a43b77bd7d14d3910ac387eb795643e33f5a3652
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
|
||||||
@@ -2026,8 +2026,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 093f6e4b36db294e8e47df2fc75a4bc4fc101e2b6ff0201c912ccd1dcf394479
|
P f5d6bf8616341037fa3e229edf820d19acef3e0a6207a652b2b143de0a493214
|
||||||
R f13bcaf00e26043effcfda9235e61887
|
R 2d5aa67e77362d00ccd0491d8ca53ec4
|
||||||
U stephan
|
U stephan
|
||||||
Z ec2d0b4aa25d1549f3750ebec3c29f7f
|
Z c9260f6deeb302437c703eb12e2e08ac
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
f5d6bf8616341037fa3e229edf820d19acef3e0a6207a652b2b143de0a493214
|
bbfcfba260f39a9c91e82d87e06b1c2cb297c03498b4530aa3e7e01ef9916012
|
Reference in New Issue
Block a user