mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-01 06:27:03 +03:00
Build refactoring for the fiddle/wasm bits. Set up wasm binding of a chunk of the core C API and added some infastructure for creating test pages for it.
FossilOrigin-Name: dea098b64eb95c395b346ebcae687afe42b7d21df48833527808c02226300a66
This commit is contained in:
35
Makefile.in
35
Makefile.in
@ -1515,7 +1515,7 @@ sqlite3.dll: $(REAL_LIBOBJ) sqlite3.def
|
|||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# fiddle section
|
# fiddle/wasm section
|
||||||
#
|
#
|
||||||
fiddle_dir = ext/fiddle
|
fiddle_dir = ext/fiddle
|
||||||
fiddle_dir_abs = $(TOP)/$(fiddle_dir)
|
fiddle_dir_abs = $(TOP)/$(fiddle_dir)
|
||||||
@ -1524,22 +1524,31 @@ fiddle_html = $(fiddle_dir)/fiddle.html
|
|||||||
fiddle_module_js = $(fiddle_dir)/fiddle-module.js
|
fiddle_module_js = $(fiddle_dir)/fiddle-module.js
|
||||||
fiddle_generated = $(fiddle_module_js) \
|
fiddle_generated = $(fiddle_module_js) \
|
||||||
$(fiddle_dir)/fiddle-module.wasm
|
$(fiddle_dir)/fiddle-module.wasm
|
||||||
clean-fiddle:
|
sqlite3_wasm_js = $(fiddle_dir)/sqlite3.js
|
||||||
rm -f $(fiddle_generated)
|
sqlite3_wasm = $(fiddle_dir)/sqlite3.wasm
|
||||||
clean: clean-fiddle
|
sqlite3_wasm_generated = $(sqlite3_wasm) $(sqlite3_wasm_js)
|
||||||
|
clean-wasm:
|
||||||
|
rm -f $(fiddle_generated) $(sqlite3_wasm_generated)
|
||||||
|
clean: clean-wasm
|
||||||
#emcc_opt = -O0
|
#emcc_opt = -O0
|
||||||
#emcc_opt = -O1
|
#emcc_opt = -O1
|
||||||
#emcc_opt = -O2
|
#emcc_opt = -O2
|
||||||
#emcc_opt = -O3
|
#emcc_opt = -O3
|
||||||
# --js-library $(fiddle_dir)/_dummylib.js
|
|
||||||
emcc_opt = -Oz
|
emcc_opt = -Oz
|
||||||
emcc_flags = $(emcc_opt) $(SHELL_OPT) \
|
emcc_flags = $(emcc_opt) -I. $(SHELL_OPT)
|
||||||
-sEXPORTED_RUNTIME_METHODS=@$(fiddle_dir_abs)/EXPORTED_RUNTIME_METHODS \
|
|
||||||
-sEXPORTED_FUNCTIONS=@$(fiddle_dir_abs)/EXPORTED_FUNCTIONS \
|
|
||||||
$(fiddle_cflags)
|
|
||||||
# $(fiddle_cflags) is intended to be passed to make via the CLI in
|
|
||||||
# order to override, e.g., -Ox for one-off builds.
|
|
||||||
$(fiddle_module_js): Makefile sqlite3.c shell.c \
|
$(fiddle_module_js): Makefile sqlite3.c shell.c \
|
||||||
$(fiddle_dir)/EXPORTED_RUNTIME_METHODS $(fiddle_dir)/EXPORTED_FUNCTIONS
|
$(fiddle_dir)/EXPORTED_RUNTIME_METHODS $(fiddle_dir)/EXPORTED_FUNCTIONS.fiddle
|
||||||
emcc -o $@ $(emcc_flags) sqlite3.c shell.c
|
emcc -o $@ $(emcc_flags) \
|
||||||
|
-sEXPORTED_RUNTIME_METHODS=@$(fiddle_dir_abs)/EXPORTED_RUNTIME_METHODS \
|
||||||
|
-sEXPORTED_FUNCTIONS=@$(fiddle_dir_abs)/EXPORTED_FUNCTIONS.fiddle \
|
||||||
|
sqlite3.c shell.c
|
||||||
|
$(sqlite3_wasm_js): Makefile sqlite3.c \
|
||||||
|
$(fiddle_dir)/EXPORTED_RUNTIME_METHODS $(fiddle_dir)/EXPORTED_FUNCTIONS.sqlite3
|
||||||
|
emcc -o $@ $(emcc_flags) \
|
||||||
|
-sEXPORTED_RUNTIME_METHODS=@$(fiddle_dir_abs)/EXPORTED_RUNTIME_METHODS \
|
||||||
|
-sEXPORTED_FUNCTIONS=@$(fiddle_dir_abs)/EXPORTED_FUNCTIONS.sqlite3 \
|
||||||
|
--no-entry \
|
||||||
|
sqlite3.c
|
||||||
fiddle: $(fiddle_module_js)
|
fiddle: $(fiddle_module_js)
|
||||||
|
sqlite3-wasm: $(sqlite3_wasm_js)
|
||||||
|
wasm: fiddle sqlite3-wasm
|
||||||
|
39
ext/fiddle/EXPORTED_FUNCTIONS.sqlite3
Normal file
39
ext/fiddle/EXPORTED_FUNCTIONS.sqlite3
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
_sqlite3_bind_blob
|
||||||
|
_sqlite3_bind_double
|
||||||
|
_sqlite3_bind_int
|
||||||
|
_sqlite3_bind_parameter_index
|
||||||
|
_sqlite3_bind_text
|
||||||
|
_sqlite3_changes
|
||||||
|
_sqlite3_clear_bindings
|
||||||
|
_sqlite3_close_v2
|
||||||
|
_sqlite3_column_blob
|
||||||
|
_sqlite3_column_bytes
|
||||||
|
_sqlite3_column_count
|
||||||
|
_sqlite3_column_count
|
||||||
|
_sqlite3_column_double
|
||||||
|
_sqlite3_column_name
|
||||||
|
_sqlite3_column_text
|
||||||
|
_sqlite3_column_type
|
||||||
|
_sqlite3_create_function_v2
|
||||||
|
_sqlite3_data_count
|
||||||
|
_sqlite3_errmsg
|
||||||
|
_sqlite3_exec
|
||||||
|
_sqlite3_finalize
|
||||||
|
_sqlite3_libversion
|
||||||
|
_sqlite3_open
|
||||||
|
_sqlite3_prepare_v2
|
||||||
|
_sqlite3_prepare_v2
|
||||||
|
_sqlite3_reset
|
||||||
|
_sqlite3_result_blob
|
||||||
|
_sqlite3_result_double
|
||||||
|
_sqlite3_result_error
|
||||||
|
_sqlite3_result_int
|
||||||
|
_sqlite3_result_null
|
||||||
|
_sqlite3_result_text
|
||||||
|
_sqlite3_sourceid
|
||||||
|
_sqlite3_step
|
||||||
|
_sqlite3_value_blob
|
||||||
|
_sqlite3_value_bytes
|
||||||
|
_sqlite3_value_double
|
||||||
|
_sqlite3_value_text
|
||||||
|
_sqlite3_value_type
|
@ -1,7 +1,10 @@
|
|||||||
# This makefile exists primarily to simplify/speed up development from
|
# This makefile exists primarily to simplify/speed up development from
|
||||||
# emacs. It is not part of the canonical build process.
|
# emacs. It is not part of the canonical build process.
|
||||||
default:
|
default:
|
||||||
make -C ../.. fiddle -e emcc_opt=-O0
|
make -C ../.. wasm -e emcc_opt=-O0
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
make -C ../../ clean-fiddle
|
make -C ../../ clean-wasm
|
||||||
|
|
||||||
|
push-demo:
|
||||||
|
rsync -va fiddle*.js fiddle*.wasm fiddle.html *.css wh2:www/wh/sqlite3/.
|
||||||
|
24
ext/fiddle/emscripten.css
Normal file
24
ext/fiddle/emscripten.css
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/* emcscript-related styling, used during the module load/intialization processes... */
|
||||||
|
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
||||||
|
div.emscripten { text-align: center; }
|
||||||
|
div.emscripten_border { border: 1px solid black; }
|
||||||
|
#module-spinner { overflow: visible; }
|
||||||
|
#module-spinner > * {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
.spinner {
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
margin: 0px auto;
|
||||||
|
animation: rotation 0.8s linear infinite;
|
||||||
|
border-left: 10px solid rgb(0,150,240);
|
||||||
|
border-right: 10px solid rgb(0,150,240);
|
||||||
|
border-bottom: 10px solid rgb(0,150,240);
|
||||||
|
border-top: 10px solid rgb(100,0,200);
|
||||||
|
border-radius: 100%;
|
||||||
|
background-color: rgb(200,100,250);
|
||||||
|
}
|
||||||
|
@keyframes rotation {
|
||||||
|
from {transform: rotate(0deg);}
|
||||||
|
to {transform: rotate(360deg);}
|
||||||
|
}
|
@ -14,6 +14,10 @@
|
|||||||
sqlite3 wasm module and offers access to the db via the Worker
|
sqlite3 wasm module and offers access to the db via the Worker
|
||||||
message-passing interface.
|
message-passing interface.
|
||||||
|
|
||||||
|
Forewarning: this API is still very much Under Construction and
|
||||||
|
subject to any number of changes as experience reveals what those
|
||||||
|
need to be.
|
||||||
|
|
||||||
Because we can have only a single message handler, as opposed to an
|
Because we can have only a single message handler, as opposed to an
|
||||||
arbitrary number of discrete event listeners like with DOM elements,
|
arbitrary number of discrete event listeners like with DOM elements,
|
||||||
we have to define a lower-level message API. Messages abstractly
|
we have to define a lower-level message API. Messages abstractly
|
||||||
@ -70,23 +74,23 @@
|
|||||||
Noting that it happens in Firefox as well as Chrome. Harmless but
|
Noting that it happens in Firefox as well as Chrome. Harmless but
|
||||||
annoying.
|
annoying.
|
||||||
*/
|
*/
|
||||||
|
"use strict";
|
||||||
const thisWorker = self;
|
|
||||||
|
|
||||||
const wMsg = (type,data)=>postMessage({type, data});
|
const wMsg = (type,data)=>postMessage({type, data});
|
||||||
|
|
||||||
self.onerror = function(/*message, source, lineno, colno, error*/) {
|
self.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){
|
||||||
|
/* This is relevant for the sqlite3 shell binding but not the
|
||||||
|
lower-level binding. */
|
||||||
Module._isDead = true;
|
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');
|
wMsg('error', err);
|
||||||
//if(taOutput) taOutput.classList.add('error');
|
|
||||||
}
|
}
|
||||||
Module.setStatus('Exception thrown, see JavaScript console');
|
Module.setStatus('Exception thrown, see JavaScript console');
|
||||||
Module.setStatus = function(text) {
|
Module.setStatus = function(text) {
|
||||||
if(text) console.error('[post-exception status] ' + text);
|
console.error('[post-exception status]', text);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -139,47 +143,10 @@ self.onmessage = function(ev){
|
|||||||
self.Module.setStatus('Downloading...');
|
self.Module.setStatus('Downloading...');
|
||||||
importScripts('fiddle-module.js')
|
importScripts('fiddle-module.js')
|
||||||
/* loads the wasm module and notifies, via Module.setStatus() and
|
/* loads the wasm module and notifies, via Module.setStatus() and
|
||||||
Module.onRuntimeInitialized(), when it's done loading. */;
|
Module.onRuntimeInitialized(), when it's done loading. The latter
|
||||||
|
is called _before_ the final call to Module.setStatus(). */;
|
||||||
|
|
||||||
Module["onRuntimeInitialized"] = function onRuntimeInitialized() {
|
Module["onRuntimeInitialized"] = function onRuntimeInitialized() {
|
||||||
/* For reference: sql.js does essentially everything we want and
|
//console.log('onRuntimeInitialized');
|
||||||
it solves much of the wasm-related voodoo, but we'll need a
|
//wMsg('module','done');
|
||||||
different structure because we want the db connection to run in
|
};
|
||||||
a worker thread and feed data back into the main
|
|
||||||
thread. Regardless of those differences, it makes a great point
|
|
||||||
of reference:
|
|
||||||
|
|
||||||
https://github.com/sql-js/sql.js
|
|
||||||
|
|
||||||
Some of the specific design goals here:
|
|
||||||
|
|
||||||
- Bind a low-level sqlite3 API which is close to the native one in
|
|
||||||
terms of usage.
|
|
||||||
|
|
||||||
- Create a higher-level one, more akin to sql.js and
|
|
||||||
node.js-style implementations. This one would speak directly
|
|
||||||
to the low-level API. This API could be used by clients who
|
|
||||||
import the low-level API directly into their main thread
|
|
||||||
(which we don't want to recommend but also don't want to
|
|
||||||
outright forbid).
|
|
||||||
|
|
||||||
- Create a second higher-level one which speaks to the
|
|
||||||
low-level API via worker messages. This one would be intended
|
|
||||||
for use in the main thread, talking to the low-level UI via
|
|
||||||
worker messages. Because workers have only a single message
|
|
||||||
channel, some acrobatics will be needed here to feed async
|
|
||||||
work results back into client-side callbacks (as those
|
|
||||||
callbacks cannot simply be passed to the worker). Exactly
|
|
||||||
what those acrobatics should look like is not yet entirely
|
|
||||||
clear and much experimentation is pending.
|
|
||||||
|
|
||||||
*/
|
|
||||||
console.log('onRuntimeInitialized');
|
|
||||||
|
|
||||||
/*
|
|
||||||
TODO: create the main sqlite API here. We'll have another for
|
|
||||||
use in the main thread which will talk to this one via worker
|
|
||||||
messages.
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -6,34 +6,9 @@
|
|||||||
<title>sqlite3 fiddle</title>
|
<title>sqlite3 fiddle</title>
|
||||||
<!--script src="jqterm/jqterm-bundle.min.js"></script>
|
<!--script src="jqterm/jqterm-bundle.min.js"></script>
|
||||||
<link rel="stylesheet" href="jqterm/jquery.terminal.min.css"/-->
|
<link rel="stylesheet" href="jqterm/jquery.terminal.min.css"/-->
|
||||||
|
<link rel="stylesheet" href="emscripten.css"/>
|
||||||
<style>
|
<style>
|
||||||
/* emcscript-related styling, used during the intialization phase... */
|
|
||||||
.emscripten { padding-right: 0; margin-left: auto; margin-right: auto; display: block; }
|
|
||||||
div.emscripten { text-align: center; }
|
|
||||||
div.emscripten_border { border: 1px solid black; }
|
|
||||||
#module-spinner { overflow: visible; }
|
|
||||||
#module-spinner > * {
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
.spinner {
|
|
||||||
height: 50px;
|
|
||||||
width: 50px;
|
|
||||||
margin: 0px auto;
|
|
||||||
animation: rotation 0.8s linear infinite;
|
|
||||||
border-left: 10px solid rgb(0,150,240);
|
|
||||||
border-right: 10px solid rgb(0,150,240);
|
|
||||||
border-bottom: 10px solid rgb(0,150,240);
|
|
||||||
border-top: 10px solid rgb(100,0,200);
|
|
||||||
border-radius: 100%;
|
|
||||||
background-color: rgb(200,100,250);
|
|
||||||
}
|
|
||||||
@keyframes rotation {
|
|
||||||
from {transform: rotate(0deg);}
|
|
||||||
to {transform: rotate(360deg);}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The following styles are for app-level use. */
|
/* The following styles are for app-level use. */
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
@ -70,9 +45,6 @@
|
|||||||
filter: invert(100%);
|
filter: invert(100%);
|
||||||
flex: 10 1 auto;
|
flex: 10 1 auto;
|
||||||
}
|
}
|
||||||
/*#main-wrapper:not(.side-by-side) .ta-wrapper.input {
|
|
||||||
flex: 5 1 auto;
|
|
||||||
}*/
|
|
||||||
.button-bar {
|
.button-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -142,6 +114,7 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header id='titlebar'><span>sqlite3 fiddle</span></header>
|
<header id='titlebar'><span>sqlite3 fiddle</span></header>
|
||||||
|
<!-- emscripten bits -->
|
||||||
<figure id="module-spinner">
|
<figure id="module-spinner">
|
||||||
<div class="spinner"></div>
|
<div class="spinner"></div>
|
||||||
<div class='center'><strong>Initializing app...</strong></div>
|
<div class='center'><strong>Initializing app...</strong></div>
|
||||||
@ -154,7 +127,7 @@
|
|||||||
<div class="emscripten" id="module-status">Downloading...</div>
|
<div class="emscripten" id="module-status">Downloading...</div>
|
||||||
<div class="emscripten">
|
<div class="emscripten">
|
||||||
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
|
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
|
||||||
</div>
|
</div><!-- /emscripten bits -->
|
||||||
|
|
||||||
<div id='view-terminal' class='app-view hidden initially-hidden'>
|
<div id='view-terminal' class='app-view hidden initially-hidden'>
|
||||||
This is a placeholder for a terminal-like view.
|
This is a placeholder for a terminal-like view.
|
||||||
|
@ -159,8 +159,9 @@
|
|||||||
progressElement.remove();
|
progressElement.remove();
|
||||||
if(!text) spinnerElement.remove();
|
if(!text) spinnerElement.remove();
|
||||||
}
|
}
|
||||||
if(text) statusElement.innerText = text;
|
if(text){
|
||||||
else {
|
statusElement.innerText = text;
|
||||||
|
}else{
|
||||||
console.log("Finalizing status.");
|
console.log("Finalizing status.");
|
||||||
statusElement.remove();
|
statusElement.remove();
|
||||||
SF.clearMsgHandlers('module');
|
SF.clearMsgHandlers('module');
|
||||||
|
165
ext/fiddle/sqlite3-api.js
Normal file
165
ext/fiddle/sqlite3-api.js
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
2022-05-22
|
||||||
|
|
||||||
|
The author disclaims copyright to this source code. In place of a
|
||||||
|
legal notice, here is a blessing:
|
||||||
|
|
||||||
|
* May you do good and not evil.
|
||||||
|
* May you find forgiveness for yourself and forgive others.
|
||||||
|
* May you share freely, never taking more than you give.
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
|
||||||
|
This file is intended to be loaded after loading
|
||||||
|
sqlite3-module.wasm. It sets one of any number of potential
|
||||||
|
bindings using that API, this one as closely matching the C-native
|
||||||
|
API as is feasible.
|
||||||
|
|
||||||
|
Note that this file is not named sqlite3.js because that file gets
|
||||||
|
generated by emscripten as the JS-glue counterpart of sqlite3.wasm.
|
||||||
|
|
||||||
|
The API gets installed as self.sqlite3, where self is expected to be
|
||||||
|
either the global window or Worker object.
|
||||||
|
|
||||||
|
Because using this API properly requires some degree of WASM-related
|
||||||
|
magic, it is not recommended that this API be used as-is in
|
||||||
|
client-level code, but instead is intended to be used as a basis for
|
||||||
|
APIs more appropriate for high-level client code.
|
||||||
|
|
||||||
|
This file installs namespace.sqlite3, where namespace is `self`,
|
||||||
|
meaning either the global window or worker, depending on where this
|
||||||
|
is loaded from.
|
||||||
|
*/
|
||||||
|
(function(namespace){
|
||||||
|
/* For reference: sql.js does essentially everything we want and
|
||||||
|
it solves much of the wasm-related voodoo, but we'll need a
|
||||||
|
different structure because we want the db connection to run in
|
||||||
|
a worker thread and feed data back into the main
|
||||||
|
thread. Regardless of those differences, it makes a great point
|
||||||
|
of reference:
|
||||||
|
|
||||||
|
https://github.com/sql-js/sql.js
|
||||||
|
|
||||||
|
Some of the specific design goals here:
|
||||||
|
|
||||||
|
- Bind a low-level sqlite3 API which is close to the native one
|
||||||
|
in terms of usage.
|
||||||
|
|
||||||
|
- Create a higher-level one, more akin to sql.js and
|
||||||
|
node.js-style implementations. This one would speak directly
|
||||||
|
to the low-level API. This API could be used by clients who
|
||||||
|
import the low-level API directly into their main thread
|
||||||
|
(which we don't want to recommend but also don't want to
|
||||||
|
outright forbid).
|
||||||
|
|
||||||
|
- Create a second higher-level one which speaks to the
|
||||||
|
low-level API via worker messages. This one would be intended
|
||||||
|
for use in the main thread, talking to the low-level UI via
|
||||||
|
worker messages. Because workers have only a single message
|
||||||
|
channel, some acrobatics will be needed here to feed async
|
||||||
|
work results back into client-side callbacks (as those
|
||||||
|
callbacks cannot simply be passed to the worker). Exactly
|
||||||
|
what those acrobatics should look like is not yet entirely
|
||||||
|
clear and much experimentation is pending.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set up the main sqlite3 binding API here, mimicking the C API as
|
||||||
|
closely as we can.
|
||||||
|
|
||||||
|
Attribution: though not a direct copy/paste, much of what
|
||||||
|
follows is strongly influenced by the sql.js implementation.
|
||||||
|
*/
|
||||||
|
const api = {
|
||||||
|
/* It is important that the following integer values match
|
||||||
|
those from the C code. Ideally we could fetch them from the
|
||||||
|
C API, e.g., in the form of a JSON object, but getting that
|
||||||
|
JSON string constructed within our current confised is
|
||||||
|
currently not worth the effort. */
|
||||||
|
/* Minimum subset of sqlite result codes we'll need. */
|
||||||
|
SQLITE_OK: 0,
|
||||||
|
SQLITE_ROW: 100,
|
||||||
|
SQLITE_DONE: 101,
|
||||||
|
/* sqlite data types */
|
||||||
|
SQLITE_INTEGER: 1,
|
||||||
|
SQLITE_FLOAT: 2,
|
||||||
|
SQLITE_TEXT: 3,
|
||||||
|
SQLITE_BLOB: 4,
|
||||||
|
/* sqlite encodings, used for creating UDFs, noting that we
|
||||||
|
will only support UTF8. */
|
||||||
|
SQLITE_UTF8: 1
|
||||||
|
};
|
||||||
|
const cwrap = Module.cwrap;
|
||||||
|
[/* C-side functions to bind. Each entry is an array with 3 or 4
|
||||||
|
elements:
|
||||||
|
|
||||||
|
["c-side name",
|
||||||
|
"result type" (cwrap() syntax),
|
||||||
|
[arg types in cwrap() syntax]
|
||||||
|
]
|
||||||
|
|
||||||
|
If it has 4 elements, the first one is an alternate name to
|
||||||
|
use for the JS-side binding. That's required when overloading
|
||||||
|
a binding for two different uses.
|
||||||
|
*/
|
||||||
|
["sqlite3_open", "number", ["string", "number"]],
|
||||||
|
["sqlite3_close_v2", "number", ["number"]],
|
||||||
|
["sqlite3_exec", "number",
|
||||||
|
["number", "string", "number", "number", "number"]],
|
||||||
|
["sqlite3_changes", "number", ["number"]],
|
||||||
|
["sqlite3_prepare_v2", "number", ["number", "string", "number", "number", "number"]],
|
||||||
|
["sqlite3_prepare_v2_sqlptr",
|
||||||
|
/* Impl which requires that the 2nd argument be a pointer to
|
||||||
|
the SQL, instead of a string. This is used for cases where
|
||||||
|
we require a non-NULL value for the final argument. We may
|
||||||
|
or may not need this, depending on how our higher-level
|
||||||
|
API shapes up, but this code's spiritual guide (sql.js)
|
||||||
|
uses it we we'll include it. */
|
||||||
|
"sqlite3_prepare_v2",
|
||||||
|
"number", ["number", "number", "number", "number", "number"]],
|
||||||
|
["sqlite3_bind_text","number",["number", "number", "number", "number", "number"]],
|
||||||
|
["sqlite3_bind_blob","number",["number", "number", "number", "number", "number"]],
|
||||||
|
["sqlite3_bind_double","number",["number", "number", "number"]],
|
||||||
|
["sqlite3_bind_int","number",["number", "number", "number"]],
|
||||||
|
["sqlite3_bind_parameter_index","number",["number", "string"]],
|
||||||
|
["sqlite3_step", "number", ["number"]],
|
||||||
|
["sqlite3_errmsg", "string", ["number"]],
|
||||||
|
["sqlite3_column_count","number",["number"]],
|
||||||
|
["sqlite3_data_count", "number", ["number"]],
|
||||||
|
["sqlite3_column_count", "number", ["number"]],
|
||||||
|
["sqlite3_column_double","number",["number", "number"]],
|
||||||
|
["sqlite3_column_text","string",["number", "number"]],
|
||||||
|
["sqlite3_column_blob","number", ["number", "number"]],
|
||||||
|
["sqlite3_column_bytes","number",["number", "number"]],
|
||||||
|
["sqlite3_column_type","number",["number", "number"]],
|
||||||
|
["sqlite3_column_name","string",["number", "number"]],
|
||||||
|
["sqlite3_reset", "number", ["number"]],
|
||||||
|
["sqlite3_clear_bindings","number",["number"]],
|
||||||
|
["sqlite3_finalize", "number", ["number"]],
|
||||||
|
["sqlite3_create_function_v2", "number",
|
||||||
|
["number", "string", "number", "number",
|
||||||
|
"number", "number", "number", "number",
|
||||||
|
"number"]],
|
||||||
|
["sqlite3_value_type", "number", ["number"]],
|
||||||
|
["sqlite3_value_bytes","number",["number"]],
|
||||||
|
["sqlite3_value_text", "string", ["number"]],
|
||||||
|
["sqlite3_value_blob", "number", ["number"]],
|
||||||
|
["sqlite3_value_double","number",["number"]],
|
||||||
|
["sqlite3_result_double",null,["number", "number"]],
|
||||||
|
["sqlite3_result_null",null,["number"]],
|
||||||
|
["sqlite3_result_text",null,["number", "string", "number", "number"]],
|
||||||
|
["sqlite3_result_blob",null,["number", "number", "number", "number"]],
|
||||||
|
["sqlite3_result_int",null,["number", "number"]],
|
||||||
|
["sqlite3_result_error",null,["number", "string", "number"]],
|
||||||
|
["sqlite3_libversion", "string", []],
|
||||||
|
["sqlite3_sourceid", "string", []]
|
||||||
|
//["sqlite3_sql", "string", ["number"]],
|
||||||
|
//["sqlite3_normalized_sql", "string", ["number"]]
|
||||||
|
].forEach(function(e){
|
||||||
|
const a = Array.prototype.slice.call(e);
|
||||||
|
const k = (4==a.length) ? a.shift() : a[0];
|
||||||
|
api[k] = cwrap.apply(this, a);
|
||||||
|
});
|
||||||
|
//console.debug("libversion =",api.sqlite3_libversion());
|
||||||
|
namespace.sqlite3 = api;
|
||||||
|
})(self/*worker or window*/);
|
96
ext/fiddle/testing-common.js
Normal file
96
ext/fiddle/testing-common.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
2022-05-22
|
||||||
|
|
||||||
|
The author disclaims copyright to this source code. In place of a
|
||||||
|
legal notice, here is a blessing:
|
||||||
|
|
||||||
|
* May you do good and not evil.
|
||||||
|
* May you find forgiveness for yourself and forgive others.
|
||||||
|
* May you share freely, never taking more than you give.
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
|
||||||
|
This file contains bootstrapping code used by various test scripts
|
||||||
|
which live in this file's directory.
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
/* querySelectorAll() proxy */
|
||||||
|
const EAll = function(/*[element=document,] cssSelector*/){
|
||||||
|
return (arguments.length>1 ? arguments[0] : document)
|
||||||
|
.querySelectorAll(arguments[arguments.length-1]);
|
||||||
|
};
|
||||||
|
/* querySelector() proxy */
|
||||||
|
const E = function(/*[element=document,] cssSelector*/){
|
||||||
|
return (arguments.length>1 ? arguments[0] : document)
|
||||||
|
.querySelector(arguments[arguments.length-1]);
|
||||||
|
};
|
||||||
|
|
||||||
|
const statusElement = E('#module-status');
|
||||||
|
const progressElement = E('#module-progress');
|
||||||
|
const spinnerElement = E('#module-spinner');
|
||||||
|
|
||||||
|
self.Module = {
|
||||||
|
/* ^^^ cannot declare that const because fiddle-module.js
|
||||||
|
(auto-generated) includes a decl for it and runs in this scope. */
|
||||||
|
preRun: [],
|
||||||
|
postRun: [],
|
||||||
|
//onRuntimeInitialized: function(){},
|
||||||
|
print: function(){
|
||||||
|
console.log(Array.prototype.slice.call(arguments));
|
||||||
|
},
|
||||||
|
printErr: function(){
|
||||||
|
console.error(Array.prototype.slice.call(arguments));
|
||||||
|
},
|
||||||
|
setStatus: function f(text){
|
||||||
|
if(!f.last) f.last = { time: Date.now(), text: '' };
|
||||||
|
if(text === f.last.text) return;
|
||||||
|
const m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
|
||||||
|
const now = Date.now();
|
||||||
|
if(m && now - f.last.time < 30) return; // if this is a progress update, skip it if too soon
|
||||||
|
f.last.time = now;
|
||||||
|
f.last.text = text;
|
||||||
|
if(m) {
|
||||||
|
text = m[1];
|
||||||
|
progressElement.value = parseInt(m[2])*100;
|
||||||
|
progressElement.max = parseInt(m[4])*100;
|
||||||
|
progressElement.hidden = false;
|
||||||
|
spinnerElement.hidden = false;
|
||||||
|
} else {
|
||||||
|
progressElement.remove();
|
||||||
|
if(!text) spinnerElement.remove();
|
||||||
|
}
|
||||||
|
if(text) statusElement.innerText = text;
|
||||||
|
else statusElement.remove();
|
||||||
|
},
|
||||||
|
totalDependencies: 0,
|
||||||
|
monitorRunDependencies: function(left) {
|
||||||
|
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||||
|
this.setStatus(left
|
||||||
|
? ('Preparing... (' + (this.totalDependencies-left)
|
||||||
|
+ '/' + this.totalDependencies + ')')
|
||||||
|
: 'All downloads complete.');
|
||||||
|
},
|
||||||
|
/* Loads sqlite3-api.js and calls the given callback (if
|
||||||
|
provided), passing it the sqlite3 module. Whether this is
|
||||||
|
synchronous or async depends on whether it's run in the
|
||||||
|
main thread or a worker.*/
|
||||||
|
loadSqliteAPI: function(callback){
|
||||||
|
const theScript = 'sqlite3-api.js';
|
||||||
|
if(self.importScripts){/*worker*/
|
||||||
|
importScripts(theScript);
|
||||||
|
if(callback) callback(self.sqlite3);
|
||||||
|
}else{/*main thread*/
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
document.body.appendChild(script);
|
||||||
|
script.onload = resolve;
|
||||||
|
script.onerror = reject;
|
||||||
|
script.async = true;
|
||||||
|
script.src = theScript;
|
||||||
|
}).then(() => {
|
||||||
|
if(callback) callback(self.sqlite3);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(self/*window or worker*/);
|
31
ext/fiddle/testing1.html
Normal file
31
ext/fiddle/testing1.html
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link rel="stylesheet" href="emscripten.css"/>
|
||||||
|
<title>sqlite3-api.js tests</title>
|
||||||
|
<style></style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header id='titlebar'><span>sqlite3-api.js tests</span></header>
|
||||||
|
<!-- emscripten bits -->
|
||||||
|
<figure id="module-spinner">
|
||||||
|
<div class="spinner"></div>
|
||||||
|
<div class='center'><strong>Initializing app...</strong></div>
|
||||||
|
<div class='center'>
|
||||||
|
On a slow internet connection this may take a moment. If this
|
||||||
|
message displays for "a long time", intialization may have
|
||||||
|
failed and the JavaScript console may contain clues as to why.
|
||||||
|
</div>
|
||||||
|
</figure>
|
||||||
|
<div class="emscripten" id="module-status">Downloading...</div>
|
||||||
|
<div class="emscripten">
|
||||||
|
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
|
||||||
|
</div><!-- /emscripten bits -->
|
||||||
|
<div>Everything on this page happens in the dev console.</div>
|
||||||
|
<script src="testing-common.js"></script>
|
||||||
|
<script src="testing1.js"></script>
|
||||||
|
<script src="sqlite3.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
23
ext/fiddle/testing1.js
Normal file
23
ext/fiddle/testing1.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
2022-05-22
|
||||||
|
|
||||||
|
The author disclaims copyright to this source code. In place of a
|
||||||
|
legal notice, here is a blessing:
|
||||||
|
|
||||||
|
* May you do good and not evil.
|
||||||
|
* May you find forgiveness for yourself and forgive others.
|
||||||
|
* May you share freely, never taking more than you give.
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
|
||||||
|
A basic test script for sqlite3-api.js.
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
self.Module.onRuntimeInitialized = function(){
|
||||||
|
console.log("Loading sqlite3-api.js...");
|
||||||
|
self.Module.loadSqliteAPI(function(S){
|
||||||
|
console.log("Loaded module:",S.sqlite3_libversion(),
|
||||||
|
S.sqlite3_sourceid());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
})(self/*window or worker*/);
|
28
manifest
28
manifest
@ -1,9 +1,9 @@
|
|||||||
C Minor\sfiddle-related\sbuild\srestructuring\sto\ssupport\supcoming\sdevelopment\sof\sthe\sC-style\swasm\ssqlite3\sinterface,\splus\ssome\scommentary\sabout\sthe\splans\sand\sgoals\sfor\sthat.
|
C Build\srefactoring\sfor\sthe\sfiddle/wasm\sbits.\sSet\sup\swasm\sbinding\sof\sa\schunk\sof\sthe\score\sC\sAPI\sand\sadded\ssome\sinfastructure\sfor\screating\stest\spages\sfor\sit.
|
||||||
D 2022-05-21T21:13:44.686
|
D 2022-05-22T00:27:19.296
|
||||||
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 62df7206650987c76f15b2e1c23830976858892815b9fc4d283c850628e0c724
|
F Makefile.in a192a8de35ba61e6d695a3bd430b021e7cbf7ea473497028540801fe7b659282
|
||||||
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
||||||
F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3
|
F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3
|
||||||
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
|
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
|
||||||
@ -55,13 +55,19 @@ F ext/expert/expert1.test 3c642a4e7bbb14f21ddab595436fb465a4733f47a0fe5b2855e1d5
|
|||||||
F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0ff5d9cdfac204
|
F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0ff5d9cdfac204
|
||||||
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/EXPORTED_FUNCTIONS 487fc7c83d45c48326f731c89162ed17ab15767e5efede8999d7d6c6e2d04c0f
|
F ext/fiddle/EXPORTED_FUNCTIONS.fiddle 487fc7c83d45c48326f731c89162ed17ab15767e5efede8999d7d6c6e2d04c0f w ext/fiddle/EXPORTED_FUNCTIONS
|
||||||
|
F ext/fiddle/EXPORTED_FUNCTIONS.sqlite3 4b06e6c3ce8c8389274079ffb6b441ffff1a55e32a448cf21ce1da45a16c8a01
|
||||||
F ext/fiddle/EXPORTED_RUNTIME_METHODS 91d5dcb0168ee056fa1a340cb8ab3c23d922622f8dad39d28919dd8af2b3ade0
|
F ext/fiddle/EXPORTED_RUNTIME_METHODS 91d5dcb0168ee056fa1a340cb8ab3c23d922622f8dad39d28919dd8af2b3ade0
|
||||||
F ext/fiddle/Makefile b2904d52c10a7c984cfab95c54fb85f33aa8a6b2653faf1527d08ce57114be46
|
F ext/fiddle/Makefile 9277c73e208b9c8093659256c9f07409c877e366480c7c22ec545ee345451d95
|
||||||
F ext/fiddle/fiddle-worker.js 28e50e021e84aaedf4cbdb2ef25e4183f1e5be8da7996a50fc8d0b5ed78fa00a
|
F ext/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
F ext/fiddle/fiddle.html f536878dbaa35ba4d9ad8c87dda7fb2ea5502fdd824577d83b2265d65b8ca4d1
|
F ext/fiddle/fiddle-worker.js c22557b641b47fa1473d3465a4e69fe06b8b09b924955805a4202c8201ddc429
|
||||||
F ext/fiddle/fiddle.js 9361d451845ac3c97c5492c24c8d18b8fe2deff07741462bdf8e39c375be25b2
|
F ext/fiddle/fiddle.html 657c6c3f860c322fba3c69fa4f7a1209e2d2ce44b4bc65a3e154e3a97c047a7c
|
||||||
|
F ext/fiddle/fiddle.js f9c79164428e96a5909532f18a8bc8f8c8ec4f738bfc09ad3d2a532c2400f9f0
|
||||||
F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf
|
F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf
|
||||||
|
F ext/fiddle/sqlite3-api.js d3c6da99850e146e50dc42039ac027e5d9b08b9f24eb22b31d1982c49930ee7c
|
||||||
|
F ext/fiddle/testing-common.js 37b014758db7e5e74278e37dc712ced2fc9b40d0617f5ed0b8b64a6bd9c0a45d
|
||||||
|
F ext/fiddle/testing1.html 68cec1b1c8646a071717e5979f22e4268e6d36d96ba13ad68333351acdbcf1d1
|
||||||
|
F ext/fiddle/testing1.js 0fb900c768b06c2ec3922ab522f721a68b0756d200e3c66602461f45910bcd39
|
||||||
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
|
||||||
@ -1961,8 +1967,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 5ff3326856bc190cee15a5fca5ded89aacc4bf931a8df98726a872b310e2a4fc
|
P c7cfdd4c3682659352642461d3307bf8180703b121ec1802ba5881f8e1ef9809
|
||||||
R 3ab23a2e617cc2f177067d0130c7a41f
|
R d89e623e1614875df0e3a579152a2be9
|
||||||
U stephan
|
U stephan
|
||||||
Z 0792a8e58fb57cfdbc5dcb7974589bd6
|
Z fd89698a5fe01334529b2fb407d595a1
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@ -1 +1 @@
|
|||||||
c7cfdd4c3682659352642461d3307bf8180703b121ec1802ba5881f8e1ef9809
|
dea098b64eb95c395b346ebcae687afe42b7d21df48833527808c02226300a66
|
Reference in New Issue
Block a user