mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-30 19:03:16 +03:00
In wasm builds, ifdef out shell commands which require file I/O, pipes, or which trigger an exit() (.quit and .exit). Documented some of the quirks and limitations of the C/WASM crossover. Keep the JS code from calling into the C code after an exit() has been triggered.
FossilOrigin-Name: bee436e62a956e49b0df4a92abff2c89f2b44e21d8f593716df0331f8fc49814
This commit is contained in:
@ -53,13 +53,22 @@
|
|||||||
.button-bar button {
|
.button-bar button {
|
||||||
margin: 0.25em 1em;
|
margin: 0.25em 1em;
|
||||||
}
|
}
|
||||||
label {
|
label[for] {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
fieldset {
|
||||||
|
border-radius: 0.5em;
|
||||||
|
}
|
||||||
.error {
|
.error {
|
||||||
color: red;
|
color: red;
|
||||||
background-color: yellow;
|
background-color: yellow;
|
||||||
}
|
}
|
||||||
|
.hidden {
|
||||||
|
position: absolute !important;
|
||||||
|
opacity: 0 !important;
|
||||||
|
pointer-events: none !important;
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -97,6 +106,34 @@ select * from t;</textarea>
|
|||||||
<label for='opt-cb-sbs'>Side-by-side</label>
|
<label for='opt-cb-sbs'>Side-by-side</label>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<hr>
|
||||||
|
<header>
|
||||||
|
Notes and Caveats
|
||||||
|
(<input id='cb-notes-caveats' type='checkbox'>
|
||||||
|
<label for='cb-notes-caveats'>hide</label>)
|
||||||
|
</header>
|
||||||
|
<div id='notes-caveats'>
|
||||||
|
<p>
|
||||||
|
This JavaScript application runs a C application which has been
|
||||||
|
compiled into WASM (Web Assembly). As such, it has certain
|
||||||
|
limitations. Those include, but are not limited to:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>It <strong>cannot recover after a call to
|
||||||
|
<code>exit()</code></strong>. If the native code triggers
|
||||||
|
an exit, reloading the page is the only way to restart
|
||||||
|
the application. (Making the app restartable without reloading
|
||||||
|
the page would require significant surgery in the C code.)
|
||||||
|
</li>
|
||||||
|
<li>It <strong>cannot perform any file I/O</strong>, and running
|
||||||
|
any command which attempts to do so might trigger an
|
||||||
|
<code>exit()</code>.
|
||||||
|
</li>
|
||||||
|
<li>A number of dot-commands available in the CLI shell are
|
||||||
|
explicitly removed from this version of the shell.
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div><!-- #notes-caveats -->
|
||||||
<script type='text/javascript'>
|
<script type='text/javascript'>
|
||||||
(function(){
|
(function(){
|
||||||
/**
|
/**
|
||||||
@ -126,7 +163,14 @@ select * from t;</textarea>
|
|||||||
btnClearOut.addEventListener('click',function(){
|
btnClearOut.addEventListener('click',function(){
|
||||||
taOutput.value = '';
|
taOutput.value = '';
|
||||||
},false);
|
},false);
|
||||||
const doExec = Module.cwrap('fiddle_exec', null, ['string']);
|
const doExec = function f(sql){
|
||||||
|
if(!f._) f._ = Module.cwrap('fiddle_exec', null, ['string']);
|
||||||
|
if(Module._isDead){
|
||||||
|
Module.printErr("shell module has exit()ed. Cannot run SQL.");
|
||||||
|
}else{
|
||||||
|
f._(sql);
|
||||||
|
}
|
||||||
|
};
|
||||||
const btnRun = document.querySelector('#btn-run');
|
const btnRun = document.querySelector('#btn-run');
|
||||||
btnRun.addEventListener('click',function(){
|
btnRun.addEventListener('click',function(){
|
||||||
const sql = taInput.value.trim();
|
const sql = taInput.value.trim();
|
||||||
@ -136,11 +180,18 @@ select * from t;</textarea>
|
|||||||
},false);
|
},false);
|
||||||
doExec(null)/*sets up the db and outputs the header*/;
|
doExec(null)/*sets up the db and outputs the header*/;
|
||||||
|
|
||||||
let e = document.querySelector('#opt-cb-sbs');
|
document.querySelector('#opt-cb-sbs')
|
||||||
const mainWrapper = document.querySelector('#main-wrapper');
|
.addEventListener('change', function(){
|
||||||
e.addEventListener('change', function(){
|
document.querySelector('#main-wrapper').classList[
|
||||||
mainWrapper.classList[this.checked ? 'add' : 'remove']('side-by-side');
|
this.checked ? 'add' : 'remove'
|
||||||
}, false);
|
]('side-by-side');
|
||||||
|
}, false);
|
||||||
|
document.querySelector('#cb-notes-caveats')
|
||||||
|
.addEventListener('change', function(){
|
||||||
|
document.querySelector('#notes-caveats').classList[
|
||||||
|
this.checked ? 'add' : 'remove'
|
||||||
|
]('hidden');
|
||||||
|
}, false);
|
||||||
|
|
||||||
/* For all buttons with data-cmd=X, map a click handler which
|
/* For all buttons with data-cmd=X, map a click handler which
|
||||||
calls doExec(X). */
|
calls doExec(X). */
|
||||||
@ -217,6 +268,7 @@ select * from t;</textarea>
|
|||||||
window.onerror = function(/*message, source, lineno, colno, error*/) {
|
window.onerror = function(/*message, source, lineno, colno, error*/) {
|
||||||
const err = arguments[4];
|
const err = arguments[4];
|
||||||
if(err && 'ExitStatus'==err.name){
|
if(err && 'ExitStatus'==err.name){
|
||||||
|
Module._isDead = true;
|
||||||
Module.printErr("FATAL ERROR:", err.message);
|
Module.printErr("FATAL ERROR:", err.message);
|
||||||
Module.printErr("Restarting the app requires reloading the page.");
|
Module.printErr("Restarting the app requires reloading the page.");
|
||||||
const taOutput = document.querySelector('#output');
|
const taOutput = document.querySelector('#output');
|
||||||
|
@ -64,7 +64,30 @@ Then browse to `http://localhost:9090/fiddle.html`.
|
|||||||
Note that when serving this app via [althttpd][], it must be a version
|
Note that when serving this app via [althttpd][], it must be a version
|
||||||
from 2022-05-17 or newer so that it recognizes the `.wasm` file
|
from 2022-05-17 or newer so that it recognizes the `.wasm` file
|
||||||
extension and responds with the mimetype `application/wasm`, as the
|
extension and responds with the mimetype `application/wasm`, as the
|
||||||
wasm loader is pedantic about that detail.
|
WASM loader is pedantic about that detail.
|
||||||
|
|
||||||
|
# Known Quirks and Limitations
|
||||||
|
|
||||||
|
Some "impedence mismatch" between C and WASM/JavaScript is to be
|
||||||
|
expected.
|
||||||
|
|
||||||
|
## No I/O
|
||||||
|
|
||||||
|
sqlite3 shell commands which require file I/O or pipes are disabled in
|
||||||
|
the WASM build.
|
||||||
|
|
||||||
|
## `exit()` Triggered from C
|
||||||
|
|
||||||
|
When C code calls `exit()`, as happens (for example) when running an
|
||||||
|
"unsafe" command when safe mode is active, WASM's connection to the
|
||||||
|
sqlite3 shell environment has no sensible choice but to shut down
|
||||||
|
because `exit()` leaves it in a state we can no longer recover
|
||||||
|
from. The JavaScript-side application attempts to recognize this and
|
||||||
|
warn the user that restarting the application is necessary. Currently
|
||||||
|
the only way to restart it is to reload the page. Restructuring the
|
||||||
|
shell code such that it could be "rebooted" without restarting the
|
||||||
|
JS app would require some invasive changes which are not currently
|
||||||
|
on any TODO list but have not been entirely ruled out long-term.
|
||||||
|
|
||||||
|
|
||||||
[emscripten]: https://emscripten.org
|
[emscripten]: https://emscripten.org
|
||||||
|
16
manifest
16
manifest
@ -1,5 +1,5 @@
|
|||||||
C Improved\shandling/reporting\sof\sconditions\swhich\strigger\san\sexit()\sfrom\snative\scode,\se.g.\scalling\sthe\s'.read'\scommand.\sAdded\sa\sHelp\sbutton\swhich\ssimply\ssubmits\sthe\s'.help'\scommand.\sAdded\scommented-out\svariants\sof\svarious\s-Ox\sflags\sto\ssimplify\sexperimenting\swith\sthem.
|
C In\swasm\sbuilds,\sifdef\sout\sshell\scommands\swhich\srequire\sfile\sI/O,\spipes,\sor\swhich\strigger\san\sexit()\s(.quit\sand\s.exit).\sDocumented\ssome\sof\sthe\squirks\sand\slimitations\sof\sthe\sC/WASM\scrossover.\sKeep\sthe\sJS\scode\sfrom\scalling\sinto\sthe\sC\scode\safter\san\sexit()\shas\sbeen\striggered.
|
||||||
D 2022-05-18T21:18:21.599
|
D 2022-05-18T22:58:34.214
|
||||||
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
|
||||||
@ -56,8 +56,8 @@ F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0
|
|||||||
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
||||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||||
F ext/fiddle/Makefile ea647919e6ac4b50edde1490f60ee87e8ccd75141e4aa650718c6f28eb323bbc
|
F ext/fiddle/Makefile ea647919e6ac4b50edde1490f60ee87e8ccd75141e4aa650718c6f28eb323bbc
|
||||||
F ext/fiddle/fiddle.in.html be6f4402b5b3e6287004b1b4d76c049d1fc0a5ae3b642578241e77e853fda30e
|
F ext/fiddle/fiddle.in.html 4836ba55dba4f29e6dc356e4ab763a6bcb0e13a7835da24b68f746078121a655
|
||||||
F ext/fiddle/index.md 08d25ec6fe2a56923e8ea6e5d6c80907bf3a60f9c40a6841a8f402e402dd5f22
|
F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf
|
||||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||||
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
|
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
|
||||||
F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea
|
F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea
|
||||||
@ -557,7 +557,7 @@ F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
|
|||||||
F src/resolve.c a4eb3c617027fd049b07432f3b942ea7151fa793a332a11a7d0f58c9539e104f
|
F src/resolve.c a4eb3c617027fd049b07432f3b942ea7151fa793a332a11a7d0f58c9539e104f
|
||||||
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
|
||||||
F src/select.c 74060a09f66c0c056f3c61627e22cb484af0bbfa29d7d14dcf17c684742c15de
|
F src/select.c 74060a09f66c0c056f3c61627e22cb484af0bbfa29d7d14dcf17c684742c15de
|
||||||
F src/shell.c.in 1a7cdd4b71b747fcf41902068657a7e73273a2c1a98d0ceb044dbd5874c2f0e4
|
F src/shell.c.in be0687bf657dfa3df50153063d5629ec1324f44da11b21acd3920384f86450b7
|
||||||
F src/sqlite.h.in d15c307939039086adca159dd340a94b79b69827e74c6d661f343eeeaefba896
|
F src/sqlite.h.in d15c307939039086adca159dd340a94b79b69827e74c6d661f343eeeaefba896
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
|
F src/sqlite3ext.h a988810c9b21c0dc36dc7a62735012339dc76fc7ab448fb0792721d30eacb69d
|
||||||
@ -1957,8 +1957,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 9bf042b2eb2137239a59e421e89eb463e719b264eac3db2adae44e321b9a4ad3
|
P bf06ddf4125d2726019fa16d312726c8551094be991509499b5688f6a68a7747
|
||||||
R 7e80413f51d07b2a693b13b3778bbe1a
|
R f918d85b43414b7ea69ea32ee376905e
|
||||||
U stephan
|
U stephan
|
||||||
Z 307b97d13682722e9b5c5bfc0074797a
|
Z d35b2897d114db6dc646414a4ea884d4
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
bf06ddf4125d2726019fa16d312726c8551094be991509499b5688f6a68a7747
|
bee436e62a956e49b0df4a92abff2c89f2b44e21d8f593716df0331f8fc49814
|
@ -4241,13 +4241,14 @@ static int run_schema_dump_query(
|
|||||||
** Text of help messages.
|
** Text of help messages.
|
||||||
**
|
**
|
||||||
** The help text for each individual command begins with a line that starts
|
** The help text for each individual command begins with a line that starts
|
||||||
** with ".". Subsequent lines are supplimental information.
|
** with ".". Subsequent lines are supplemental information.
|
||||||
**
|
**
|
||||||
** There must be two or more spaces between the end of the command and the
|
** There must be two or more spaces between the end of the command and the
|
||||||
** start of the description of what that command does.
|
** start of the description of what that command does.
|
||||||
*/
|
*/
|
||||||
static const char *(azHelp[]) = {
|
static const char *(azHelp[]) = {
|
||||||
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
|
#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE) \
|
||||||
|
&& !defined(SQLITE_SHELL_WASM_MODE)
|
||||||
".archive ... Manage SQL archives",
|
".archive ... Manage SQL archives",
|
||||||
" Each command must have exactly one of the following options:",
|
" Each command must have exactly one of the following options:",
|
||||||
" -c, --create Create a new archive",
|
" -c, --create Create a new archive",
|
||||||
@ -4273,10 +4274,12 @@ static const char *(azHelp[]) = {
|
|||||||
#ifndef SQLITE_OMIT_AUTHORIZATION
|
#ifndef SQLITE_OMIT_AUTHORIZATION
|
||||||
".auth ON|OFF Show authorizer callbacks",
|
".auth ON|OFF Show authorizer callbacks",
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
|
".backup ?DB? FILE Backup DB (default \"main\") to FILE",
|
||||||
" Options:",
|
" Options:",
|
||||||
" --append Use the appendvfs",
|
" --append Use the appendvfs",
|
||||||
" --async Write to FILE without journal and fsync()",
|
" --async Write to FILE without journal and fsync()",
|
||||||
|
#endif
|
||||||
".bail on|off Stop after hitting an error. Default OFF",
|
".bail on|off Stop after hitting an error. Default OFF",
|
||||||
".binary on|off Turn binary output on or off. Default OFF",
|
".binary on|off Turn binary output on or off. Default OFF",
|
||||||
".cd DIRECTORY Change the working directory to DIRECTORY",
|
".cd DIRECTORY Change the working directory to DIRECTORY",
|
||||||
@ -4303,9 +4306,13 @@ static const char *(azHelp[]) = {
|
|||||||
" trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
|
" trace Like \"full\" but enable \"PRAGMA vdbe_trace\"",
|
||||||
#endif
|
#endif
|
||||||
" trigger Like \"full\" but also show trigger bytecode",
|
" trigger Like \"full\" but also show trigger bytecode",
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
".excel Display the output of next command in spreadsheet",
|
".excel Display the output of next command in spreadsheet",
|
||||||
" --bom Put a UTF8 byte-order mark on intermediate file",
|
" --bom Put a UTF8 byte-order mark on intermediate file",
|
||||||
|
#endif
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
".exit ?CODE? Exit this program with return-code CODE",
|
".exit ?CODE? Exit this program with return-code CODE",
|
||||||
|
#endif
|
||||||
".expert EXPERIMENTAL. Suggest indexes for queries",
|
".expert EXPERIMENTAL. Suggest indexes for queries",
|
||||||
".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
|
".explain ?on|off|auto? Change the EXPLAIN formatting mode. Default: auto",
|
||||||
".filectrl CMD ... Run various sqlite3_file_control() operations",
|
".filectrl CMD ... Run various sqlite3_file_control() operations",
|
||||||
@ -4371,6 +4378,7 @@ static const char *(azHelp[]) = {
|
|||||||
" TABLE The name of SQL table used for \"insert\" mode",
|
" TABLE The name of SQL table used for \"insert\" mode",
|
||||||
".nonce STRING Suspend safe mode for one command if nonce matches",
|
".nonce STRING Suspend safe mode for one command if nonce matches",
|
||||||
".nullvalue STRING Use STRING in place of NULL values",
|
".nullvalue STRING Use STRING in place of NULL values",
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
|
".once ?OPTIONS? ?FILE? Output for the next SQL command only to FILE",
|
||||||
" If FILE begins with '|' then open as a pipe",
|
" If FILE begins with '|' then open as a pipe",
|
||||||
" --bom Put a UTF8 byte-order mark at the beginning",
|
" --bom Put a UTF8 byte-order mark at the beginning",
|
||||||
@ -4379,6 +4387,7 @@ static const char *(azHelp[]) = {
|
|||||||
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
|
".open ?OPTIONS? ?FILE? Close existing database and reopen FILE",
|
||||||
" Options:",
|
" Options:",
|
||||||
" --append Use appendvfs to append database to the end of FILE",
|
" --append Use appendvfs to append database to the end of FILE",
|
||||||
|
#endif
|
||||||
#ifndef SQLITE_OMIT_DESERIALIZE
|
#ifndef SQLITE_OMIT_DESERIALIZE
|
||||||
" --deserialize Load into memory using sqlite3_deserialize()",
|
" --deserialize Load into memory using sqlite3_deserialize()",
|
||||||
" --hexdb Load the output of \"dbtotxt\" as an in-memory db",
|
" --hexdb Load the output of \"dbtotxt\" as an in-memory db",
|
||||||
@ -4410,9 +4419,11 @@ static const char *(azHelp[]) = {
|
|||||||
" --reset Reset the count for each input and interrupt",
|
" --reset Reset the count for each input and interrupt",
|
||||||
#endif
|
#endif
|
||||||
".prompt MAIN CONTINUE Replace the standard prompts",
|
".prompt MAIN CONTINUE Replace the standard prompts",
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
".quit Exit this program",
|
".quit Exit this program",
|
||||||
".read FILE Read input from FILE or command output",
|
".read FILE Read input from FILE or command output",
|
||||||
" If FILE begins with \"|\", it is a command that generates the input.",
|
" If FILE begins with \"|\", it is a command that generates the input.",
|
||||||
|
#endif
|
||||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
|
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB)
|
||||||
".recover Recover as much data as possible from corrupt db.",
|
".recover Recover as much data as possible from corrupt db.",
|
||||||
" --freelist-corrupt Assume the freelist is corrupt",
|
" --freelist-corrupt Assume the freelist is corrupt",
|
||||||
@ -4421,8 +4432,10 @@ static const char *(azHelp[]) = {
|
|||||||
" --no-rowids Do not attempt to recover rowid values",
|
" --no-rowids Do not attempt to recover rowid values",
|
||||||
" that are not also INTEGER PRIMARY KEYs",
|
" that are not also INTEGER PRIMARY KEYs",
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
|
".restore ?DB? FILE Restore content of DB (default \"main\") from FILE",
|
||||||
".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
|
".save ?OPTIONS? FILE Write database to FILE (an alias for .backup ...)",
|
||||||
|
#endif
|
||||||
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
|
".scanstats on|off Turn sqlite3_stmt_scanstatus() metrics on or off",
|
||||||
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
|
".schema ?PATTERN? Show the CREATE statements matching PATTERN",
|
||||||
" Options:",
|
" Options:",
|
||||||
@ -4456,7 +4469,7 @@ static const char *(azHelp[]) = {
|
|||||||
" --sha3-384 Use the sha3-384 algorithm",
|
" --sha3-384 Use the sha3-384 algorithm",
|
||||||
" --sha3-512 Use the sha3-512 algorithm",
|
" --sha3-512 Use the sha3-512 algorithm",
|
||||||
" Any other argument is a LIKE pattern for tables to hash",
|
" Any other argument is a LIKE pattern for tables to hash",
|
||||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
|
||||||
".shell CMD ARGS... Run CMD ARGS... in a system shell",
|
".shell CMD ARGS... Run CMD ARGS... in a system shell",
|
||||||
#endif
|
#endif
|
||||||
".show Show the current values for various settings",
|
".show Show the current values for various settings",
|
||||||
@ -4465,11 +4478,13 @@ static const char *(azHelp[]) = {
|
|||||||
" on Turn on automatic stat display",
|
" on Turn on automatic stat display",
|
||||||
" stmt Show statement stats",
|
" stmt Show statement stats",
|
||||||
" vmstep Show the virtual machine step count only",
|
" vmstep Show the virtual machine step count only",
|
||||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
|
||||||
".system CMD ARGS... Run CMD ARGS... in a system shell",
|
".system CMD ARGS... Run CMD ARGS... in a system shell",
|
||||||
#endif
|
#endif
|
||||||
".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
|
".tables ?TABLE? List names of tables matching LIKE pattern TABLE",
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
".testcase NAME Begin redirecting output to 'testcase-out.txt'",
|
".testcase NAME Begin redirecting output to 'testcase-out.txt'",
|
||||||
|
#endif
|
||||||
".testctrl CMD ... Run various sqlite3_test_control() operations",
|
".testctrl CMD ... Run various sqlite3_test_control() operations",
|
||||||
" Run \".testctrl\" with no arguments for details",
|
" Run \".testctrl\" with no arguments for details",
|
||||||
".timeout MS Try opening locked tables for MS milliseconds",
|
".timeout MS Try opening locked tables for MS milliseconds",
|
||||||
@ -8146,7 +8161,8 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
|
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) \
|
||||||
|
&& !defined(SQLITE_SHELL_WASM_MODE)
|
||||||
if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
|
if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
|
||||||
open_db(p, 0);
|
open_db(p, 0);
|
||||||
failIfSafeMode(p, "cannot run .archive in safe mode");
|
failIfSafeMode(p, "cannot run .archive in safe mode");
|
||||||
@ -8154,6 +8170,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}else
|
}else
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
|
if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
|
||||||
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
|
|| (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
|
||||||
){
|
){
|
||||||
@ -8222,6 +8239,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}
|
}
|
||||||
close_db(pDest);
|
close_db(pDest);
|
||||||
}else
|
}else
|
||||||
|
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
|
||||||
|
|
||||||
if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
|
if( c=='b' && n>=3 && strncmp(azArg[0], "bail", n)==0 ){
|
||||||
if( nArg==2 ){
|
if( nArg==2 ){
|
||||||
@ -8603,10 +8621,12 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
|
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
|
if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
|
||||||
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
|
if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
|
||||||
rc = 2;
|
rc = 2;
|
||||||
}else
|
}else
|
||||||
|
#endif
|
||||||
|
|
||||||
/* The ".explain" command is automatic now. It is largely pointless. It
|
/* The ".explain" command is automatic now. It is largely pointless. It
|
||||||
** retained purely for backwards compatibility */
|
** retained purely for backwards compatibility */
|
||||||
@ -9608,6 +9628,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
|
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
if( (c=='o'
|
if( (c=='o'
|
||||||
&& (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
|
&& (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
|
||||||
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
|
|| (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
|
||||||
@ -9723,6 +9744,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}
|
}
|
||||||
sqlite3_free(zFile);
|
sqlite3_free(zFile);
|
||||||
}else
|
}else
|
||||||
|
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
|
||||||
|
|
||||||
if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
|
if( c=='p' && n>=3 && strncmp(azArg[0], "parameter", n)==0 ){
|
||||||
open_db(p,0);
|
open_db(p,0);
|
||||||
@ -9892,10 +9914,13 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
|
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
|
if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
|
||||||
rc = 2;
|
rc = 2;
|
||||||
}else
|
}else
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
|
if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
|
||||||
FILE *inSaved = p->in;
|
FILE *inSaved = p->in;
|
||||||
int savedLineno = p->lineno;
|
int savedLineno = p->lineno;
|
||||||
@ -9930,7 +9955,9 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
p->in = inSaved;
|
p->in = inSaved;
|
||||||
p->lineno = savedLineno;
|
p->lineno = savedLineno;
|
||||||
}else
|
}else
|
||||||
|
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
|
||||||
|
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
|
if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
|
||||||
const char *zSrcFile;
|
const char *zSrcFile;
|
||||||
const char *zDb;
|
const char *zDb;
|
||||||
@ -9982,6 +10009,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
}
|
}
|
||||||
close_db(pSrc);
|
close_db(pSrc);
|
||||||
}else
|
}else
|
||||||
|
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
|
||||||
|
|
||||||
if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
|
if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
|
||||||
if( nArg==2 ){
|
if( nArg==2 ){
|
||||||
@ -10607,7 +10635,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
sqlite3_free(zSql);
|
sqlite3_free(zSql);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
#ifndef SQLITE_NOHAVE_SYSTEM
|
#if !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE)
|
||||||
if( c=='s'
|
if( c=='s'
|
||||||
&& (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
|
&& (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
|
||||||
){
|
){
|
||||||
@ -10628,7 +10656,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
sqlite3_free(zCmd);
|
sqlite3_free(zCmd);
|
||||||
if( x ) raw_printf(stderr, "System command returns %d\n", x);
|
if( x ) raw_printf(stderr, "System command returns %d\n", x);
|
||||||
}else
|
}else
|
||||||
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) */
|
#endif /* !defined(SQLITE_NOHAVE_SYSTEM) && !defined(SQLITE_SHELL_WASM_MODE) */
|
||||||
|
|
||||||
if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
|
if( c=='s' && strncmp(azArg[0], "show", n)==0 ){
|
||||||
static const char *azBool[] = { "off", "on", "trigger", "full"};
|
static const char *azBool[] = { "off", "on", "trigger", "full"};
|
||||||
@ -10808,6 +10836,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
sqlite3_free(azResult);
|
sqlite3_free(azResult);
|
||||||
}else
|
}else
|
||||||
|
|
||||||
|
#ifndef SQLITE_SHELL_WASM_MODE
|
||||||
/* Begin redirecting output to the file "testcase-out.txt" */
|
/* Begin redirecting output to the file "testcase-out.txt" */
|
||||||
if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
|
if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
|
||||||
output_reset(p);
|
output_reset(p);
|
||||||
@ -10821,6 +10850,7 @@ static int do_meta_command(char *zLine, ShellState *p){
|
|||||||
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
|
sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
|
||||||
}
|
}
|
||||||
}else
|
}else
|
||||||
|
#endif /* !defined(SQLITE_SHELL_WASM_MODE) */
|
||||||
|
|
||||||
#ifndef SQLITE_UNTESTABLE
|
#ifndef SQLITE_UNTESTABLE
|
||||||
if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
|
if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
|
||||||
@ -12525,7 +12555,9 @@ void fiddle_exec(const char * zSql){
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
if(!once){
|
if(!once){
|
||||||
/* Simulate an argv array for main() */
|
/* Simulate an argv array for main() */
|
||||||
static char * argv[] = {"fiddle", "-bail", "-safe"};
|
static char * argv[] = {"fiddle",
|
||||||
|
"-bail",
|
||||||
|
"-safe"};
|
||||||
rc = fiddle_main((int)(sizeof(argv)/sizeof(argv[0])), argv);
|
rc = fiddle_main((int)(sizeof(argv)/sizeof(argv[0])), argv);
|
||||||
once = rc ? -1 : 1;
|
once = rc ? -1 : 1;
|
||||||
memset(&shellState.wasm, 0, sizeof(shellState.wasm));
|
memset(&shellState.wasm, 0, sizeof(shellState.wasm));
|
||||||
|
Reference in New Issue
Block a user