mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-27 20:41:58 +03:00
Build fiddle with WASMFS OPFS support and attempt to use it if available. It does not work because of an inexplicable exception in Emscripten-generated code and perpetually-locked db, but it's not yet clear why.
FossilOrigin-Name: a16f0a46ec88c560f73d5664e4bf53fb5dd1a22e99a92c11b5c8d784816c3282
This commit is contained in:
12
Makefile.in
12
Makefile.in
@ -1540,25 +1540,29 @@ fiddle_module_js = $(fiddle_dir)/fiddle-module.js
|
|||||||
#emcc_opt = -O2
|
#emcc_opt = -O2
|
||||||
#emcc_opt = -O3
|
#emcc_opt = -O3
|
||||||
emcc_opt = -Oz
|
emcc_opt = -Oz
|
||||||
|
emcc_flags_opfs = -sWASMFS -pthread
|
||||||
emcc_flags = $(emcc_opt) \
|
emcc_flags = $(emcc_opt) \
|
||||||
-sALLOW_TABLE_GROWTH \
|
-sALLOW_TABLE_GROWTH \
|
||||||
-sABORTING_MALLOC \
|
-sABORTING_MALLOC \
|
||||||
-sSTRICT_JS \
|
-sSTRICT_JS \
|
||||||
-sENVIRONMENT=web \
|
-sENVIRONMENT=web,worker \
|
||||||
-sMODULARIZE \
|
-sMODULARIZE \
|
||||||
-sEXPORTED_RUNTIME_METHODS=@$(wasm_dir_abs)/EXPORTED_RUNTIME_METHODS.fiddle \
|
-sEXPORTED_RUNTIME_METHODS=@$(wasm_dir_abs)/EXPORTED_RUNTIME_METHODS.fiddle \
|
||||||
-sDYNAMIC_EXECUTION=0 \
|
-sDYNAMIC_EXECUTION=0 \
|
||||||
--minify 0 \
|
--minify 0 \
|
||||||
-I. $(SHELL_OPT) \
|
-I. $(SHELL_OPT) \
|
||||||
-DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_UTF16 -DSQLITE_OMIT_DEPRECATED
|
-DSQLITE_THREADSAFE=0 \
|
||||||
$(fiddle_module_js): Makefile sqlite3.c shell.c \
|
-DSQLITE_OMIT_UTF16 \
|
||||||
|
-DSQLITE_OMIT_DEPRECATED \
|
||||||
|
$(emcc_flags_opfs)
|
||||||
|
$(fiddle_module_js): Makefile $(wasm_dir)/api/sqlite3-wasm.c shell.c \
|
||||||
$(wasm_dir)/EXPORTED_RUNTIME_METHODS.fiddle \
|
$(wasm_dir)/EXPORTED_RUNTIME_METHODS.fiddle \
|
||||||
$(wasm_dir)/EXPORTED_FUNCTIONS.fiddle
|
$(wasm_dir)/EXPORTED_FUNCTIONS.fiddle
|
||||||
emcc -o $@ $(emcc_flags) \
|
emcc -o $@ $(emcc_flags) \
|
||||||
-sEXPORT_NAME=initFiddleModule \
|
-sEXPORT_NAME=initFiddleModule \
|
||||||
-sEXPORTED_FUNCTIONS=@$(wasm_dir_abs)/EXPORTED_FUNCTIONS.fiddle \
|
-sEXPORTED_FUNCTIONS=@$(wasm_dir_abs)/EXPORTED_FUNCTIONS.fiddle \
|
||||||
-DSQLITE_SHELL_FIDDLE \
|
-DSQLITE_SHELL_FIDDLE \
|
||||||
sqlite3.c shell.c
|
$(wasm_dir)/api/sqlite3-wasm.c shell.c
|
||||||
gzip < $@ > $@.gz
|
gzip < $@ > $@.gz
|
||||||
gzip < $(fiddle_dir)/fiddle-module.wasm > $(fiddle_dir)/fiddle-module.wasm.gz
|
gzip < $(fiddle_dir)/fiddle-module.wasm > $(fiddle_dir)/fiddle-module.wasm.gz
|
||||||
$(fiddle_dir)/fiddle.js.gz: $(fiddle_dir)/fiddle.js
|
$(fiddle_dir)/fiddle.js.gz: $(fiddle_dir)/fiddle.js
|
||||||
|
@ -5,3 +5,5 @@ _fiddle_the_db
|
|||||||
_fiddle_db_arg
|
_fiddle_db_arg
|
||||||
_fiddle_db_filename
|
_fiddle_db_filename
|
||||||
_fiddle_reset_db
|
_fiddle_reset_db
|
||||||
|
_sqlite3_wasm_init_opfs
|
||||||
|
_sqlite3_wasm_vfs_unlink
|
||||||
|
@ -168,12 +168,13 @@ emcc.cflags :=
|
|||||||
emcc.cflags += -std=c99 -fPIC
|
emcc.cflags += -std=c99 -fPIC
|
||||||
# -------------^^^^^^^^ we currently need c99 for WASM-specific sqlite3 APIs.
|
# -------------^^^^^^^^ we currently need c99 for WASM-specific sqlite3 APIs.
|
||||||
emcc.cflags += -I. -I$(dir.top) # $(SQLITE_OPT)
|
emcc.cflags += -I. -I$(dir.top) # $(SQLITE_OPT)
|
||||||
|
emcc.cflags += -pthread
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# emcc flags specific to building the final .js/.wasm file...
|
# emcc flags specific to building the final .js/.wasm file...
|
||||||
emcc.jsflags := -fPIC
|
emcc.jsflags := -fPIC
|
||||||
emcc.jsflags += --no-entry
|
emcc.jsflags += --no-entry
|
||||||
emcc.jsflags += -sENVIRONMENT=web
|
emcc.jsflags += -sENVIRONMENT=web,worker
|
||||||
emcc.jsflags += -sMODULARIZE
|
emcc.jsflags += -sMODULARIZE
|
||||||
emcc.jsflags += -sSTRICT_JS
|
emcc.jsflags += -sSTRICT_JS
|
||||||
emcc.jsflags += -sDYNAMIC_EXECUTION=0
|
emcc.jsflags += -sDYNAMIC_EXECUTION=0
|
||||||
@ -182,6 +183,7 @@ emcc.jsflags += -sEXPORTED_FUNCTIONS=@$(dir.wasm)/EXPORTED_FUNCTIONS.api
|
|||||||
emcc.jsflags += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory # wasmMemory==>for -sIMPORTED_MEMORY
|
emcc.jsflags += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory # wasmMemory==>for -sIMPORTED_MEMORY
|
||||||
emcc.jsflags += -sUSE_CLOSURE_COMPILER=0
|
emcc.jsflags += -sUSE_CLOSURE_COMPILER=0
|
||||||
emcc.jsflags += -sIMPORTED_MEMORY
|
emcc.jsflags += -sIMPORTED_MEMORY
|
||||||
|
emcc.jsflags += -pthread -sWASMFS
|
||||||
#emcc.jsflags += -sINITIAL_MEMORY=13107200
|
#emcc.jsflags += -sINITIAL_MEMORY=13107200
|
||||||
#emcc.jsflags += -sTOTAL_STACK=4194304
|
#emcc.jsflags += -sTOTAL_STACK=4194304
|
||||||
emcc.jsflags += -sEXPORT_NAME=sqlite3InitModule
|
emcc.jsflags += -sEXPORT_NAME=sqlite3InitModule
|
||||||
|
@ -68,5 +68,7 @@ _sqlite3_vfs_find
|
|||||||
_sqlite3_vfs_register
|
_sqlite3_vfs_register
|
||||||
_sqlite3_wasm_db_error
|
_sqlite3_wasm_db_error
|
||||||
_sqlite3_wasm_enum_json
|
_sqlite3_wasm_enum_json
|
||||||
|
_sqlite3_wasm_init_opfs
|
||||||
|
_sqlite3_wasm_vfs_unlink
|
||||||
_malloc
|
_malloc
|
||||||
_free
|
_free
|
||||||
|
@ -411,3 +411,49 @@ const char * sqlite3_wasm_enum_json(void){
|
|||||||
#undef outf
|
#undef outf
|
||||||
#undef lenCheck
|
#undef lenCheck
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** This function is NOT part of the sqlite3 public API. It is strictly
|
||||||
|
** for use by the sqlite project's own JS/WASM bindings.
|
||||||
|
**
|
||||||
|
** This function invokes the xDelete method of the default VFS,
|
||||||
|
** passing on the given filename. If zName is NULL, no default VFS is
|
||||||
|
** found, or it has no xDelete method, SQLITE_MISUSE is returned, else
|
||||||
|
** the result of the xDelete() call is returned.
|
||||||
|
*/
|
||||||
|
int sqlite3_wasm_vfs_unlink(const char * zName){
|
||||||
|
int rc = SQLITE_MISUSE /* ??? */;
|
||||||
|
sqlite3_vfs * const pVfs = sqlite3_vfs_find(0);
|
||||||
|
if( zName && pVfs && pVfs->xDelete ){
|
||||||
|
rc = pVfs->xDelete(pVfs, zName, 1);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#include <emscripten/wasmfs.h>
|
||||||
|
#include <emscripten/console.h>
|
||||||
|
/*
|
||||||
|
** This function is NOT part of the sqlite3 public API. It is strictly
|
||||||
|
** for use by the sqlite project's own JS/WASM bindings.
|
||||||
|
**
|
||||||
|
** This function should only be called if the JS side detects the
|
||||||
|
** existence of the Origin-Private FileSystem (OPFS) APIs in the
|
||||||
|
** client. The first time it is called, this function instantiates a
|
||||||
|
** WASMFS backend impl for OPFS. On success, subsequent calls are
|
||||||
|
** no-ops.
|
||||||
|
**
|
||||||
|
** Returns 0 on success, SQLITE_NOMEM if intantiation of the backend
|
||||||
|
** object fails.
|
||||||
|
*/
|
||||||
|
int sqlite3_wasm_init_opfs(void){
|
||||||
|
static backend_t pOpfs = 0;
|
||||||
|
if( !pOpfs ){
|
||||||
|
pOpfs = wasmfs_create_opfs_backend();
|
||||||
|
if( pOpfs ){
|
||||||
|
emscripten_console_log("Created OPFS WASMFS backend.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pOpfs ? 0 : SQLITE_NOMEM;
|
||||||
|
}
|
||||||
|
#endif /* __EMSCRIPTEN__ */
|
||||||
|
@ -89,213 +89,230 @@
|
|||||||
*/
|
*/
|
||||||
"use strict";
|
"use strict";
|
||||||
(function(){
|
(function(){
|
||||||
/**
|
/**
|
||||||
Posts a message in the form {type,data} unless passed more than 2
|
Posts a message in the form {type,data} unless passed more than 2
|
||||||
args, in which case it posts {type, data:[arg1...argN]}.
|
args, in which case it posts {type, data:[arg1...argN]}.
|
||||||
*/
|
*/
|
||||||
const wMsg = function(type,data){
|
const wMsg = function(type,data){
|
||||||
postMessage({
|
postMessage({
|
||||||
type,
|
type,
|
||||||
data: arguments.length<3
|
data: arguments.length<3
|
||||||
? data
|
? data
|
||||||
: Array.prototype.slice.call(arguments,1)
|
: Array.prototype.slice.call(arguments,1)
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const stdout = function(){wMsg('stdout', Array.prototype.slice.call(arguments));};
|
|
||||||
const stderr = function(){wMsg('stderr', Array.prototype.slice.call(arguments));};
|
|
||||||
|
|
||||||
self.onerror = function(/*message, source, lineno, colno, error*/) {
|
|
||||||
const err = arguments[4];
|
|
||||||
if(err && 'ExitStatus'==err.name){
|
|
||||||
/* This is relevant for the sqlite3 shell binding but not the
|
|
||||||
lower-level binding. */
|
|
||||||
fiddleModule.isDead = true;
|
|
||||||
stderr("FATAL ERROR:", err.message);
|
|
||||||
stderr("Restarting the app requires reloading the page.");
|
|
||||||
wMsg('error', err);
|
|
||||||
}
|
|
||||||
console.error(err);
|
|
||||||
fiddleModule.setStatus('Exception thrown, see JavaScript console: '+err);
|
|
||||||
};
|
|
||||||
|
|
||||||
const Sqlite3Shell = {
|
|
||||||
/** Returns the name of the currently-opened db. */
|
|
||||||
dbFilename: function f(){
|
|
||||||
if(!f._) f._ = fiddleModule.cwrap('fiddle_db_filename', "string", ['string']);
|
|
||||||
return f._();
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
Runs the given text through the shell as if it had been typed
|
|
||||||
in by a user. Fires a working/start event before it starts and
|
|
||||||
working/end event when it finishes.
|
|
||||||
*/
|
|
||||||
exec: function f(sql){
|
|
||||||
if(!f._) f._ = fiddleModule.cwrap('fiddle_exec', null, ['string']);
|
|
||||||
if(fiddleModule.isDead){
|
|
||||||
stderr("shell module has exit()ed. Cannot run SQL.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
wMsg('working','start');
|
|
||||||
try {
|
|
||||||
if(f._running){
|
|
||||||
stderr('Cannot run multiple commands concurrently.');
|
|
||||||
}else{
|
|
||||||
f._running = true;
|
|
||||||
f._(sql);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
delete f._running;
|
|
||||||
wMsg('working','end');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
resetDb: function f(){
|
|
||||||
if(!f._) f._ = fiddleModule.cwrap('fiddle_reset_db', null);
|
|
||||||
stdout("Resetting database.");
|
|
||||||
f._();
|
|
||||||
stdout("Reset",this.dbFilename());
|
|
||||||
},
|
|
||||||
/* Interrupt can't work: this Worker is tied up working, so won't get the
|
|
||||||
interrupt event which would be needed to perform the interrupt. */
|
|
||||||
interrupt: function f(){
|
|
||||||
if(!f._) f._ = fiddleModule.cwrap('fiddle_interrupt', null);
|
|
||||||
stdout("Requesting interrupt.");
|
|
||||||
f._();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.onmessage = function f(ev){
|
|
||||||
ev = ev.data;
|
|
||||||
if(!f.cache){
|
|
||||||
f.cache = {
|
|
||||||
prevFilename: null
|
|
||||||
};
|
|
||||||
}
|
|
||||||
//console.debug("worker: onmessage.data",ev);
|
|
||||||
switch(ev.type){
|
|
||||||
case 'shellExec': Sqlite3Shell.exec(ev.data); return;
|
|
||||||
case 'db-reset': Sqlite3Shell.resetDb(); return;
|
|
||||||
case 'interrupt': Sqlite3Shell.interrupt(); return;
|
|
||||||
/** Triggers the export of the current db. Fires an
|
|
||||||
event in the form:
|
|
||||||
|
|
||||||
{type:'db-export',
|
|
||||||
data:{
|
|
||||||
filename: name of db,
|
|
||||||
buffer: contents of the db file (Uint8Array),
|
|
||||||
error: on error, a message string and no buffer property.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
case 'db-export': {
|
|
||||||
const fn = Sqlite3Shell.dbFilename();
|
|
||||||
stdout("Exporting",fn+".");
|
|
||||||
const fn2 = fn ? fn.split(/[/\\]/).pop() : null;
|
|
||||||
try{
|
|
||||||
if(!fn2) throw new Error("DB appears to be closed.");
|
|
||||||
wMsg('db-export',{
|
|
||||||
filename: fn2,
|
|
||||||
buffer: fiddleModule.FS.readFile(fn, {encoding:"binary"})
|
|
||||||
});
|
|
||||||
}catch(e){
|
|
||||||
/* Post a failure message so that UI elements disabled
|
|
||||||
during the export can be re-enabled. */
|
|
||||||
wMsg('db-export',{
|
|
||||||
filename: fn,
|
|
||||||
error: e.message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case 'open': {
|
|
||||||
/* Expects: {
|
|
||||||
buffer: ArrayBuffer | Uint8Array,
|
|
||||||
filename: for logging/informational purposes only
|
|
||||||
} */
|
|
||||||
const opt = ev.data;
|
|
||||||
let buffer = opt.buffer;
|
|
||||||
if(buffer instanceof Uint8Array){
|
|
||||||
}else if(buffer instanceof ArrayBuffer){
|
|
||||||
buffer = new Uint8Array(buffer);
|
|
||||||
}else{
|
|
||||||
stderr("'open' expects {buffer:Uint8Array} containing an uploaded db.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const fn = (
|
|
||||||
opt.filename
|
|
||||||
? opt.filename.split(/[/\\]/).pop().replace('"','_')
|
|
||||||
: ("db-"+((Math.random() * 10000000) | 0)+
|
|
||||||
"-"+((Math.random() * 10000000) | 0)+".sqlite3")
|
|
||||||
);
|
|
||||||
/* We cannot delete the existing db file until the new one
|
|
||||||
is installed, which means that we risk overflowing our
|
|
||||||
quota (if any) by having both the previous and current
|
|
||||||
db briefly installed in the virtual filesystem. */
|
|
||||||
fiddleModule.FS.createDataFile("/", fn, buffer, true, true);
|
|
||||||
const oldName = Sqlite3Shell.dbFilename();
|
|
||||||
Sqlite3Shell.exec('.open "/'+fn+'"');
|
|
||||||
if(oldName && oldName !== fn){
|
|
||||||
try{fiddleModule.FS.unlink(oldName);}
|
|
||||||
catch(e){/*ignored*/}
|
|
||||||
}
|
|
||||||
stdout("Replaced DB with",fn+".");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
console.warn("Unknown fiddle-worker message type:",ev);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
emscripten module for use with build mode -sMODULARIZE.
|
|
||||||
*/
|
|
||||||
const fiddleModule = {
|
|
||||||
print: stdout,
|
|
||||||
printErr: stderr,
|
|
||||||
/**
|
|
||||||
Intercepts status updates from the emscripting module init
|
|
||||||
and fires worker events with a type of 'status' and a
|
|
||||||
payload of:
|
|
||||||
|
|
||||||
{
|
|
||||||
text: string | null, // null at end of load process
|
|
||||||
step: integer // starts at 1, increments 1 per call
|
|
||||||
}
|
|
||||||
|
|
||||||
We have no way of knowing in advance how many steps will
|
|
||||||
be processed/posted, so creating a "percentage done" view is
|
|
||||||
not really practical. One can be approximated by giving it a
|
|
||||||
current value of message.step and max value of message.step+1,
|
|
||||||
though.
|
|
||||||
|
|
||||||
When work is finished, a message with a text value of null is
|
|
||||||
submitted.
|
|
||||||
|
|
||||||
After a message with text==null is posted, the module may later
|
|
||||||
post messages about fatal problems, e.g. an exit() being
|
|
||||||
triggered, so it is recommended that UI elements for posting
|
|
||||||
status messages not be outright removed from the DOM when
|
|
||||||
text==null, and that they instead be hidden until/unless
|
|
||||||
text!=null.
|
|
||||||
*/
|
|
||||||
setStatus: function f(text){
|
|
||||||
if(!f.last) f.last = { step: 0, text: '' };
|
|
||||||
else if(text === f.last.text) return;
|
|
||||||
f.last.text = text;
|
|
||||||
wMsg('module',{
|
|
||||||
type:'status',
|
|
||||||
data:{step: ++f.last.step, text: text||null}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
importScripts('fiddle-module.js');
|
|
||||||
/**
|
|
||||||
initFiddleModule() is installed via fiddle-module.js due to
|
|
||||||
building with:
|
|
||||||
|
|
||||||
emcc ... -sMODULARIZE=1 -sEXPORT_NAME=initFiddleModule
|
|
||||||
*/
|
|
||||||
initFiddleModule(fiddleModule).then(function(thisModule){
|
|
||||||
wMsg('fiddle-ready');
|
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const stdout = function(){wMsg('stdout', Array.prototype.slice.call(arguments));};
|
||||||
|
const stderr = function(){wMsg('stderr', Array.prototype.slice.call(arguments));};
|
||||||
|
|
||||||
|
self.onerror = function(/*message, source, lineno, colno, error*/) {
|
||||||
|
const err = arguments[4];
|
||||||
|
if(err && 'ExitStatus'==err.name){
|
||||||
|
/* This is relevant for the sqlite3 shell binding but not the
|
||||||
|
lower-level binding. */
|
||||||
|
fiddleModule.isDead = true;
|
||||||
|
stderr("FATAL ERROR:", err.message);
|
||||||
|
stderr("Restarting the app requires reloading the page.");
|
||||||
|
wMsg('error', err);
|
||||||
|
}
|
||||||
|
console.error(err);
|
||||||
|
fiddleModule.setStatus('Exception thrown, see JavaScript console: '+err);
|
||||||
|
};
|
||||||
|
|
||||||
|
const Sqlite3Shell = {
|
||||||
|
/** Returns the name of the currently-opened db. */
|
||||||
|
dbFilename: function f(){
|
||||||
|
if(!f._) f._ = fiddleModule.cwrap('fiddle_db_filename', "string", ['string']);
|
||||||
|
return f._();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
Runs the given text through the shell as if it had been typed
|
||||||
|
in by a user. Fires a working/start event before it starts and
|
||||||
|
working/end event when it finishes.
|
||||||
|
*/
|
||||||
|
exec: function f(sql){
|
||||||
|
if(!f._) f._ = fiddleModule.cwrap('fiddle_exec', null, ['string']);
|
||||||
|
if(fiddleModule.isDead){
|
||||||
|
stderr("shell module has exit()ed. Cannot run SQL.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
wMsg('working','start');
|
||||||
|
try {
|
||||||
|
if(f._running){
|
||||||
|
stderr('Cannot run multiple commands concurrently.');
|
||||||
|
}else{
|
||||||
|
f._running = true;
|
||||||
|
f._(sql);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
delete f._running;
|
||||||
|
wMsg('working','end');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetDb: function f(){
|
||||||
|
if(!f._) f._ = fiddleModule.cwrap('fiddle_reset_db', null);
|
||||||
|
stdout("Resetting database.");
|
||||||
|
f._();
|
||||||
|
stdout("Reset",this.dbFilename());
|
||||||
|
},
|
||||||
|
/* Interrupt can't work: this Worker is tied up working, so won't get the
|
||||||
|
interrupt event which would be needed to perform the interrupt. */
|
||||||
|
interrupt: function f(){
|
||||||
|
if(!f._) f._ = fiddleModule.cwrap('fiddle_interrupt', null);
|
||||||
|
stdout("Requesting interrupt.");
|
||||||
|
f._();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.onmessage = function f(ev){
|
||||||
|
ev = ev.data;
|
||||||
|
if(!f.cache){
|
||||||
|
f.cache = {
|
||||||
|
prevFilename: null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//console.debug("worker: onmessage.data",ev);
|
||||||
|
switch(ev.type){
|
||||||
|
case 'shellExec': Sqlite3Shell.exec(ev.data); return;
|
||||||
|
case 'db-reset': Sqlite3Shell.resetDb(); return;
|
||||||
|
case 'interrupt': Sqlite3Shell.interrupt(); return;
|
||||||
|
/** Triggers the export of the current db. Fires an
|
||||||
|
event in the form:
|
||||||
|
|
||||||
|
{type:'db-export',
|
||||||
|
data:{
|
||||||
|
filename: name of db,
|
||||||
|
buffer: contents of the db file (Uint8Array),
|
||||||
|
error: on error, a message string and no buffer property.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
case 'db-export': {
|
||||||
|
const fn = Sqlite3Shell.dbFilename();
|
||||||
|
stdout("Exporting",fn+".");
|
||||||
|
const fn2 = fn ? fn.split(/[/\\]/).pop() : null;
|
||||||
|
try{
|
||||||
|
if(!fn2) throw new Error("DB appears to be closed.");
|
||||||
|
wMsg('db-export',{
|
||||||
|
filename: fn2,
|
||||||
|
buffer: fiddleModule.FS.readFile(fn, {encoding:"binary"})
|
||||||
|
});
|
||||||
|
}catch(e){
|
||||||
|
/* Post a failure message so that UI elements disabled
|
||||||
|
during the export can be re-enabled. */
|
||||||
|
wMsg('db-export',{
|
||||||
|
filename: fn,
|
||||||
|
error: e.message
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 'open': {
|
||||||
|
/* Expects: {
|
||||||
|
buffer: ArrayBuffer | Uint8Array,
|
||||||
|
filename: for logging/informational purposes only
|
||||||
|
} */
|
||||||
|
const opt = ev.data;
|
||||||
|
let buffer = opt.buffer;
|
||||||
|
if(buffer instanceof Uint8Array){
|
||||||
|
}else if(buffer instanceof ArrayBuffer){
|
||||||
|
buffer = new Uint8Array(buffer);
|
||||||
|
}else{
|
||||||
|
stderr("'open' expects {buffer:Uint8Array} containing an uploaded db.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const fn = (
|
||||||
|
opt.filename
|
||||||
|
? opt.filename.split(/[/\\]/).pop().replace('"','_')
|
||||||
|
: ("db-"+((Math.random() * 10000000) | 0)+
|
||||||
|
"-"+((Math.random() * 10000000) | 0)+".sqlite3")
|
||||||
|
);
|
||||||
|
/* We cannot delete the existing db file until the new one
|
||||||
|
is installed, which means that we risk overflowing our
|
||||||
|
quota (if any) by having both the previous and current
|
||||||
|
db briefly installed in the virtual filesystem. */
|
||||||
|
fiddleModule.FS.createDataFile("/", fn, buffer, true, true);
|
||||||
|
const oldName = Sqlite3Shell.dbFilename();
|
||||||
|
Sqlite3Shell.exec('.open "/'+fn+'"');
|
||||||
|
if(oldName && oldName !== fn){
|
||||||
|
try{fiddleModule.fsUnlink(oldName);}
|
||||||
|
catch(e){/*ignored*/}
|
||||||
|
}
|
||||||
|
stdout("Replaced DB with",fn+".");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
console.warn("Unknown fiddle-worker message type:",ev);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
emscripten module for use with build mode -sMODULARIZE.
|
||||||
|
*/
|
||||||
|
const fiddleModule = {
|
||||||
|
print: stdout,
|
||||||
|
printErr: stderr,
|
||||||
|
/**
|
||||||
|
Intercepts status updates from the emscripting module init
|
||||||
|
and fires worker events with a type of 'status' and a
|
||||||
|
payload of:
|
||||||
|
|
||||||
|
{
|
||||||
|
text: string | null, // null at end of load process
|
||||||
|
step: integer // starts at 1, increments 1 per call
|
||||||
|
}
|
||||||
|
|
||||||
|
We have no way of knowing in advance how many steps will
|
||||||
|
be processed/posted, so creating a "percentage done" view is
|
||||||
|
not really practical. One can be approximated by giving it a
|
||||||
|
current value of message.step and max value of message.step+1,
|
||||||
|
though.
|
||||||
|
|
||||||
|
When work is finished, a message with a text value of null is
|
||||||
|
submitted.
|
||||||
|
|
||||||
|
After a message with text==null is posted, the module may later
|
||||||
|
post messages about fatal problems, e.g. an exit() being
|
||||||
|
triggered, so it is recommended that UI elements for posting
|
||||||
|
status messages not be outright removed from the DOM when
|
||||||
|
text==null, and that they instead be hidden until/unless
|
||||||
|
text!=null.
|
||||||
|
*/
|
||||||
|
setStatus: function f(text){
|
||||||
|
if(!f.last) f.last = { step: 0, text: '' };
|
||||||
|
else if(text === f.last.text) return;
|
||||||
|
f.last.text = text;
|
||||||
|
wMsg('module',{
|
||||||
|
type:'status',
|
||||||
|
data:{step: ++f.last.step, text: text||null}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
importScripts('fiddle-module.js');
|
||||||
|
/**
|
||||||
|
initFiddleModule() is installed via fiddle-module.js due to
|
||||||
|
building with:
|
||||||
|
|
||||||
|
emcc ... -sMODULARIZE=1 -sEXPORT_NAME=initFiddleModule
|
||||||
|
*/
|
||||||
|
initFiddleModule(fiddleModule).then(function(thisModule){
|
||||||
|
fiddleModule.fsUnlink = fiddleModule.cwrap('sqlite3_wasm_vfs_unlink','number',['string']);
|
||||||
|
(function initOpfs(){
|
||||||
|
if(!self.FileSystemHandle || !self.FileSystemDirectoryHandle
|
||||||
|
|| !self.FileSystemFileHandle){
|
||||||
|
stdout("OPFS unavailable. All DB state is transient.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if(0===fiddleModule.ccall('sqlite3_wasm_init_opfs', undefined)){
|
||||||
|
stdout("Initialized OPFS WASMFS backend.");
|
||||||
|
}else{
|
||||||
|
stderr("Initialization of OPFS WASMFS backend failed.");
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
stderr("Apparently missing WASMFS:",e.message);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
wMsg('fiddle-ready');
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
@ -775,7 +775,7 @@ SELECT group_concat(rtrim(t),x'0a') as Mandelbrot FROM a;`}
|
|||||||
});
|
});
|
||||||
})()/* example queries */;
|
})()/* example queries */;
|
||||||
|
|
||||||
SF.echo(null/*clear any output generated by the init process*/);
|
//SF.echo(null/*clear any output generated by the init process*/);
|
||||||
if(window.jQuery && window.jQuery.terminal){
|
if(window.jQuery && window.jQuery.terminal){
|
||||||
/* Set up the terminal-style view... */
|
/* Set up the terminal-style view... */
|
||||||
const eTerm = window.jQuery('#view-terminal').empty();
|
const eTerm = window.jQuery('#view-terminal').empty();
|
||||||
|
27
manifest
27
manifest
@ -1,9 +1,9 @@
|
|||||||
C Minor\swasm-related\sdoc\sclarification\sand\sremove\san\sobsolete\scode\scomment.
|
C Build\sfiddle\swith\sWASMFS\sOPFS\ssupport\sand\sattempt\sto\suse\sit\sif\savailable.\sIt\sdoes\snot\swork\sbecause\sof\san\sinexplicable\sexception\sin\sEmscripten-generated\scode\sand\sperpetually-locked\sdb,\sbut\sit's\snot\syet\sclear\swhy.
|
||||||
D 2022-08-12T17:55:18.237
|
D 2022-08-12T17:57:09.467
|
||||||
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
|
||||||
F Makefile.in eceb228bf7b48f961b59a508f42ffa1211bf0c4c5bc818807768cc7b187ab0c8
|
F Makefile.in bada766cb44d202e405eca68e32bb3bcf11cad5b85c75f7fb16ac39e863f03f5
|
||||||
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
||||||
F Makefile.msc d547a2fdba38a1c6cd1954977d0b0cc017f5f8fbfbc65287bf8d335808938016
|
F Makefile.msc d547a2fdba38a1c6cd1954977d0b0cc017f5f8fbfbc65287bf8d335808938016
|
||||||
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
|
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
|
||||||
@ -472,11 +472,11 @@ F ext/session/test_session.c f433f68a8a8c64b0f5bc74dc725078f12483301ad4ae8375205
|
|||||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
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 7fb73f7150ab79d83bb45a67d257553c905c78cd3d693101699243f36c5ae6c3
|
F ext/wasm/EXPORTED_FUNCTIONS.fiddle db7a4602f043cf4a5e4135be3609a487f9f1c83f05778bfbdf93766be4541b96
|
||||||
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02
|
F ext/wasm/EXPORTED_RUNTIME_METHODS.fiddle a004bd5eeeda6d3b28d16779b7f1a80305bfe009dfc7f0721b042967f0d39d02
|
||||||
F ext/wasm/GNUmakefile 5359a37fc13b68fad2259228590450339a0c59687744edd0db7bb93d3b1ae2b1
|
F ext/wasm/GNUmakefile c354ad5ce3ecec80c28ed4314827adc10cbbc0ef47e028b0cfbdf336c4a98fa4
|
||||||
F ext/wasm/README.md 4b00ae7c7d93c4591251245f0996a319e2651361013c98d2efb0b026771b7331
|
F ext/wasm/README.md 4b00ae7c7d93c4591251245f0996a319e2651361013c98d2efb0b026771b7331
|
||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api c5eaceabb9e759aaae7d3101a4a3e542f96ab2c99d89a80ce20ec18c23115f33
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api 77ef4bcf37e362b9ad61f9c175dfc0f1b3e571563fb311b96581cf422ee6a8ec
|
||||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||||
F ext/wasm/api/README.md b6d0fb64bfdf7bf9ce6938ea4104228f6f5bbef600f5d910b2f8c8694195988c
|
F ext/wasm/api/README.md b6d0fb64bfdf7bf9ce6938ea4104228f6f5bbef600f5d910b2f8c8694195988c
|
||||||
F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c
|
F ext/wasm/api/post-js-footer.js b64319261d920211b8700004d08b956a6c285f3b0bba81456260a713ed04900c
|
||||||
@ -488,16 +488,16 @@ F ext/wasm/api/sqlite3-api-opfs.js c93cdd14f81a26b3a64990515ee05c7e29827fbc8fba4
|
|||||||
F ext/wasm/api/sqlite3-api-prologue.js 0fb0703d2d8ac89fa2d4dd8f9726b0ea226b8708ac34e5b482df046e147de0eb
|
F ext/wasm/api/sqlite3-api-prologue.js 0fb0703d2d8ac89fa2d4dd8f9726b0ea226b8708ac34e5b482df046e147de0eb
|
||||||
F ext/wasm/api/sqlite3-api-worker.js 1124f404ecdf3c14d9f829425cef778cd683911a9883f0809a463c3c7773c9fd
|
F ext/wasm/api/sqlite3-api-worker.js 1124f404ecdf3c14d9f829425cef778cd683911a9883f0809a463c3c7773c9fd
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||||
F ext/wasm/api/sqlite3-wasm.c 8585793ca8311c7a0618b7e00ed2b3729799c20664a51f196258576e3d475c9e
|
F ext/wasm/api/sqlite3-wasm.c 0b3f56078f3e3806fb6dfbc756198d1634d3bfdbf3677c77702cf453c4ed336a
|
||||||
F ext/wasm/api/sqlite3-worker.js 1325ca8d40129a82531902a3a077b795db2eeaee81746e5a0c811a04b415fa7f
|
F ext/wasm/api/sqlite3-worker.js 1325ca8d40129a82531902a3a077b795db2eeaee81746e5a0c811a04b415fa7f
|
||||||
F ext/wasm/common/SqliteTestUtil.js e41a1406f18da9224523fad0c48885caf995b56956a5b9852909c0989e687e90
|
F ext/wasm/common/SqliteTestUtil.js e41a1406f18da9224523fad0c48885caf995b56956a5b9852909c0989e687e90
|
||||||
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
F ext/wasm/common/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
F ext/wasm/common/testing.css 572cf1ffae0b6eb7ca63684d3392bf350217a07b90e7a896e4fa850700c989b0
|
F ext/wasm/common/testing.css 572cf1ffae0b6eb7ca63684d3392bf350217a07b90e7a896e4fa850700c989b0
|
||||||
F ext/wasm/common/whwasmutil.js 3d9deda1be718e2b10e2b6b474ba6ba857d905be314201ae5b3df5eef79f66aa
|
F ext/wasm/common/whwasmutil.js 3d9deda1be718e2b10e2b6b474ba6ba857d905be314201ae5b3df5eef79f66aa
|
||||||
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
F ext/wasm/fiddle/fiddle-worker.js 88bc2193a6cb6a3f04d8911bed50a4401fe6f277de7a71ba833865ab64a1b4ae
|
F ext/wasm/fiddle/fiddle-worker.js c9d66230269cc26d33aa84501ae601c24f8697c3711be5d769c4c687bfcaba8f
|
||||||
F ext/wasm/fiddle/fiddle.html 550c5aafce40bd218de9bf26192749f69f9b10bc379423ecd2e162bcef885c08
|
F ext/wasm/fiddle/fiddle.html 550c5aafce40bd218de9bf26192749f69f9b10bc379423ecd2e162bcef885c08
|
||||||
F ext/wasm/fiddle/fiddle.js 812f9954cc7c4b191884ad171f36fcf2d0112d0a7ecfdf6087896833a0c079a8
|
F ext/wasm/fiddle/fiddle.js bef4b30e078445a7cd2255fba07acd083aa1c3cc074a73b38ea847fd340f1adc
|
||||||
F ext/wasm/jaccwabyt/jaccwabyt.js 99b424b4d467d4544e82615b58e2fe07532a898540bf9de2a985f3c21e7082b2
|
F ext/wasm/jaccwabyt/jaccwabyt.js 99b424b4d467d4544e82615b58e2fe07532a898540bf9de2a985f3c21e7082b2
|
||||||
F ext/wasm/jaccwabyt/jaccwabyt.md 447cc02b598f7792edaa8ae6853a7847b8178a18ed356afacbdbf312b2588106
|
F ext/wasm/jaccwabyt/jaccwabyt.md 447cc02b598f7792edaa8ae6853a7847b8178a18ed356afacbdbf312b2588106
|
||||||
F ext/wasm/jaccwabyt/jaccwabyt_test.c 39e4b865a33548f943e2eb9dd0dc8d619a80de05d5300668e9960fff30d0d36f
|
F ext/wasm/jaccwabyt/jaccwabyt_test.c 39e4b865a33548f943e2eb9dd0dc8d619a80de05d5300668e9960fff30d0d36f
|
||||||
@ -1999,8 +1999,11 @@ 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 4c10b9b18feca82440273f8192fef951ad051bbfd8aad4d3c840cf6375130afd
|
P 1b1f650a08da93da97ed3a96b9a3e4eac567472c266188c02a9bffe1cf620e53
|
||||||
R 3e055b525bbc2100d8c4c001b630489b
|
R a893d12114f31061d4e8d4e31dd72df1
|
||||||
|
T *branch * fiddle-opfs
|
||||||
|
T *sym-fiddle-opfs *
|
||||||
|
T -sym-trunk * Cancelled\sby\sbranch.
|
||||||
U stephan
|
U stephan
|
||||||
Z 4d766400503717808861a1e631c17801
|
Z e55c83b0eefdc75c613c24a829476f39
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
1b1f650a08da93da97ed3a96b9a3e4eac567472c266188c02a9bffe1cf620e53
|
a16f0a46ec88c560f73d5664e4bf53fb5dd1a22e99a92c11b5c8d784816c3282
|
Reference in New Issue
Block a user