aboutsummaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/wasm/api/sqlite3-api-oo1.js24
-rw-r--r--ext/wasm/api/sqlite3-api-opfs.js7
-rw-r--r--ext/wasm/api/sqlite3-api-prologue.js13
-rw-r--r--ext/wasm/api/sqlite3-wasm.c5
-rw-r--r--ext/wasm/common/SqliteTestUtil.js2
-rw-r--r--ext/wasm/demo-123.js9
-rw-r--r--ext/wasm/fiddle/fiddle-worker.js2
-rw-r--r--ext/wasm/index.html14
-rw-r--r--ext/wasm/speedtest1-wasmfs.html168
-rw-r--r--ext/wasm/speedtest1-worker.html222
-rw-r--r--ext/wasm/speedtest1-worker.js2
-rw-r--r--ext/wasm/speedtest1.html225
12 files changed, 353 insertions, 340 deletions
diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js
index e0f812baa..4f7ffe1cd 100644
--- a/ext/wasm/api/sqlite3-api-oo1.js
+++ b/ext/wasm/api/sqlite3-api-oo1.js
@@ -495,24 +495,25 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
},
/**
- Similar to this.filename but will return a falsy value for
- special names like ":memory:". Throws if the DB has been
- closed. If passed an argument it then it will return the
+ Similar to the this.filename property but will return a falsy
+ value for special names like ":memory:". Throws if the DB has
+ been closed. If passed an argument it then it will return the
filename of the ATTACHEd db with that name, else it assumes a
- name of `main`.
+ name of `main`. The argument may be either a JS string or
+ a pointer to a WASM-allocated C-string.
*/
getFilename: function(dbName='main'){
return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName);
},
/**
Returns true if this db instance has a name which resolves to a
- file. If the name is "" or ":memory:", it resolves to false.
+ file. If the name is "" or starts with ":", it resolves to false.
Note that it is not aware of the peculiarities of URI-style
names and a URI-style name for a ":memory:" db will fool it.
Returns false if this db is closed.
*/
hasFilename: function(){
- return this.filename && ':memory'!==this.filename;
+ return this.filename && ':'!==this.filename[0];
},
/**
Returns the name of the given 0-based db number, as documented
@@ -525,9 +526,13 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
Compiles the given SQL and returns a prepared Stmt. This is
the only way to create new Stmt objects. Throws on error.
- The given SQL must be a string, a Uint8Array holding SQL, or a
- WASM pointer to memory holding the NUL-terminated SQL string.
- If the SQL contains no statements, an SQLite3Error is thrown.
+ The given SQL must be a string, a Uint8Array holding SQL, a
+ WASM pointer to memory holding the NUL-terminated SQL string,
+ or an array of strings. In the latter case, the array is
+ concatenated together, with no separators, to form the SQL
+ string (arrays are often a convenient way to formulate long
+ statements). If the SQL contains no statements, an
+ SQLite3Error is thrown.
Design note: the C API permits empty SQL, reporting it as a 0
result code and a NULL stmt pointer. Supporting that case here
@@ -541,6 +546,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
*/
prepare: function(sql){
affirmDbOpen(this);
+ if(Array.isArray(sql)) sql = sql.join('');
const stack = capi.wasm.scopedAllocPush();
let ppStmt, pStmt;
try{
diff --git a/ext/wasm/api/sqlite3-api-opfs.js b/ext/wasm/api/sqlite3-api-opfs.js
index e28e47ab6..a346443f5 100644
--- a/ext/wasm/api/sqlite3-api-opfs.js
+++ b/ext/wasm/api/sqlite3-api-opfs.js
@@ -883,12 +883,15 @@ sqlite3.installOpfsVfs = function callee(asyncProxyUri = callee.defaultProxyUri)
hook in to any C-side calls to sqlite3_initialize(), so we
cannot add an after-initialize callback mechanism.
*/
- opfsUtil.reregisterVfs = (asDefault=false)=>{
+ opfsUtil.registerVfs = (asDefault=false)=>{
return capi.wasm.exports.sqlite3_vfs_register(
opfsVfs.pointer, asDefault ? 1 : 0
);
};
-
+
+ //TODO to support fiddle db upload:
+ //opfsUtil.createFile = function(absName, content=undefined){...}
+
if(sqlite3.oo1){
opfsUtil.OpfsDb = function(...args){
const opt = sqlite3.oo1.dbCtorHelper.normalizeArgs(...args);
diff --git a/ext/wasm/api/sqlite3-api-prologue.js b/ext/wasm/api/sqlite3-api-prologue.js
index b5cd292fc..b2d880937 100644
--- a/ext/wasm/api/sqlite3-api-prologue.js
+++ b/ext/wasm/api/sqlite3-api-prologue.js
@@ -120,7 +120,7 @@
the `free(3)`-compatible routine for the WASM
environment. Defaults to `"free"`.
- - `persistentDirName`[^1]: if the environment supports persistent storage, this
+ - `wasmfsOpfsDir`[^1]: if the environment supports persistent storage, this
directory names the "mount point" for that directory. It must be prefixed
by `/` and may currently contain only a single directory-name part. Using
the root directory name is not supported by any current persistent backend.
@@ -157,7 +157,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
})(),
allocExportName: 'malloc',
deallocExportName: 'free',
- persistentDirName: '/persistent'
+ wasmfsOpfsDir: '/opfs'
};
Object.keys(configDefaults).forEach(function(k){
config[k] = Object.getOwnPropertyDescriptor(apiConfig, k)
@@ -174,7 +174,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
[
// If any of these config options are functions, replace them with
// the result of calling that function...
- 'Module', 'exports', 'memory', 'persistentDirName'
+ 'Module', 'exports', 'memory', 'wasmfsOpfsDir'
].forEach((k)=>{
if('function' === typeof config[k]){
config[k] = config[k]();
@@ -185,8 +185,8 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
all args with a space between each. */
const toss = (...args)=>{throw new Error(args.join(' '))};
- if(config.persistentDirName && !/^\/[^/]+$/.test(config.persistentDirName)){
- toss("config.persistentDirName must be falsy or in the form '/dir-name'.");
+ if(config.wasmfsOpfsDir && !/^\/[^/]+$/.test(config.wasmfsOpfsDir)){
+ toss("config.wasmfsOpfsDir must be falsy or in the form '/dir-name'.");
}
/**
@@ -727,7 +727,7 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
capi.sqlite3_web_persistent_dir = function(){
if(undefined !== __persistentDir) return __persistentDir;
// If we have no OPFS, there is no persistent dir
- const pdir = config.persistentDirName;
+ const pdir = config.wasmfsOpfsDir;
if(!pdir
|| !self.FileSystemHandle
|| !self.FileSystemDirectoryHandle
@@ -748,7 +748,6 @@ self.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
const pVfs = sqlite3.capi.sqlite3_vfs_find("unix-none");
if(pVfs){
capi.sqlite3_vfs_register(pVfs,1);
- console.warn("Installed 'unix-none' as the default sqlite3 VFS.");
}
return __persistentDir = pdir;
}else{
diff --git a/ext/wasm/api/sqlite3-wasm.c b/ext/wasm/api/sqlite3-wasm.c
index cf9a1a3db..8750d9b20 100644
--- a/ext/wasm/api/sqlite3-wasm.c
+++ b/ext/wasm/api/sqlite3-wasm.c
@@ -571,7 +571,7 @@ int sqlite3_wasm_vfs_unlink(const char * zName){
WASM_KEEP
int sqlite3_wasm_init_wasmfs(const char *zMountPoint){
static backend_t pOpfs = 0;
- if( !zMountPoint || !*zMountPoint ) zMountPoint = "/persistent";
+ if( !zMountPoint || !*zMountPoint ) zMountPoint = "/opfs";
if( !pOpfs ){
pOpfs = wasmfs_create_opfs_backend();
if( pOpfs ){
@@ -595,7 +595,8 @@ int sqlite3_wasm_init_wasmfs(const char *zMountPoint){
}
#else
WASM_KEEP
-int sqlite3_wasm_init_wasmfs(void){
+int sqlite3_wasm_init_wasmfs(const char *zUnused){
+ if(zUnused){/*unused*/}
return SQLITE_NOTFOUND;
}
#endif /* __EMSCRIPTEN__ && SQLITE_WASM_WASMFS */
diff --git a/ext/wasm/common/SqliteTestUtil.js b/ext/wasm/common/SqliteTestUtil.js
index 779f271fb..277ab5529 100644
--- a/ext/wasm/common/SqliteTestUtil.js
+++ b/ext/wasm/common/SqliteTestUtil.js
@@ -221,7 +221,7 @@
sqlite3 API.
*/
sqlite3ApiConfig: {
- persistentDirName: "/persistent"
+ wasmfsOpfsDir: "/opfs"
},
/**
Intended to be called by apps which need to call the
diff --git a/ext/wasm/demo-123.js b/ext/wasm/demo-123.js
index c7dc4c769..5ba1f1df7 100644
--- a/ext/wasm/demo-123.js
+++ b/ext/wasm/demo-123.js
@@ -44,7 +44,7 @@
oo = sqlite3.oo1/*high-level OO API*/;
log("sqlite3 version",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
const db = new oo.DB("/mydb.sqlite3");
- log("transient b =",db.filename);
+ log("transient db =",db.filename);
/**
Never(!) rely on garbage collection to clean up DBs and
(especially) prepared statements. Always wrap their lifetimes
@@ -82,7 +82,12 @@
}
log("Insert using a prepared statement...");
- let q = db.prepare("insert into t(a,b) values(?,?)");
+ let q = db.prepare([
+ // SQL may be a string or array of strings
+ // (concatenated w/o separators).
+ "insert into t(a,b) ",
+ "values(?,?)"
+ ]);
try {
for( i = 100; i < 103; ++i ){
q.bind( [i, i*2] ).step();
diff --git a/ext/wasm/fiddle/fiddle-worker.js b/ext/wasm/fiddle/fiddle-worker.js
index dd8291465..b0c0526f8 100644
--- a/ext/wasm/fiddle/fiddle-worker.js
+++ b/ext/wasm/fiddle/fiddle-worker.js
@@ -170,7 +170,7 @@
stdout("\nOPFS is available. To open a persistent db, use:\n\n",
" .open file:name?vfs=opfs\n\nbut note that some",
"features (e.g. upload) do not yet work with OPFS.");
- S.opfs.reregisterVfs();
+ S.opfs.registerVfs();
}
stdout('\nEnter ".help" for usage hints.');
this.exec([ // initialization commands...
diff --git a/ext/wasm/index.html b/ext/wasm/index.html
index ee31306bb..20668db20 100644
--- a/ext/wasm/index.html
+++ b/ext/wasm/index.html
@@ -14,7 +14,7 @@
builds. All of them require that this directory have been
"make"d first. The intent is that <em>this</em> page be run
using:</div>
- <blockquote><pre>althttpd -page index.html</pre></blockquote>
+ <blockquote><pre>althttpd -enable-sab -page index.html</pre></blockquote>
<div>and the individual tests be started in their own tab.
Warnings and Caveats:
<ul class='warning'>
@@ -23,9 +23,8 @@
<a href='https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Opener-Policy'>COOP</a>
and
<a href='https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cross-Origin-Embedder-Policy'>COEP</a>
- headers. The default build
- of <a href='https://sqlite.org/althttpd'>althttpd</a>
- <em>does not</em>.
+ headers. <a href='https://sqlite.org/althttpd'>althttpd</a> requires the
+ <code>-enable-sab</code> flag for that.
</li>
<li>Any OPFS-related pages require very recent version of
Chrome or Chromium (v102 at least, possibly newer). OPFS
@@ -37,9 +36,6 @@
page may depend on build-time options which are <em>off by
default</em> because they currently (as of 2022-09-08) break
with Worker-based pages.
- <!-- Similarly, WASMFS does not work on some platforms,
- e.g. Raspberry Pi 4 (for which there is no Chrome
- build, so it's currently a moot point). -->
</li>
</ul>
</div>
@@ -63,9 +59,9 @@
<li>speedtest1 ports (sqlite3's primary benchmarking tool)...
<ul>
<li><a href='speedtest1.html'>speedtest1</a>: a main-thread WASM build of speedtest1.</li>
- <li><a href='speedtest1-wasmfs.html'>speedtest1-wasmfs</a>: a variant of speedtest1 built solely for the wasmfs/opfs feature.</li>
+ <li><a href='speedtest1-wasmfs.html?flags=--size,25'>speedtest1-wasmfs</a>: a variant of speedtest1 built solely for the wasmfs/opfs feature.</li>
<li><a href='speedtest1.html?vfs=kvvfs'>speedtest1-kvvfs</a>: speedtest1 with the kvvfs.</li>
- <li><a href='speedtest1-worker.html'>speedtest1-worker</a>: an interactive Worker-thread variant of speedtest1.</li>
+ <li><a href='speedtest1-worker.html?size=25'>speedtest1-worker</a>: an interactive Worker-thread variant of speedtest1.</li>
<li><a href='speedtest1-worker.html?vfs=opfs&size=25'>speedtest1-worker-opfs</a>: speedtest1-worker with the
OPFS VFS preselected and configured for a moderate workload.</li>
</ul>
diff --git a/ext/wasm/speedtest1-wasmfs.html b/ext/wasm/speedtest1-wasmfs.html
index 37155282c..6952fc1ee 100644
--- a/ext/wasm/speedtest1-wasmfs.html
+++ b/ext/wasm/speedtest1-wasmfs.html
@@ -39,115 +39,113 @@
<script src="common/SqliteTestUtil.js"></script>
<script src="speedtest1-wasmfs.js"></script>
<script>(function(){
- /**
- If this environment contains OPFS, this function initializes it and
- returns the name of the dir on which OPFS is mounted, else it returns
- an empty string.
- */
- const wasmfsDir = function f(wasmUtil){
- if(undefined !== f._) return f._;
- const pdir = '/persistent';
- if( !self.FileSystemHandle
- || !self.FileSystemDirectoryHandle
- || !self.FileSystemFileHandle){
+ /**
+ If this environment contains OPFS, this function initializes it and
+ returns the name of the dir on which OPFS is mounted, else it returns
+ an empty string.
+ */
+ const wasmfsDir = function f(wasmUtil,dirName="/opfs"){
+ if(undefined !== f._) return f._;
+ if( !self.FileSystemHandle
+ || !self.FileSystemDirectoryHandle
+ || !self.FileSystemFileHandle){
return f._ = "";
- }
- try{
+ }
+ try{
if(0===wasmUtil.xCallWrapped(
- 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
+ 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], dirName
)){
- return f._ = pdir;
+ return f._ = dirName;
}else{
- return f._ = "";
+ return f._ = "";
}
- }catch(e){
+ }catch(e){
// sqlite3_wasm_init_wasmfs() is not available
return f._ = "";
- }
- };
- wasmfsDir._ = undefined;
+ }
+ };
+ wasmfsDir._ = undefined;
- const eOut = document.querySelector('#test-output');
- const log2 = function(cssClass,...args){
- const ln = document.createElement('div');
- if(cssClass) ln.classList.add(cssClass);
- ln.append(document.createTextNode(args.join(' ')));
- eOut.append(ln);
- //this.e.output.lastElementChild.scrollIntoViewIfNeeded();
- };
- const logList = [];
- const dumpLogList = function(){
- logList.forEach((v)=>log2('',v));
- logList.length = 0;
- };
- /* can't update DOM while speedtest is running unless we run
- speedtest in a worker thread. */;
- const log = (...args)=>{
- console.log(...args);
- logList.push(args.join(' '));
- };
- const logErr = function(...args){
- console.error(...args);
- logList.push('ERROR: '+args.join(' '));
- };
+ const eOut = document.querySelector('#test-output');
+ const log2 = function(cssClass,...args){
+ const ln = document.createElement('div');
+ if(cssClass) ln.classList.add(cssClass);
+ ln.append(document.createTextNode(args.join(' ')));
+ eOut.append(ln);
+ //this.e.output.lastElementChild.scrollIntoViewIfNeeded();
+ };
+ const logList = [];
+ const dumpLogList = function(){
+ logList.forEach((v)=>log2('',v));
+ logList.length = 0;
+ };
+ /* can't update DOM while speedtest is running unless we run
+ speedtest in a worker thread. */;
+ const log = (...args)=>{
+ console.log(...args);
+ logList.push(args.join(' '));
+ };
+ const logErr = function(...args){
+ console.error(...args);
+ logList.push('ERROR: '+args.join(' '));
+ };
- const runTests = function(sqlite3){
- console.log("Module inited.");
- const wasm = sqlite3.capi.wasm;
- const unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["string"]);
- const pDir = wasmfsDir(wasm);
- if(pDir) log2('',"Persistent storage:",pDir);
- else{
+ const runTests = function(sqlite3){
+ console.log("Module inited.");
+ const wasm = sqlite3.capi.wasm;
+ const unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["string"]);
+ const pDir = wasmfsDir(wasm);
+ if(pDir) log2('',"Persistent storage:",pDir);
+ else{
log2('error',"Expecting persistent storage in this build.");
return;
- }
- const scope = wasm.scopedAllocPush();
- const dbFile = pDir+"/speedtest1.db";
- const urlParams = self.SqliteTestUtil.processUrlArgs();
- const argv = ["speedtest1"];
- if(urlParams.flags){
- argv.push(...(urlParams.flags.split(',')));
+ }
+ const scope = wasm.scopedAllocPush();
+ const dbFile = pDir+"/speedtest1.db";
+ const urlParams = new URL(self.location.href).searchParams;
+ const argv = ["speedtest1"];
+ if(urlParams.has('flags')){
+ argv.push(...(urlParams.get('flags').split(',')));
let i = argv.indexOf('--vfs');
if(i>=0) argv.splice(i,2);
- }else{
+ }else{
argv.push(
- "--singlethread",
- "--nomutex",
- "--nosync",
- "--nomemstat"
+ "--singlethread",
+ "--nomutex",
+ "--nosync",
+ "--nomemstat"
);
//"--memdb", // note that memdb trumps the filename arg
- }
+ }
- if(argv.indexOf('--memdb')>=0){
+ if(argv.indexOf('--memdb')>=0){
log2('error',"WARNING: --memdb flag trumps db filename.");
- }
- argv.push("--big-transactions"/*important for tests 410 and 510!*/,
- dbFile);
- console.log("argv =",argv);
- // These log messages are not emitted to the UI until after main() returns. Fixing that
- // requires moving the main() call and related cleanup into a timeout handler.
- if(pDir) unlink(dbFile);
- log2('',"Starting native app:\n ",argv.join(' '));
- log2('',"This will take a while and the browser might warn about the runaway JS.",
- "Give it time...");
- logList.length = 0;
- setTimeout(function(){
+ }
+ argv.push("--big-transactions"/*important for tests 410 and 510!*/,
+ dbFile);
+ console.log("argv =",argv);
+ // These log messages are not emitted to the UI until after main() returns. Fixing that
+ // requires moving the main() call and related cleanup into a timeout handler.
+ if(pDir) unlink(dbFile);
+ log2('',"Starting native app:\n ",argv.join(' '));
+ log2('',"This will take a while and the browser might warn about the runaway JS.",
+ "Give it time...");
+ logList.length = 0;
+ setTimeout(function(){
wasm.xCall('wasm_main', argv.length,
wasm.scopedAllocMainArgv(argv));
wasm.scopedAllocPop(scope);
if(pDir) unlink(dbFile);
logList.unshift("Done running native main(). Output:");
dumpLogList();
- }, 25);
- }/*runTests()*/;
+ }, 25);
+ }/*runTests()*/;
- self.sqlite3TestModule.print = log;
- self.sqlite3TestModule.printErr = logErr;
- sqlite3Speedtest1InitModule(self.sqlite3TestModule).then(function(M){
- runTests(M.sqlite3);
- });
- })();
- </script>
+ self.sqlite3TestModule.print = log;
+ self.sqlite3TestModule.printErr = logErr;
+ sqlite3Speedtest1InitModule(self.sqlite3TestModule).then(function(M){
+ runTests(M.sqlite3);
+ });
+})();</script>
</body>
</html>
diff --git a/ext/wasm/speedtest1-worker.html b/ext/wasm/speedtest1-worker.html
index b1bc3aace..b5e1089b6 100644
--- a/ext/wasm/speedtest1-worker.html
+++ b/ext/wasm/speedtest1-worker.html
@@ -127,75 +127,75 @@
}
</style>
<script>(function(){
- 'use strict';
- const E = (sel)=>document.querySelector(sel);
- const eOut = E('#test-output');
- const log2 = function(cssClass,...args){
+ 'use strict';
+ const E = (sel)=>document.querySelector(sel);
+ const eOut = E('#test-output');
+ const log2 = function(cssClass,...args){
let ln;
if(1 || cssClass){
- ln = document.createElement('div');
- if(cssClass) ln.classList.add(cssClass);
- ln.append(document.createTextNode(args.join(' ')));
+ ln = document.createElement('div');
+ if(cssClass) ln.classList.add(cssClass);
+ ln.append(document.createTextNode(args.join(' ')));
}else{
- // This doesn't work with the "reverse order" option!
- ln = document.createTextNode(args.join(' ')+'\n');
+ // This doesn't work with the "reverse order" option!
+ ln = document.createTextNode(args.join(' ')+'\n');
}
eOut.append(ln);
- };
- const log = (...args)=>{
+ };
+ const log = (...args)=>{
//console.log(...args);
log2('', ...args);
- };
- const logErr = function(...args){
+ };
+ const logErr = function(...args){
console.error(...args);
log2('error', ...args);
- };
- const logWarn = function(...args){
+ };
+ const logWarn = function(...args){
console.warn(...args);
log2('warning', ...args);
- };
+ };
- const spacePad = function(str,len=21){
+ const spacePad = function(str,len=21){
if(str.length===len) return str;
else if(str.length>len) return str.substr(0,len);
const a = []; a.length = len - str.length;
return str+a.join(' ');
- };
- // OPTION elements seem to ignore white-space:pre, so do this the hard way...
- const nbspPad = function(str,len=21){
+ };
+ // OPTION elements seem to ignore white-space:pre, so do this the hard way...
+ const nbspPad = function(str,len=21){
if(str.length===len) return str;
else if(str.length>len) return str.substr(0,len);
const a = []; a.length = len - str.length;
return str+a.join('&nbsp;');
- };
+ };
- const W = new Worker("speedtest1-worker.js"+self.location.search);
- const mPost = function(msgType,payload){
+ const W = new Worker("speedtest1-worker.js"+self.location.search);
+ const mPost = function(msgType,payload){
W.postMessage({type: msgType, data: payload});
- };
+ };
- const eFlags = E('#select-flags');
- const eSelectedFlags = E('#toolbar-selected-flags');
- const eLinkMainThread = E('#link-main-thread');
- const eLinkWasmfs = E('#link-wasmfs');
- const eLinkKvvfs = E('#link-kvvfs');
- const urlParams = new URL(self.location.href).searchParams;
- const getSelectedFlags = ()=>{
- const f = Array.prototype.map.call(eFlags.selectedOptions, (v)=>v.value);
- [
- 'size', 'vfs'
- ].forEach(function(k){
- if(urlParams.has(k)) f.push('--'+k, urlParams.get(k));
- });
- return f;
- };
- const updateSelectedFlags = function(){
+ const eFlags = E('#select-flags');
+ const eSelectedFlags = E('#toolbar-selected-flags');
+ const eLinkMainThread = E('#link-main-thread');
+ const eLinkWasmfs = E('#link-wasmfs');
+ const eLinkKvvfs = E('#link-kvvfs');
+ const urlParams = new URL(self.location.href).searchParams;
+ const getSelectedFlags = ()=>{
+ const f = Array.prototype.map.call(eFlags.selectedOptions, (v)=>v.value);
+ [
+ 'size', 'vfs'
+ ].forEach(function(k){
+ if(urlParams.has(k)) f.push('--'+k, urlParams.get(k));
+ });
+ return f;
+ };
+ const updateSelectedFlags = function(){
eSelectedFlags.innerText = '';
const flags = getSelectedFlags();
flags.forEach(function(f){
- const e = document.createElement('span');
- e.innerText = f;
- eSelectedFlags.appendChild(e);
+ const e = document.createElement('span');
+ e.innerText = f;
+ eSelectedFlags.appendChild(e);
});
const rxStripDash = /^(-+)?/;
const comma = flags.join(',');
@@ -205,9 +205,9 @@
eLinkWasmfs.href = 'speedtest1-wasmfs.html?flags='+comma;
eLinkKvvfs.setAttribute('target', 'speedtest1-kvvfs-'+comma);
eLinkKvvfs.href = 'speedtest1-kvvfs.html?flags='+comma;
- };
- eFlags.addEventListener('change', updateSelectedFlags );
- {
+ };
+ eFlags.addEventListener('change', updateSelectedFlags );
+ {
const flags = Object.create(null);
/* TODO? Flags which require values need custom UI
controls and some of them make little sense here
@@ -259,111 +259,111 @@
flags["--verify"] = "Run additional verification steps.";
flags["--without"] = "rowid Use WITHOUT ROWID where appropriate";
const preselectedFlags = [
- '--big-transactions',
- '--singlethread'
+ '--big-transactions',
+ '--singlethread'
];
if(urlParams.has('flags')){
- preselectedFlags.push(...urlParams.get('flags').split(','));
+ preselectedFlags.push(...urlParams.get('flags').split(','));
}
- if('opfs'!==urlParams.get('vfs')){
- preselectedFlags.push('--memdb');
+ if('opfs'!==urlParams.get('vfs')){
+ preselectedFlags.push('--memdb');
}
Object.keys(flags).sort().forEach(function(f){
- const opt = document.createElement('option');
- eFlags.appendChild(opt);
- const lbl = nbspPad(f)+flags[f];
- //opt.innerText = lbl;
- opt.innerHTML = lbl;
- opt.value = f;
- if(preselectedFlags.indexOf(f) >= 0) opt.selected = true;
+ const opt = document.createElement('option');
+ eFlags.appendChild(opt);
+ const lbl = nbspPad(f)+flags[f];
+ //opt.innerText = lbl;
+ opt.innerHTML = lbl;
+ opt.value = f;
+ if(preselectedFlags.indexOf(f) >= 0) opt.selected = true;
});
const cbReverseLog = E('#cb-reverse-log-order');
const lblReverseLog = E('#lbl-reverse-log-order');
if(cbReverseLog.checked){
- lblReverseLog.classList.add('warning');
- eOut.classList.add('reverse');
+ lblReverseLog.classList.add('warning');
+ eOut.classList.add('reverse');
}
cbReverseLog.addEventListener('change', function(){
- if(this.checked){
- eOut.classList.add('reverse');
- lblReverseLog.classList.add('warning');
- }else{
- eOut.classList.remove('reverse');
- lblReverseLog.classList.remove('warning');
- }
+ if(this.checked){
+ eOut.classList.add('reverse');
+ lblReverseLog.classList.add('warning');
+ }else{
+ eOut.classList.remove('reverse');
+ lblReverseLog.classList.remove('warning');
+ }
}, false);
updateSelectedFlags();
- }
- E('#btn-output-clear').addEventListener('click', ()=>{
+ }
+ E('#btn-output-clear').addEventListener('click', ()=>{
eOut.innerText = '';
- });
- E('#btn-reset-flags').addEventListener('click',()=>{
+ });
+ E('#btn-reset-flags').addEventListener('click',()=>{
eFlags.value = '';
updateSelectedFlags();
- });
- E('#btn-run').addEventListener('click',function(){
+ });
+ E('#btn-run').addEventListener('click',function(){
log("Running speedtest1. UI controls will be disabled until it completes.");
mPost('run', getSelectedFlags());
- });
+ });
- const eControls = E('#ui-controls');
- /** Update Emscripten-related UI elements while loading the module. */
- const updateLoadStatus = function f(text){
+ const eControls = E('#ui-controls');
+ /** Update Emscripten-related UI elements while loading the module. */
+ const updateLoadStatus = function f(text){
if(!f.last){
- f.last = { text: '', step: 0 };
- const E = (cssSelector)=>document.querySelector(cssSelector);
- f.ui = {
- status: E('#module-status'),
- progress: E('#module-progress'),
- spinner: E('#module-spinner')
- };
+ f.last = { text: '', step: 0 };
+ const E = (cssSelector)=>document.querySelector(cssSelector);
+ f.ui = {
+ status: E('#module-status'),
+ progress: E('#module-progress'),
+ spinner: E('#module-spinner')
+ };
}
if(text === f.last.text) return;
f.last.text = text;
if(f.ui.progress){
- f.ui.progress.value = f.last.step;
- f.ui.progress.max = f.last.step + 1;
+ f.ui.progress.value = f.last.step;
+ f.ui.progress.max = f.last.step + 1;
}
++f.last.step;
if(text) {
- f.ui.status.classList.remove('hidden');
- f.ui.status.innerText = text;
+ f.ui.status.classList.remove('hidden');
+ f.ui.status.innerText = text;
}else{
- if(f.ui.progress){
- f.ui.progress.remove();
- f.ui.spinner.remove();
- delete f.ui.progress;
- delete f.ui.spinner;
- }
- f.ui.status.classList.add('hidden');
+ if(f.ui.progress){
+ f.ui.progress.remove();
+ f.ui.spinner.remove();
+ delete f.ui.progress;
+ delete f.ui.spinner;
+ }
+ f.ui.status.classList.add('hidden');
}
- };
+ };
- W.onmessage = function(msg){
+ W.onmessage = function(msg){
msg = msg.data;
switch(msg.type){
case 'ready':
- log("Worker is ready.");
- eControls.classList.remove('hidden');
- break;
+ log("Worker is ready.");
+ eControls.classList.remove('hidden');
+ break;
case 'stdout': log(msg.data); break;
case 'stdout': logErr(msg.data); break;
case 'run-start':
- eControls.disabled = true;
- log("Running speedtest1 with argv =",msg.data.join(' '));
- break;
+ eControls.disabled = true;
+ log("Running speedtest1 with argv =",msg.data.join(' '));
+ break;
case 'run-end':
- log("speedtest1 finished.");
- eControls.disabled = false;
- // app output is in msg.data
- break;
+ log("speedtest1 finished.");
+ eControls.disabled = false;
+ // app output is in msg.data
+ break;
case 'error': logErr(msg.data); break;
case 'load-status': updateLoadStatus(msg.data); break;
default:
- logErr("Unhandled worker message type:",msg);
- break;
+ logErr("Unhandled worker message type:",msg);
+ break;
}
- };
- })();</script>
+ };
+})();</script>
</body>
</html>
diff --git a/ext/wasm/speedtest1-worker.js b/ext/wasm/speedtest1-worker.js
index b697d6925..78e2db57f 100644
--- a/ext/wasm/speedtest1-worker.js
+++ b/ext/wasm/speedtest1-worker.js
@@ -8,7 +8,7 @@
*/
const wasmfsDir = function f(wasmUtil){
if(undefined !== f._) return f._;
- const pdir = '/persistent';
+ const pdir = '/opfs';
if( !self.FileSystemHandle
|| !self.FileSystemDirectoryHandle
|| !self.FileSystemFileHandle){
diff --git a/ext/wasm/speedtest1.html b/ext/wasm/speedtest1.html
index 08195f2b1..6c2853a73 100644
--- a/ext/wasm/speedtest1.html
+++ b/ext/wasm/speedtest1.html
@@ -39,131 +39,136 @@
<script src="common/SqliteTestUtil.js"></script>
<script src="speedtest1.js"></script>
<script>(function(){
- /**
- If this environment contains OPFS, this function initializes it and
- returns the name of the dir on which OPFS is mounted, else it returns
- an empty string.
- */
- const wasmfsDir = function f(wasmUtil){
- if(undefined !== f._) return f._;
- const pdir = '/persistent';
- if( !self.FileSystemHandle
- || !self.FileSystemDirectoryHandle
- || !self.FileSystemFileHandle){
+ /**
+ If this environment contains OPFS, this function initializes it and
+ returns the name of the dir on which OPFS is mounted, else it returns
+ an empty string.
+ */
+ const wasmfsDir = function f(wasmUtil){
+ if(undefined !== f._) return f._;
+ const pdir = '/persistent';
+ if( !self.FileSystemHandle
+ || !self.FileSystemDirectoryHandle
+ || !self.FileSystemFileHandle){
return f._ = "";
- }
- try{
+ }
+ try{
if(0===wasmUtil.xCallWrapped(
- 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
+ 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], pdir
)){
- return f._ = pdir;
+ return f._ = pdir;
}else{
- return f._ = "";
+ return f._ = "";
}
- }catch(e){
+ }catch(e){
// sqlite3_wasm_init_wasmfs() is not available
return f._ = "";
- }
- };
- wasmfsDir._ = undefined;
+ }
+ };
+ wasmfsDir._ = undefined;
- const eOut = document.querySelector('#test-output');
- const log2 = function(cssClass,...args){
- const ln = document.createElement('div');
- if(cssClass) ln.classList.add(cssClass);
- ln.append(document.createTextNode(args.join(' ')));
- eOut.append(ln);
- //this.e.output.lastElementChild.scrollIntoViewIfNeeded();
- };
- const logList = [];
- const dumpLogList = function(){
- logList.forEach((v)=>log2('',v));
- logList.length = 0;
- };
- /* can't update DOM while speedtest is running unless we run
- speedtest in a worker thread. */;
- const log = (...args)=>{
- console.log(...args);
- logList.push(args.join(' '));
- };
- const logErr = function(...args){
- console.error(...args);
- logList.push('ERROR: '+args.join(' '));
- };
+ const eOut = document.querySelector('#test-output');
+ const log2 = function(cssClass,...args){
+ const ln = document.createElement('div');
+ if(cssClass) ln.classList.add(cssClass);
+ ln.append(document.createTextNode(args.join(' ')));
+ eOut.append(ln);
+ //this.e.output.lastElementChild.scrollIntoViewIfNeeded();
+ };
+ const logList = [];
+ const dumpLogList = function(){
+ logList.forEach((v)=>log2('',v));
+ logList.length = 0;
+ };
+ /* can't update DOM while speedtest is running unless we run
+ speedtest in a worker thread. */;
+ const log = (...args)=>{
+ console.log(...args);
+ logList.push(args.join(' '));
+ };
+ const logErr = function(...args){
+ console.error(...args);
+ logList.push('ERROR: '+args.join(' '));
+ };
- const runTests = function(sqlite3){
- const capi = sqlite3.capi, wasm = capi.wasm;
- //console.debug('sqlite3 =',sqlite3);
- const unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["string"]);
- const pDir = wasmfsDir(wasm);
- if(pDir){
+ const runTests = function(sqlite3){
+ const capi = sqlite3.capi, wasm = capi.wasm;
+ //console.debug('sqlite3 =',sqlite3);
+ const unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["string"]);
+ const pDir = wasmfsDir(wasm);
+ if(pDir){
console.warn("Persistent storage:",pDir);
- }
- const scope = wasm.scopedAllocPush();
- let dbFile = pDir+"/speedtest1.db";
- const urlParams = self.SqliteTestUtil.processUrlArgs();
- const argv = ["speedtest1"];
- if('string'===typeof urlParams.vfs){
- if(!capi.sqlite3_vfs_find(urlParams.vfs)){
- log2('error',"Unknown VFS:",urlParams.vfs);
- return;
- }
- argv.push("--vfs", urlParams.vfs);
- log2('',"Using VFS:",urlParams.vfs);
- if('kvvfs' === urlParams.vfs){
- urlParams.size = 2;
- dbFile = 'session';
- log2('warning',"kvvfs VFS: forcing --size",urlParams.size,
- "and filename '"+dbFile+"'.");
- capi.sqlite3_web_kvvfs_clear('session');
- }
- }
- [
- 'size'
- ].forEach(function(k){
- const v = urlParams[k];
- if(v) argv.push('--'+k, urlParams[k]);
- });
- if(urlParams.flags){
- argv.push(...(urlParams.flags.split(',')));
- }else{
- argv.push(
- "--singlethread",
- //"--nomutex",
- //"--nosync",
- "--nomemstat"
- );
+ }
+ const scope = wasm.scopedAllocPush();
+ let dbFile = pDir+"/speedtest1.db";
+ const urlParams = new URL(self.location.href).searchParams;
+ const argv = ["speedtest1"];
+ if(urlParams.has('flags')){
+ argv.push(...(urlParams.get('flags').split(',')));
+ }
+
+ let forceSize = 0;
+ if(urlParams.has('vfs')){
+ const vfs = urlParams.get('vfs');
+ if(!capi.sqlite3_vfs_find(vfs)){
+ log2('error',"Unknown VFS:",vfs);
+ return;
+ }
+ argv.push("--vfs", vfs);
+ log2('',"Using VFS:",vfs);
+ if('kvvfs' === vfs){
+ forceSize = 2;
+ dbFile = 'session';
+ log2('warning',"kvvfs VFS: forcing --size",forceSize,
+ "and filename '"+dbFile+"'.");
+ capi.sqlite3_web_kvvfs_clear(dbFile);
+ }
+ }
+ if(forceSize){
+ argv.push('--size',forceSize);
+ }else{
+ [
+ 'size'
+ ].forEach(function(k){
+ const v = urlParams.get(k);
+ if(v) argv.push('--'+k, urlParams[k]);
+ });
+ }
+ argv.push(
+ "--singlethread",
+ //"--nomutex",
+ //"--nosync",
//"--memdb", // note that memdb trumps the filename arg
- }
- argv.push("--big-transactions"/*important for tests 410 and 510!*/,
- dbFile);
- console.log("argv =",argv);
- // These log messages are not emitted to the UI until after main() returns. Fixing that
- // requires moving the main() call and related cleanup into a timeout handler.
- if(pDir) unlink(dbFile);
- log2('',"Starting native app:\n ",argv.join(' '));
- log2('',"This will take a while and the browser might warn about the runaway JS.",
- "Give it time...");
- logList.length = 0;
- setTimeout(function(){
- wasm.xCall('wasm_main', argv.length,
- wasm.scopedAllocMainArgv(argv));
- wasm.scopedAllocPop(scope);
- if(pDir) unlink(dbFile);
- logList.unshift("Done running native main(). Output:");
- dumpLogList();
- }, 50);
- }/*runTests()*/;
+ "--nomemstat"
+ );
+ argv.push("--big-transactions"/*important for tests 410 and 510!*/,
+ dbFile);
+ console.log("argv =",argv);
+ // These log messages are not emitted to the UI until after main() returns. Fixing that
+ // requires moving the main() call and related cleanup into a timeout handler.
+ if(pDir) unlink(dbFile);
+ log2('',"Starting native app:\n ",argv.join(' '));
+ log2('',"This will take a while and the browser might warn about the runaway JS.",
+ "Give it time...");
+ logList.length = 0;
+ setTimeout(function(){
+ wasm.xCall('wasm_main', argv.length,
+ wasm.scopedAllocMainArgv(argv));
+ wasm.scopedAllocPop(scope);
+ if(pDir) unlink(dbFile);
+ logList.unshift("Done running native main(). Output:");
+ dumpLogList();
+ }, 50);
+ }/*runTests()*/;
- self.sqlite3TestModule.print = log;
- self.sqlite3TestModule.printErr = logErr;
- sqlite3Speedtest1InitModule(self.sqlite3TestModule)
+ self.sqlite3TestModule.print = log;
+ self.sqlite3TestModule.printErr = logErr;
+ sqlite3Speedtest1InitModule(self.sqlite3TestModule)
.then((EmscriptenModule)=>{
return EmscriptenModule.sqlite3.installOpfsVfs()
.catch((e)=>{console.warn(e.message)})
.then(()=>runTests(EmscriptenModule.sqlite3));
});
- })();
- </script>
- </body>
+})();</script>
+</body>
</html>