Got the sqlite3-api JS bits wrapped up in deferred-load module. Whether that's going to be easier to use, in practice, remains to be seen. Consolidated two of the test-related JS files.
FossilOrigin-Name: dd83cc05f2522d221641807dd66b33df48ac9264f27e5b6f63f312084f109801
This commit is contained in:
+6
-1
@@ -1540,18 +1540,23 @@ $(fiddle_module_js): Makefile sqlite3.c shell.c \
|
||||
$(fiddle_dir)/EXPORTED_RUNTIME_METHODS \
|
||||
$(fiddle_dir)/EXPORTED_FUNCTIONS.fiddle
|
||||
emcc -o $@ $(emcc_flags) \
|
||||
-sENVIRONMENT=web \
|
||||
-sMODULARIZE \
|
||||
-sEXPORT_NAME=initFiddleModule \
|
||||
-sENVIRONMENT=web \
|
||||
-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)/sqlite3-api.js \
|
||||
$(fiddle_dir)/EXPORTED_RUNTIME_METHODS \
|
||||
$(fiddle_dir)/EXPORTED_FUNCTIONS.sqlite3-api
|
||||
emcc -o $@ $(emcc_flags) \
|
||||
-sENVIRONMENT=web \
|
||||
-sMODULARIZE \
|
||||
-sEXPORT_NAME=initSqlite3Module \
|
||||
-sEXPORTED_RUNTIME_METHODS=@$(fiddle_dir_abs)/EXPORTED_RUNTIME_METHODS \
|
||||
-sEXPORTED_FUNCTIONS=@$(fiddle_dir_abs)/EXPORTED_FUNCTIONS.sqlite3-api \
|
||||
--post-js=$(fiddle_dir)/sqlite3-api.js \
|
||||
--no-entry \
|
||||
sqlite3.c
|
||||
fiddle: $(fiddle_module_js)
|
||||
|
||||
+2
-2
@@ -1,10 +1,10 @@
|
||||
# This GNU makefile exists primarily to simplify/speed up development
|
||||
# from emacs. It is not part of the canonical build process.
|
||||
default:
|
||||
make -C ../.. wasm -e emcc_opt=-O0
|
||||
$(MAKE) -C ../.. wasm -e emcc_opt=-O0
|
||||
|
||||
clean:
|
||||
make -C ../../ clean-wasm
|
||||
$(MAKE) -C ../../ clean-wasm
|
||||
|
||||
fiddle_files = emscripten.css fiddle.html \
|
||||
fiddle.js fiddle-module.js \
|
||||
|
||||
+140
-50
@@ -1,54 +1,144 @@
|
||||
/**
|
||||
Helpers for writing sqlite3-specific tests.
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
self/*window or worker*/.SqliteTestUtil = {
|
||||
/** Running total of the number of tests run via
|
||||
this API. */
|
||||
counter: 0,
|
||||
(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]);
|
||||
};
|
||||
|
||||
/**
|
||||
If expr is a function, it is called and its result
|
||||
is returned, coerced to a bool, else expr, coerced to
|
||||
a bool, is returned.
|
||||
Helpers for writing sqlite3-specific tests.
|
||||
*/
|
||||
toBool: function(expr){
|
||||
return (expr instanceof Function) ? !!expr() : !!expr;
|
||||
},
|
||||
/** abort() if expr is false. If expr is a function, it
|
||||
is called and its result is evaluated.
|
||||
self/*window or worker*/.SqliteTestUtil = {
|
||||
/** Running total of the number of tests run via
|
||||
this API. */
|
||||
counter: 0,
|
||||
/**
|
||||
If expr is a function, it is called and its result
|
||||
is returned, coerced to a bool, else expr, coerced to
|
||||
a bool, is returned.
|
||||
*/
|
||||
toBool: function(expr){
|
||||
return (expr instanceof Function) ? !!expr() : !!expr;
|
||||
},
|
||||
/** abort() if expr is false. If expr is a function, it
|
||||
is called and its result is evaluated.
|
||||
*/
|
||||
assert: function f(expr, msg){
|
||||
if(!f._){
|
||||
f._ = ('undefined'===typeof abort
|
||||
? (msg)=>{throw new Error(msg)}
|
||||
: abort);
|
||||
}
|
||||
++this.counter;
|
||||
if(!this.toBool(expr)){
|
||||
f._(msg || "Assertion failed.");
|
||||
}
|
||||
return this;
|
||||
},
|
||||
/** Identical to assert() but throws instead of calling
|
||||
abort(). */
|
||||
affirm: function(expr, msg){
|
||||
++this.counter;
|
||||
if(!this.toBool(expr)) throw new Error(msg || "Affirmation failed.");
|
||||
return this;
|
||||
},
|
||||
/** Calls f() and squelches any exception it throws. If it
|
||||
does not throw, this function throws. */
|
||||
mustThrow: function(f, msg){
|
||||
++this.counter;
|
||||
let err;
|
||||
try{ f(); } catch(e){err=e;}
|
||||
if(!err) throw new Error(msg || "Expected exception.");
|
||||
return this;
|
||||
},
|
||||
/** Throws if expr is truthy or expr is a function and expr()
|
||||
returns truthy. */
|
||||
throwIf: function(expr, msg){
|
||||
++this.counter;
|
||||
if(this.toBool(expr)) throw new Error(msg || "throwIf() failed");
|
||||
return this;
|
||||
},
|
||||
/** Throws if expr is falsy or expr is a function and expr()
|
||||
returns falsy. */
|
||||
throwUnless: function(expr, msg){
|
||||
++this.counter;
|
||||
if(!this.toBool(expr)) throw new Error(msg || "throwUnless() failed");
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
This is a module object for use with the emscripten-installed
|
||||
initSqlite3Module() factory function.
|
||||
*/
|
||||
assert: function(expr, msg){
|
||||
++this.counter;
|
||||
if(!this.toBool(expr)) abort(msg || "Assertion failed.");
|
||||
return this;
|
||||
},
|
||||
/** Identical to assert() but throws instead of calling
|
||||
abort(). */
|
||||
affirm: function(expr, msg){
|
||||
++this.counter;
|
||||
if(!this.toBool(expr)) throw new Error(msg || "Affirmation failed.");
|
||||
return this;
|
||||
},
|
||||
/** Calls f() and squelches any exception it throws. If it
|
||||
does not throw, this function throws. */
|
||||
mustThrow: function(f, msg){
|
||||
++this.counter;
|
||||
let err;
|
||||
try{ f(); } catch(e){err=e;}
|
||||
if(!err) throw new Error(msg || "Expected exception.");
|
||||
return this;
|
||||
},
|
||||
/** Throws if expr is truthy or expr is a function and expr()
|
||||
returns truthy. */
|
||||
throwIf: function(expr, msg){
|
||||
++this.counter;
|
||||
if(this.toBool(expr)) throw new Error(msg || "throwIf() failed");
|
||||
return this;
|
||||
},
|
||||
/** Throws if expr is falsy or expr is a function and expr()
|
||||
returns falsy. */
|
||||
throwUnless: function(expr, msg){
|
||||
++this.counter;
|
||||
if(!this.toBool(expr)) throw new Error(msg || "throwUnless() failed");
|
||||
return this;
|
||||
}
|
||||
};
|
||||
self.sqlite3TestModule = {
|
||||
postRun: [
|
||||
/* function(theModule){...} */
|
||||
],
|
||||
//onRuntimeInitialized: function(){},
|
||||
/* Proxy for C-side stdout output. */
|
||||
print: function(){
|
||||
console.log.apply(console, Array.prototype.slice.call(arguments));
|
||||
},
|
||||
/* Proxy for C-side stderr output. */
|
||||
printErr: function(){
|
||||
console.error.apply(console, Array.prototype.slice.call(arguments));
|
||||
},
|
||||
/**
|
||||
Called by the module init bits to report loading
|
||||
progress. It gets passed an empty argument when loading is
|
||||
done (after onRuntimeInitialized() and any this.postRun
|
||||
callbacks have been run).
|
||||
*/
|
||||
setStatus: function f(text){
|
||||
if(!f.last){
|
||||
f.last = { text: '', step: 0 };
|
||||
f.ui = {
|
||||
status: E('#module-status'),
|
||||
progress: E('#module-progress'),
|
||||
spinner: E('#module-spinner')
|
||||
};
|
||||
}
|
||||
if(text === f.last.text) return;
|
||||
f.last.text = text;
|
||||
if(f.ui.progress){
|
||||
f.ui.progress.value = f.last.step;
|
||||
f.ui.progress.max = f.last.step + 1;
|
||||
}
|
||||
++f.last.step;
|
||||
if(text) {
|
||||
f.ui.status.classList.remove('hidden');
|
||||
f.ui.status.innerText = text;
|
||||
}else{
|
||||
if(f.ui.progress){
|
||||
f.ui.progress.remove();
|
||||
f.ui.spinner.remove();
|
||||
delete f.ui.progress;
|
||||
delete f.ui.spinner;
|
||||
}
|
||||
f.ui.status.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
};
|
||||
})(self/*window or worker*/);
|
||||
|
||||
+46
-36
@@ -10,40 +10,45 @@
|
||||
|
||||
***********************************************************************
|
||||
|
||||
This file is intended to be loaded after loading sqlite3.wasm. It
|
||||
sets up one of any number of potential bindings using that API, this
|
||||
one as closely matching the C-native API as is feasible in JS.
|
||||
This file is intended to be appended to the emcc-generated
|
||||
sqlite3.js via emcc:
|
||||
|
||||
Note that this file is not named sqlite3.js because that file gets
|
||||
generated by emscripten as the JS-glue counterpart of sqlite3.wasm.
|
||||
emcc ... -sMODULARIZE -sEXPORT_NAME=initSqlite3Module --post-js=THIS_FILE
|
||||
|
||||
This code installs an object named self.Module.sqlite3, where self
|
||||
is expected to be either the global window or Worker object and
|
||||
Module is the object set up by the emscripten infrastructure. The
|
||||
sqlite3 object looks like:
|
||||
It is loaded by importing the emcc-generated sqlite3.js, then:
|
||||
|
||||
{
|
||||
api: bindings for much of the core sqlite3 APIs,
|
||||
SQLite3: high-level OO API wrapper
|
||||
}
|
||||
initSqlite3Module({module object}).then(
|
||||
function(theModule){
|
||||
theModule.sqlite3 == an object containing this file's
|
||||
deliverables:
|
||||
{
|
||||
api: bindings for much of the core sqlite3 APIs,
|
||||
SQLite3: high-level OO API wrapper
|
||||
}
|
||||
});
|
||||
|
||||
The way we export this module is not _really_ modern-JS-friendly
|
||||
because it exports/relies on a global symbol (which is admittedly
|
||||
not ideal). Exporting it "cleanly," without introducing any
|
||||
global-scope symbols, requires using a module loader in all client
|
||||
code. As there are several different approaches, none of which this
|
||||
developer is currently truly familiar with, the current approach
|
||||
will have to do for the time being.
|
||||
It is up to the caller to provide a module object compatible with
|
||||
emcc, but it can be a plain empty object. The object passed to
|
||||
initSqlite3Module() will get populated by the emscripten-generated
|
||||
bits and, in part, by the code from this file. Specifically, this file
|
||||
installs the `theModule.sqlite3` part shown above.
|
||||
|
||||
The resulting sqlite3.api object wraps the standard sqlite3 C API in
|
||||
a way as close to its native form as JS allows for. The
|
||||
sqlite3.SQLite3 object provides a higher-level wrapper more
|
||||
appropriate for general client-side use in JS.
|
||||
|
||||
Because using certain parts of the low-level API properly requires
|
||||
some degree of WASM-related magic, it is not recommended that that
|
||||
API be used as-is in client-level code. Rather, client code should
|
||||
use the higher-level OO API or write a custom wrapper on top of the
|
||||
lower-level API. In short, using any C-style APIs which take
|
||||
lower-level API. In short, most of the C-style API is used in an
|
||||
intuitive manner from JS but any C-style APIs which take
|
||||
pointers-to-pointer arguments require WASM-specific interfaces
|
||||
installed by emcscripten-generated code. Those which take or return
|
||||
only integers, doubles, strings, or "plain" pointers to db or
|
||||
statement objects can be used in a straightforward manner.
|
||||
statement objects can be used in "as normal," noting that "pointers"
|
||||
in wasm are simply 32-bit integers.
|
||||
|
||||
# Goals and Non-goals of this API
|
||||
|
||||
@@ -77,7 +82,10 @@
|
||||
modern web and requires modern platforms.
|
||||
|
||||
*/
|
||||
(function(namespace){
|
||||
if(!Module.postRun) Module.postRun = [];
|
||||
/* ^^^^ the name Module is, in this setup, scope-local in the generated
|
||||
file sqlite3.js, with which this file gets combined at build-time. */
|
||||
Module.postRun.push(function(namespace){
|
||||
'use strict';
|
||||
/* For reference: sql.js does essentially everything we want and
|
||||
it solves much of the wasm-related voodoo, but we'll need a
|
||||
@@ -111,6 +119,8 @@
|
||||
clear and much experimentation is pending.
|
||||
*/
|
||||
|
||||
const SQM = namespace/*the sqlite module object */;
|
||||
|
||||
/**
|
||||
Set up the main sqlite3 binding API here, mimicking the C API as
|
||||
closely as we can.
|
||||
@@ -157,7 +167,7 @@
|
||||
will only support UTF8. */
|
||||
SQLITE_UTF8: 1
|
||||
};
|
||||
const cwrap = Module.cwrap;
|
||||
const cwrap = SQM.cwrap;
|
||||
[/* C-side functions to bind. Each entry is an array with 3 or 4
|
||||
elements:
|
||||
|
||||
@@ -237,7 +247,6 @@
|
||||
const k = (4==a.length) ? a.shift() : a[0];
|
||||
api[k] = cwrap.apply(this, a);
|
||||
});
|
||||
//console.debug("libversion =",api.sqlite3_libversion());
|
||||
|
||||
/* What follows is colloquially known as "OO API #1". It is a
|
||||
binding of the sqlite3 API which is designed to be run within
|
||||
@@ -418,7 +427,7 @@
|
||||
delete that._statements[k];
|
||||
if(s && s._pStmt) s.finalize();
|
||||
});
|
||||
Object.values(this._udfs).forEach(Module.removeFunction);
|
||||
Object.values(this._udfs).forEach(SQM.removeFunction);
|
||||
delete this._udfs;
|
||||
delete this._statements;
|
||||
delete this.filename;
|
||||
@@ -562,7 +571,7 @@
|
||||
(opt.callback && opt.rowMode)
|
||||
? opt.rowMode : false);
|
||||
try{
|
||||
let pSql = allocateUTF8OnStack(arg.sql)
|
||||
let pSql = SQM.allocateUTF8OnStack(arg.sql)
|
||||
const pzTail = stackAlloc(4);
|
||||
while(getValue(pSql, "i8")){
|
||||
setValue(pPtrArg, 0, "i32");
|
||||
@@ -731,9 +740,10 @@
|
||||
api.sqlite3_result_null(pCx);
|
||||
break;
|
||||
}else if(undefined!==val.length){
|
||||
const pBlob = Module.allocate(val, ALLOC_NORMAL);
|
||||
const pBlob =
|
||||
SQM.allocate(val, SQM.ALLOC_NORMAL);
|
||||
api.sqlite3_result_blob(pCx, pBlob, val.length, -1/*==SQLITE_TRANSIENT*/);
|
||||
Module._free(blobptr);
|
||||
SQM._free(blobptr);
|
||||
break;
|
||||
}
|
||||
// else fall through
|
||||
@@ -749,7 +759,7 @@
|
||||
api.sqlite3_result_error(pCx, e.message, -1);
|
||||
}
|
||||
};
|
||||
const pUdf = Module.addFunction(wrapper, "viii");
|
||||
const pUdf = SQM.addFunction(wrapper, "viii");
|
||||
let fFlags = 0;
|
||||
if(getOwnOption(opt, 'deterministic')) fFlags |= api.SQLITE_DETERMINISTIC;
|
||||
if(getOwnOption(opt, 'directOnly')) fFlags |= api.SQLITE_DIRECTONLY;
|
||||
@@ -762,11 +772,11 @@
|
||||
api.SQLITE_UTF8 | fFlags, null/*pApp*/, pUdf,
|
||||
null/*xStep*/, null/*xFinal*/, null/*xDestroy*/));
|
||||
}catch(e){
|
||||
Module.removeFunction(pUdf);
|
||||
SQM.removeFunction(pUdf);
|
||||
throw e;
|
||||
}
|
||||
if(this._udfs.hasOwnProperty(name)){
|
||||
Module.removeFunction(this._udfs[name]);
|
||||
SQM.removeFunction(this._udfs[name]);
|
||||
}
|
||||
this._udfs[name] = pUdf;
|
||||
return this;
|
||||
@@ -911,7 +921,7 @@
|
||||
f._ = {
|
||||
string: function(stmt, ndx, val, asBlob){
|
||||
const bytes = intArrayFromString(val,true);
|
||||
const pStr = Module.allocate(bytes, ALLOC_NORMAL);
|
||||
const pStr = SQM.allocate(bytes, ALLOC_NORMAL);
|
||||
stmt._allocs.push(pStr);
|
||||
const func = asBlob ? api.sqlite3_bind_blob : api.sqlite3_bind_text;
|
||||
return func(stmt._pStmt, ndx, pStr, bytes.length, 0);
|
||||
@@ -950,7 +960,7 @@
|
||||
toss("Binding a value as a blob requires",
|
||||
"that it have a length member.");
|
||||
}
|
||||
const pBlob = Module.allocate(val, ALLOC_NORMAL);
|
||||
const pBlob = SQM.allocate(val, ALLOC_NORMAL);
|
||||
stmt._allocs.push(pBlob);
|
||||
rc = api.sqlite3_bind_blob(stmt._pStmt, ndx, pBlob, len, 0);
|
||||
}
|
||||
@@ -966,7 +976,7 @@
|
||||
const freeBindMemory = function(stmt){
|
||||
let m;
|
||||
while(undefined !== (m = stmt._allocs.pop())){
|
||||
Module._free(m);
|
||||
SQM._free(m);
|
||||
}
|
||||
return stmt;
|
||||
};
|
||||
@@ -1383,4 +1393,4 @@
|
||||
api: api,
|
||||
SQLite3
|
||||
};
|
||||
})(self/*worker or window*/.Module);
|
||||
});
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
/*
|
||||
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]);
|
||||
};
|
||||
|
||||
/* emscripten-related bits... */
|
||||
self.Module = {
|
||||
/* ^^^ cannot declare that const because sqlite3.js
|
||||
(auto-generated) includes a decl for it and runs in this
|
||||
scope. */
|
||||
preRun: [],
|
||||
postRun: [],
|
||||
//onRuntimeInitialized: function(){},
|
||||
print: function(){
|
||||
console.log.apply(console, Array.prototype.slice.call(arguments));
|
||||
},
|
||||
printErr: function(){
|
||||
console.error.apply(console, Array.prototype.slice.call(arguments));
|
||||
},
|
||||
setStatus: function f(text){
|
||||
if(!f.last){
|
||||
f.last = { text: '', step: 0 };
|
||||
f.ui = {
|
||||
status: E('#module-status'),
|
||||
progress: E('#module-progress'),
|
||||
spinner: E('#module-spinner')
|
||||
};
|
||||
}
|
||||
if(text === f.last.text) return;
|
||||
f.last.text = text;
|
||||
if(f.ui.progress){
|
||||
f.ui.progress.value = f.last.step;
|
||||
f.ui.progress.max = f.last.step + 1;
|
||||
}
|
||||
++f.last.step;
|
||||
if(text) {
|
||||
f.ui.status.classList.remove('hidden');
|
||||
f.ui.status.innerText = text;
|
||||
}else{
|
||||
if(f.ui.progress){
|
||||
f.ui.progress.remove();
|
||||
f.ui.spinner.remove();
|
||||
delete f.ui.progress;
|
||||
delete f.ui.spinner;
|
||||
}
|
||||
f.ui.status.classList.add('hidden');
|
||||
}
|
||||
},
|
||||
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 an object:
|
||||
|
||||
{
|
||||
api:sqlite3_c-like API wrapper,
|
||||
SQLite3: OO wrapper
|
||||
}
|
||||
|
||||
Whether this is synchronous or async depends on whether
|
||||
it's run in the main thread (async) or a worker
|
||||
(synchronous).
|
||||
|
||||
If called after the module has been loaded, it uses a
|
||||
cached reference, noting that multiple async calls may end
|
||||
up loading it multiple times.
|
||||
*/
|
||||
loadSqliteAPI: function f(callback){
|
||||
const namespace = self.Module;
|
||||
if(namespace.sqlite3){
|
||||
if(callback) callback(namespace.sqlite3);
|
||||
return;
|
||||
}
|
||||
const theScript = 'sqlite3-api.js';
|
||||
if(self.importScripts){/*worker*/
|
||||
importScripts(theScript);
|
||||
if(callback) callback(namespace.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(namespace.sqlite3);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})(self/*window or worker*/);
|
||||
@@ -26,9 +26,8 @@
|
||||
<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="SqliteTestUtil.js"></script>
|
||||
<script src="testing-common.js"></script>
|
||||
<script src="testing1.js"></script>
|
||||
<script src="sqlite3.js"></script>
|
||||
<script src="SqliteTestUtil.js"></script>
|
||||
<script src="testing1.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+21
-11
@@ -16,7 +16,14 @@
|
||||
const T = self.SqliteTestUtil;
|
||||
const log = console.log.bind(console);
|
||||
|
||||
const test1 = function(db,api){
|
||||
const assert = function(condition, text) {
|
||||
if (!condition) {
|
||||
throw new Error('Assertion failed' + (text ? ': ' + text : ''));
|
||||
}
|
||||
};
|
||||
|
||||
const test1 = function(db,sqlite3){
|
||||
const api = sqlite3.api;
|
||||
log("Basic sanity tests...");
|
||||
T.assert(db._pDb);
|
||||
let st = db.prepare("select 3 as a");
|
||||
@@ -114,13 +121,14 @@ INSERT INTO t(a,b) VALUES(1,2),(3,4),(?,?);`,
|
||||
assert(null === db.selectValue("select $a",{$a:null}));
|
||||
};
|
||||
|
||||
const runTests = function(namespace){
|
||||
const runTests = function(Module){
|
||||
T.assert(Module._free instanceof Function).
|
||||
assert(Module.allocate instanceof Function).
|
||||
assert(Module.addFunction instanceof Function).
|
||||
assert(Module.removeFunction instanceof Function);
|
||||
const api = namespace.api;
|
||||
const oo = namespace.SQLite3;
|
||||
const sqlite3 = Module.sqlite3;
|
||||
const api = sqlite3.api;
|
||||
const oo = sqlite3.SQLite3;
|
||||
console.log("Loaded module:",api.sqlite3_libversion(),
|
||||
api.sqlite3_sourceid());
|
||||
log("Build options:",oo.compileOptionUsed());
|
||||
@@ -129,17 +137,19 @@ INSERT INTO t(a,b) VALUES(1,2),(3,4),(?,?);`,
|
||||
log("DB:",db.filename);
|
||||
[
|
||||
test1, testUDF
|
||||
].forEach((f)=>f(db, api));
|
||||
].forEach((f)=>f(db, sqlite3));
|
||||
}finally{
|
||||
db.close();
|
||||
}
|
||||
log("Total Test count:",T.counter);
|
||||
};
|
||||
|
||||
self.Module.postRun.push(function(theModule){
|
||||
/** Use a timeout so that we are (hopefully) out from under the
|
||||
module init stack when our setup gets run. Just on principle,
|
||||
not because we _need_ to be. */
|
||||
setTimeout(()=>theModule.loadSqliteAPI(runTests), 0);
|
||||
initSqlite3Module(self.sqlite3TestModule).then(function(theModule){
|
||||
/** Use a timeout so that we are (hopefully) out from
|
||||
under the module init stack when our setup gets
|
||||
run. Just on principle, not because we _need_ to
|
||||
be. */
|
||||
//console.debug("theModule =",theModule);
|
||||
setTimeout(()=>runTests(theModule), 0);
|
||||
});
|
||||
})(self/*window or worker*/);
|
||||
})();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
C Renamed\sEXPORTED_FUNCTIONS.sqlite3\sto\sEXPORTED_FUNCTIONS.sqlite3-api\sto\savoid\sany\spotential\sconfusion\sabout\sthat\sfile\s(not)\sbeing\san\ssqlite3\sdatabase.
|
||||
D 2022-05-25T04:38:35.081
|
||||
C Got\sthe\ssqlite3-api\sJS\sbits\swrapped\sup\sin\sdeferred-load\smodule.\sWhether\sthat's\sgoing\sto\sbe\seasier\sto\suse,\sin\spractice,\sremains\sto\sbe\sseen.\sConsolidated\stwo\sof\sthe\stest-related\sJS\sfiles.
|
||||
D 2022-05-25T08:51:07.626
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
F Makefile.in 335ac492dc602e7a7da3be3df020eac3b439a07cbdcf00a71b58304d7068257f
|
||||
F Makefile.in 7ad689fdbe11297af09488b00c88b133b1505d6559bdad1f1829b6b7388c05be
|
||||
F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241
|
||||
F Makefile.msc b28a8a7a977e7312f6859f560348e1eb110c21bd6cf9fab0d16537c0a514eef3
|
||||
F README.md 8b8df9ca852aeac4864eb1e400002633ee6db84065bd01b78c33817f97d31f5e
|
||||
@@ -56,20 +56,19 @@ F ext/expert/sqlite3expert.c 6ca30d73b9ed75bd56d6e0d7f2c962d2affaa72c505458619d0
|
||||
F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b
|
||||
F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72
|
||||
F ext/fiddle/EXPORTED_FUNCTIONS.fiddle 2f7c561af85e6d711fb42f395bc0074b6e6fcf16bc57d495ce4e1c3d0484c5d2
|
||||
F ext/fiddle/EXPORTED_FUNCTIONS.sqlite3-api 540b9dec63a3a62a256e2f030827848a92e9b9d9b6fa5c0188295a4a1c5382cd w ext/fiddle/EXPORTED_FUNCTIONS.sqlite3
|
||||
F ext/fiddle/EXPORTED_FUNCTIONS.sqlite3-api 540b9dec63a3a62a256e2f030827848a92e9b9d9b6fa5c0188295a4a1c5382cd
|
||||
F ext/fiddle/EXPORTED_RUNTIME_METHODS b831017ba67ba993b34a27400cef2f6095bd6789c0fc4eba7e7a251c207be31c
|
||||
F ext/fiddle/Makefile 2608fe0c56fa8f9cdf17e28d2be6def550a2fe987db5f7fc06d0210bfc868258
|
||||
F ext/fiddle/SqliteTestUtil.js e3094833660a6ddd40766b802901b5861b37f0b89c6c577ee0ce4c9d36399e61
|
||||
F ext/fiddle/Makefile de65d04bfb312e94dbd7a0e7d99fb126f0abc1db62f920159c4124b5a42347d8
|
||||
F ext/fiddle/SqliteTestUtil.js 559731c3e8e0de330ec7d292e6c1846566408caee6637acc8a119ac338a8781c
|
||||
F ext/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||
F ext/fiddle/fiddle-worker.js 6000da12965319bed53d546f87885a6717a0cd8de0b4832edde7a95e63d1f33e
|
||||
F ext/fiddle/fiddle.html 70796dc8a867448b41bc7e2c5fd6b1865ed8010b3abe22ba0678e8915c062e9a
|
||||
F ext/fiddle/fiddle.js 45f96ac7f7d6678503568dded46afaa741d841a2464519035636da0fd77aec50
|
||||
F ext/fiddle/index.md d9c1c308d8074341bc3b11d1d39073cd77754cb3ca9aeb949f23fdd8323d81cf
|
||||
F ext/fiddle/sqlite3-api.js ce08520b8117e4fbbbeb02d8d047defd4e8507d687e76d20a39f12401bad0219
|
||||
F ext/fiddle/testing-common.js a2527fd8dfb500bad9b434ae2645bb91489792115ee1e1b4b53cac4e9198992a
|
||||
F ext/fiddle/sqlite3-api.js 8500698d2163f4a25f8e5e6810ad826487342579d6a321d82b244dbc8e6f6db6
|
||||
F ext/fiddle/testing.css 750572dded671d2cf142bbcb27af5542522ac08db128245d0b9fe410aa1d7f2a
|
||||
F ext/fiddle/testing1.html 0a59d6cfb4cb16982c45ae3fabb1e090d122ca59285be97f3c01743eb75d6d73
|
||||
F ext/fiddle/testing1.js a2cee7ee12c2e1756e775125b0f9950dc5e5faeeeb4979c6d9894626d90cb5d9
|
||||
F ext/fiddle/testing1.html ea1f3be727f78e420007f823912c1a03b337ecbb8e79449abc2244ad4fe15d9a
|
||||
F ext/fiddle/testing1.js 94a7597955c8fdbd15839a70d9b8279bc690205dda65ff175f688f13bf315745
|
||||
F ext/fts1/README.txt 20ac73b006a70bcfd80069bdaf59214b6cf1db5e
|
||||
F ext/fts1/ft_hash.c 3927bd880e65329bdc6f506555b228b28924921b
|
||||
F ext/fts1/ft_hash.h 06df7bba40dadd19597aa400a875dbc2fed705ea
|
||||
@@ -1969,8 +1968,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P e0c30438a4f1372afb93a0488bae17b3f85d535717b215f494a83ae909871d2c
|
||||
R 9374645be385492e5cf981b1ed91722a
|
||||
P 3d6245c6f9f2ef4ca6746639d300cc5795598b119034439dfed671de3da638fb
|
||||
R 0cd793b0df7e1a958b5a7fb6c581456e
|
||||
U stephan
|
||||
Z 0e306e7b329adee899bf0b24535c7b65
|
||||
Z 24d1fc51d53037dbed19059815815fc9
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
3d6245c6f9f2ef4ca6746639d300cc5795598b119034439dfed671de3da638fb
|
||||
dd83cc05f2522d221641807dd66b33df48ac9264f27e5b6f63f312084f109801
|
||||
Reference in New Issue
Block a user