Merge the latest trunk enhancements into the json-opt branch.
FossilOrigin-Name: 00bfc4918be49ac74a3e7851c88ab7ec226e6a37853f8ad4c77f758751960456
This commit is contained in:
commit
7d70571142
@ -18,8 +18,6 @@
|
||||
# quick, q = do just a minimal build (sqlite3.js/wasm, tester1) for
|
||||
# faster development-mode turnaround.
|
||||
#
|
||||
# qo2, qoz = a combination of quick+o2/oz.
|
||||
#
|
||||
# dist = create end user deliverables. Add dist.build=oX to build
|
||||
# with a specific optimization level, where oX is one of the
|
||||
# above-listed o? or qo? target names.
|
||||
@ -46,11 +44,12 @@
|
||||
# $(eval), or at least centralize the setup of the numerous vars
|
||||
# related to each build variant $(JS_BUILD_MODES).
|
||||
#
|
||||
default: all
|
||||
#default: quick
|
||||
SHELL := $(shell which bash 2>/dev/null)
|
||||
MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||
CLEAN_FILES :=
|
||||
DISTCLEAN_FILES := ./--dummy--
|
||||
default: all
|
||||
release: oz
|
||||
# JS_BUILD_MODES exists solely to reduce repetition in documentation
|
||||
# below.
|
||||
@ -182,7 +181,7 @@ SQLITE_OPT = \
|
||||
-DSQLITE_OMIT_SHARED_CACHE \
|
||||
-DSQLITE_OMIT_WAL \
|
||||
-DSQLITE_THREADSAFE=0 \
|
||||
-DSQLITE_TEMP_STORE=3 \
|
||||
-DSQLITE_TEMP_STORE=2 \
|
||||
-DSQLITE_OS_KV_OPTIONAL=1 \
|
||||
'-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \
|
||||
-DSQLITE_USE_URI=1 \
|
||||
@ -375,6 +374,7 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-v-helper.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js
|
||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
|
||||
|
||||
# SOAP.js is an external API file which is part of our distribution
|
||||
@ -754,7 +754,7 @@ $(5): $(4) $$(MAKEFILE) $$(sqlite3-wasm.cfiles) $$(EXPORTED_FUNCTIONS.api) $$(pr
|
||||
esac; \
|
||||
ls -la $$$$dotwasm $$@
|
||||
all: $(5)
|
||||
quick: $(5)
|
||||
#quick: $(5)
|
||||
CLEAN_FILES += $(4) $(5)
|
||||
endef
|
||||
# ^^^ /SETUP_LIB_BUILD_MODE
|
||||
@ -959,6 +959,7 @@ tester1: tester1.js tester1.mjs tester1.html tester1-esm.html
|
||||
# Note that we do not include $(sqlite3-bundler-friendly.mjs) in this
|
||||
# because bundlers are client-specific.
|
||||
all quick: tester1
|
||||
quick: $(sqlite3.js)
|
||||
|
||||
########################################################################
|
||||
# Convenience rules to rebuild with various -Ox levels. Much
|
||||
@ -978,8 +979,6 @@ o1: clean
|
||||
$(MAKE) -e "emcc_opt=-O1 $(o-xtra)"
|
||||
o2: clean
|
||||
$(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)"
|
||||
qo2: clean
|
||||
$(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)" quick
|
||||
o3: clean
|
||||
$(MAKE) -e "emcc_opt=-O3 $(o-xtra)"
|
||||
os: clean
|
||||
@ -987,8 +986,6 @@ os: clean
|
||||
$(MAKE) -e "emcc_opt=-Os $(o-xtra)"
|
||||
oz: clean
|
||||
$(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)"
|
||||
qoz: clean
|
||||
$(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)" quick
|
||||
|
||||
########################################################################
|
||||
# Sub-makes...
|
||||
|
@ -82,7 +82,7 @@ features in the apps which use them.
|
||||
|
||||
# Testing on a remote machine that is accessed via SSH
|
||||
|
||||
*NB: The following are developer notes, last validated on 2022-08-18*
|
||||
*NB: The following are developer notes, last validated on 2023-07-19*
|
||||
|
||||
* Remote: Install git, emsdk, and althttpd
|
||||
* Use a [version of althttpd][althttpd] from
|
||||
@ -90,16 +90,17 @@ features in the apps which use them.
|
||||
* Remote: Install the SQLite source tree. CD to ext/wasm
|
||||
* Remote: "`make`" to build WASM
|
||||
* Remote: `althttpd --enable-sab --port 8080 --popup`
|
||||
* Local: `ssh -L 8180:localhost:8080 remote`
|
||||
* Local: `ssh -L 8180:remote:8080 remote`
|
||||
* Local: Point your web-browser at http://localhost:8180/index.html
|
||||
|
||||
In order to enable [SharedArrayBuffers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer),
|
||||
the web-browser requires that the two extra Cross-Origin lines be present
|
||||
in HTTP reply headers and that the request must come from "localhost".
|
||||
Since the web-server is on a different machine from
|
||||
the web-broser, the localhost requirement means that the connection must be tunneled
|
||||
using SSH.
|
||||
In order to enable [SharedArrayBuffer][], the web-browser requires
|
||||
that the two extra Cross-Origin lines be present in HTTP reply headers
|
||||
and that the request must come from "localhost" (_or_ over an SSL
|
||||
connection). Since the web-server is on a different machine from the
|
||||
web-broser, the localhost requirement means that the connection must
|
||||
be tunneled using SSH.
|
||||
|
||||
|
||||
[emscripten]: https://emscripten.org
|
||||
[althttpd]: https://sqlite.org/althttpd
|
||||
[SharedArrayBuffer]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
|
||||
|
@ -83,15 +83,18 @@ browser client:
|
||||
helpers for use by downstream code which creates `sqlite3_vfs`
|
||||
and `sqlite3_module` implementations.
|
||||
- **`sqlite3-vfs-opfs.c-pp.js`**\
|
||||
is an sqlite3 VFS implementation which supports Google Chrome's
|
||||
Origin-Private FileSystem (OPFS) as a storage layer to provide
|
||||
persistent storage for database files in a browser. It requires...
|
||||
is an sqlite3 VFS implementation which supports the Origin-Private
|
||||
FileSystem (OPFS) as a storage layer to provide persistent storage
|
||||
for database files in a browser. It requires...
|
||||
- **`sqlite3-opfs-async-proxy.js`**\
|
||||
is the asynchronous backend part of the OPFS proxy. It speaks
|
||||
directly to the (async) OPFS API and channels those results back
|
||||
to its synchronous counterpart. This file, because it must be
|
||||
started in its own Worker, is not part of the amalgamation.
|
||||
- **`api/sqlite3-api-cleanup.js`**\
|
||||
- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**\
|
||||
is another sqlite3 VFS supporting the OPFS, but uses a completely
|
||||
different approach that the above-listed one.
|
||||
- **`sqlite3-api-cleanup.js`**\
|
||||
The previous files do not immediately extend the library. Instead
|
||||
they add callback functions to be called during its
|
||||
bootstrapping. Some also temporarily create global objects in order
|
||||
@ -108,13 +111,15 @@ browser client:
|
||||
with `c-pp`](#c-pp), noting that such preprocessing may be applied
|
||||
after all of the relevant files are concatenated. That extension is
|
||||
used primarily to keep the code maintainers cognisant of the fact that
|
||||
those files contain constructs which will not run as-is in JavaScript.
|
||||
those files contain constructs which may not run as-is in any given
|
||||
JavaScript environment.
|
||||
|
||||
The build process glues those files together, resulting in
|
||||
`sqlite3-api.js`, which is everything except for the `post-js-*.js`
|
||||
files, and `sqlite3.js`, which is the Emscripten-generated amalgamated
|
||||
output and includes the `post-js-*.js` parts, as well as the
|
||||
Emscripten-provided module loading pieces.
|
||||
`sqlite3-api.js`, which is everything except for the
|
||||
`pre/post-js-*.js` files, and `sqlite3.js`, which is the
|
||||
Emscripten-generated amalgamated output and includes the
|
||||
`pre/post-js-*.js` parts, as well as the Emscripten-provided module
|
||||
loading pieces.
|
||||
|
||||
The non-JS outlier file is `sqlite3-wasm.c`: it is a proxy for
|
||||
`sqlite3.c` which `#include`'s that file and adds a couple more
|
||||
@ -152,8 +157,8 @@ Preprocessing of Source Files
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Certain files in the build require preprocessing to filter in/out
|
||||
parts which differ between vanilla JS builds and ES6 Module
|
||||
(a.k.a. esm) builds. The preprocessor application itself is in
|
||||
parts which differ between vanilla JS, ES6 Modules, and node.js
|
||||
builds. The preprocessor application itself is in
|
||||
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
|
||||
of such preprocessing are maintained in
|
||||
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
|
||||
|
@ -88,9 +88,9 @@
|
||||
can be replaced with (e.g.) empty functions to squelch all such
|
||||
output.
|
||||
|
||||
- `wasmfsOpfsDir`[^1]: As of 2022-12-17, this feature does not
|
||||
currently work due to incompatible Emscripten-side changes made
|
||||
in the WASMFS+OPFS combination. This option is currently ignored.
|
||||
- `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the OPFS-backed
|
||||
filesystem in WASMFS-capable builds.
|
||||
|
||||
|
||||
[^1] = This property may optionally be a function, in which case
|
||||
this function calls that function to fetch the value,
|
||||
@ -125,11 +125,11 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
log: console.log.bind(console),
|
||||
wasmfsOpfsDir: '/opfs',
|
||||
/**
|
||||
useStdAlloc is just for testing an allocator discrepancy. The
|
||||
useStdAlloc is just for testing allocator discrepancies. The
|
||||
docs guarantee that this is false in the canonical builds. For
|
||||
99% of purposes it doesn't matter which allocators we use, but
|
||||
it becomes significant with, e.g., sqlite3_deserialize()
|
||||
and certain wasm.xWrap.resultAdapter()s.
|
||||
it becomes significant with, e.g., sqlite3_deserialize() and
|
||||
certain wasm.xWrap.resultAdapter()s.
|
||||
*/
|
||||
useStdAlloc: false
|
||||
}, apiConfig || {});
|
||||
@ -1861,6 +1861,9 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
client: undefined,
|
||||
|
||||
/**
|
||||
This function is not part of the public interface, but a
|
||||
piece of internal bootstrapping infrastructure.
|
||||
|
||||
Performs any optional asynchronous library-level initialization
|
||||
which might be required. This function returns a Promise which
|
||||
resolves to the sqlite3 namespace object. Any error in the
|
||||
@ -1876,27 +1879,19 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
then it must be called by client-level code, which must not use
|
||||
the library until the returned promise resolves.
|
||||
|
||||
Bug: if called while a prior call is still resolving, the 2nd
|
||||
call will resolve prematurely, before the 1st call has finished
|
||||
resolving. The current build setup precludes that possibility,
|
||||
so it's only a hypothetical problem if/when this function
|
||||
ever needs to be invoked by clients.
|
||||
If called multiple times it will return the same promise on
|
||||
subsequent calls. The current build setup precludes that
|
||||
possibility, so it's only a hypothetical problem if/when this
|
||||
function ever needs to be invoked by clients.
|
||||
|
||||
In Emscripten-based builds, this function is called
|
||||
automatically and deleted from this object.
|
||||
*/
|
||||
asyncPostInit: async function(){
|
||||
let lip = sqlite3ApiBootstrap.initializersAsync;
|
||||
asyncPostInit: async function ff(){
|
||||
if(ff.isReady instanceof Promise) return ff.isReady;
|
||||
let lia = sqlite3ApiBootstrap.initializersAsync;
|
||||
delete sqlite3ApiBootstrap.initializersAsync;
|
||||
if(!lip || !lip.length) return Promise.resolve(sqlite3);
|
||||
lip = lip.map((f)=>{
|
||||
const p = (f instanceof Promise) ? f : f(sqlite3);
|
||||
return p.catch((e)=>{
|
||||
console.error("an async sqlite3 initializer failed:",e);
|
||||
throw e;
|
||||
});
|
||||
});
|
||||
const postInit = ()=>{
|
||||
const postInit = async ()=>{
|
||||
if(!sqlite3.__isUnderTest){
|
||||
/* Delete references to internal-only APIs which are used by
|
||||
some initializers. Retain them when running in test mode
|
||||
@ -1905,23 +1900,25 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
||||
/* It's conceivable that we might want to expose
|
||||
StructBinder to client-side code, but it's only useful if
|
||||
clients build their own sqlite3.wasm which contains their
|
||||
one C struct types. */
|
||||
own C struct types. */
|
||||
delete sqlite3.StructBinder;
|
||||
}
|
||||
return sqlite3;
|
||||
};
|
||||
if(1){
|
||||
/* Run all initializers in sequence. The advantage is that it
|
||||
allows us to have post-init cleanup defined outside of this
|
||||
routine at the end of the list and have it run at a
|
||||
well-defined time. */
|
||||
let p = lip.shift();
|
||||
while(lip.length) p = p.then(lip.shift());
|
||||
return p.then(postInit);
|
||||
}else{
|
||||
/* Run them in an arbitrary order. */
|
||||
return Promise.all(lip).then(postInit);
|
||||
const catcher = (e)=>{
|
||||
config.error("an async sqlite3 initializer failed:",e);
|
||||
throw e;
|
||||
};
|
||||
if(!lia || !lia.length){
|
||||
return ff.isReady = postInit().catch(catcher);
|
||||
}
|
||||
lia = lia.map((f)=>{
|
||||
return (f instanceof Function) ? async x=>f(sqlite3) : f;
|
||||
});
|
||||
lia.push(postInit);
|
||||
let p = Promise.resolve(sqlite3);
|
||||
while(lia.length) p = p.then(lia.shift());
|
||||
return ff.isReady = p.catch(catcher);
|
||||
},
|
||||
/**
|
||||
scriptInfo ideally gets injected into this object by the
|
||||
@ -1981,7 +1978,7 @@ globalThis.sqlite3ApiBootstrap.initializers = [];
|
||||
specifically for initializers which are asynchronous. All entries in
|
||||
this list must be either async functions, non-async functions which
|
||||
return a Promise, or a Promise. Each function in the list is called
|
||||
with the sqlite3 ojbect as its only argument.
|
||||
with the sqlite3 object as its only argument.
|
||||
|
||||
The resolved value of any Promise is ignored and rejection will kill
|
||||
the asyncPostInit() process (at an indeterminate point because all
|
||||
|
@ -35,6 +35,9 @@
|
||||
|
||||
https://developer.chrome.com/blog/sync-methods-for-accesshandles/
|
||||
|
||||
Firefox v111 and Safari 16.4, both released in March 2023, also
|
||||
include this.
|
||||
|
||||
We cannot change to the sync forms at this point without breaking
|
||||
clients who use Chrome v104-ish or higher. truncate(), getSize(),
|
||||
flush(), and close() are now (as of v108) synchronous. Calling them
|
||||
|
@ -100,7 +100,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
ACHTUNG: because we cannot generically know how to transform JS
|
||||
exceptions into result codes, the installed functions do no
|
||||
automatic catching of exceptions. It is critical, to avoid
|
||||
automatic catching of exceptions. It is critical, to avoid
|
||||
undefined behavior in the C layer, that methods mapped via
|
||||
this function do not throw. The exception, as it were, to that
|
||||
rule is...
|
||||
@ -295,7 +295,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
|
||||
- If `struct.$zName` is falsy and the entry has a string-type
|
||||
`name` property, `struct.$zName` is set to the C-string form of
|
||||
that `name` value before registerVfs() is called.
|
||||
that `name` value before registerVfs() is called. That string
|
||||
gets added to the on-dispose state of the struct.
|
||||
|
||||
On success returns this object. Throws on error.
|
||||
*/
|
||||
@ -608,7 +609,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
This is to facilitate creation of those methods inline in the
|
||||
passed-in object without requiring the client to explicitly get a
|
||||
reference to one of them in order to assign it to the other
|
||||
one.
|
||||
one.
|
||||
|
||||
The `catchExceptions`-installed handlers will account for
|
||||
identical references to the above functions and will install the
|
||||
|
1199
ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js
Normal file
1199
ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,4 @@
|
||||
//#ifnot target=node
|
||||
/*
|
||||
2022-09-18
|
||||
|
||||
@ -23,7 +24,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
||||
installOpfsVfs() returns a Promise which, on success, installs an
|
||||
sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
|
||||
which accept a VFS. It is intended to be called via
|
||||
sqlite3ApiBootstrap.initializersAsync or an equivalent mechanism.
|
||||
sqlite3ApiBootstrap.initializers or an equivalent mechanism.
|
||||
|
||||
The installed VFS uses the Origin-Private FileSystem API for
|
||||
all file storage. On error it is rejected with an exception
|
||||
@ -101,6 +102,10 @@ const installOpfsVfs = function callee(options){
|
||||
options = Object.create(null);
|
||||
}
|
||||
const urlParams = new URL(globalThis.location.href).searchParams;
|
||||
if(urlParams.has('opfs-disable')){
|
||||
//sqlite3.config.warn('Explicitly not installing "opfs" VFS due to opfs-disable flag.');
|
||||
return Promise.resolve(sqlite3);
|
||||
}
|
||||
if(undefined===options.verbose){
|
||||
options.verbose = urlParams.has('opfs-verbose')
|
||||
? (+urlParams.get('opfs-verbose') || 2) : 1;
|
||||
@ -200,9 +205,9 @@ const installOpfsVfs = function callee(options){
|
||||
opfsVfs.dispose();
|
||||
return promiseReject_(err);
|
||||
};
|
||||
const promiseResolve = (value)=>{
|
||||
const promiseResolve = ()=>{
|
||||
promiseWasRejected = false;
|
||||
return promiseResolve_(value);
|
||||
return promiseResolve_(sqlite3);
|
||||
};
|
||||
const W =
|
||||
//#if target=es6-bundler-friendly
|
||||
@ -236,6 +241,7 @@ const installOpfsVfs = function callee(options){
|
||||
? new sqlite3_vfs(pDVfs)
|
||||
: null /* dVfs will be null when sqlite3 is built with
|
||||
SQLITE_OS_OTHER. */;
|
||||
opfsIoMethods.$iVersion = 1;
|
||||
opfsVfs.$iVersion = 2/*yes, two*/;
|
||||
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
||||
opfsVfs.$mxPathname = 1024/*sure, why not?*/;
|
||||
@ -1321,10 +1327,10 @@ const installOpfsVfs = function callee(options){
|
||||
sqlite3.opfs = opfsUtil;
|
||||
opfsUtil.rootDirectory = d;
|
||||
log("End of OPFS sqlite3_vfs setup.", opfsVfs);
|
||||
promiseResolve(sqlite3);
|
||||
promiseResolve();
|
||||
}).catch(promiseReject);
|
||||
}else{
|
||||
promiseResolve(sqlite3);
|
||||
promiseResolve();
|
||||
}
|
||||
}catch(e){
|
||||
error(e);
|
||||
@ -1361,7 +1367,10 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
|
||||
});
|
||||
}catch(e){
|
||||
sqlite3.config.error("installOpfsVfs() exception:",e);
|
||||
throw e;
|
||||
return Promise.reject(e);
|
||||
}
|
||||
});
|
||||
}/*sqlite3ApiBootstrap.initializers.push()*/);
|
||||
//#else
|
||||
/* The OPFS VFS parts are elided from builds targeting node.js. */
|
||||
//#endif target=node
|
||||
|
@ -151,7 +151,7 @@
|
||||
/**********************************************************************/
|
||||
/* SQLITE_T... */
|
||||
#ifndef SQLITE_TEMP_STORE
|
||||
# define SQLITE_TEMP_STORE 3
|
||||
# define SQLITE_TEMP_STORE 2
|
||||
#endif
|
||||
#ifndef SQLITE_THREADSAFE
|
||||
# define SQLITE_THREADSAFE 0
|
||||
|
@ -40,8 +40,41 @@ span.labeled-input {
|
||||
.tests-pass { background-color: green; color: white }
|
||||
.tests-fail { background-color: red; color: yellow }
|
||||
.faded { opacity: 0.5; }
|
||||
.group-start { color: blue; }
|
||||
.group-end { color: blue; }
|
||||
.group-start {
|
||||
color: blue;
|
||||
background-color: skyblue;
|
||||
font-weight: bold;
|
||||
border-top: 1px dotted blue;
|
||||
padding: 0.5em;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
.group-end {
|
||||
padding: 0.5em;
|
||||
margin-bottom: 0.25em;
|
||||
/*border-bottom: 1px dotted blue;*/
|
||||
}
|
||||
.group-end.green {
|
||||
background: lightgreen;
|
||||
border-bottom: 1px dotted green;
|
||||
}
|
||||
.one-test-line, .skipping-group {
|
||||
margin-left: 3em;
|
||||
}
|
||||
.skipping-test, .skipping-group {
|
||||
padding: 0.25em 0.5em;
|
||||
background-color: #ffff73;
|
||||
}
|
||||
.skipping-test {
|
||||
margin-left: 6em;
|
||||
}
|
||||
.one-test-summary {
|
||||
margin-left: 6em;
|
||||
}
|
||||
.full-test-summary {
|
||||
padding-bottom: 0.5em;
|
||||
padding-top: 0.5em;
|
||||
border-top: 1px solid black;
|
||||
}
|
||||
.input-wrapper {
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
|
@ -38,7 +38,7 @@ dist-name := $(dist-name-prefix)-TEMP
|
||||
# date. Our general policy is that we want the smallest binaries for
|
||||
# dist zip files, so use the oz build unless there is a compelling
|
||||
# reason not to.
|
||||
dist.build ?= qoz
|
||||
dist.build ?= oz
|
||||
|
||||
dist-dir.top := $(dist-name)
|
||||
dist-dir.jswasm := $(dist-dir.top)/$(notdir $(dir.dout))
|
||||
|
@ -96,6 +96,10 @@
|
||||
<li><a href='speedtest1-worker.html?size=15'>speedtest1-worker</a>: an interactive Worker-thread variant of speedtest1.</li>
|
||||
<li><a href='speedtest1-worker.html?vfs=opfs&size=10'>speedtest1-worker?vfs=opfs</a>: speedtest1-worker with the
|
||||
OPFS VFS preselected and configured for a moderate workload.</li>
|
||||
<li><a href='speedtest1-worker.html?vfs=opfs-sahpool&size=10'>speedtest1-worker?vfs=opfs-sahpool</a>:
|
||||
speedtest1-worker with the OPFS-SAHPOOL VFS preselected
|
||||
and configured for a moderate workload.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>The obligatory "misc." category...
|
||||
|
@ -171,7 +171,8 @@
|
||||
const urlParams = new URL(self.location.href).searchParams;
|
||||
const W = new Worker(
|
||||
"speedtest1-worker.js?sqlite3.dir=jswasm"+
|
||||
(urlParams.has('opfs-verbose') ? '&opfs-verbose' : '')
|
||||
(urlParams.has('opfs-verbose') ? '&opfs-verbose' : '')+
|
||||
(urlParams.has('opfs-disable') ? '&opfs-disable' : '')
|
||||
);
|
||||
const mPost = function(msgType,payload){
|
||||
W.postMessage({type: msgType, data: payload});
|
||||
@ -267,7 +268,7 @@
|
||||
if(urlParams.has('flags')){
|
||||
preselectedFlags.push(...urlParams.get('flags').split(','));
|
||||
}
|
||||
if('opfs'!==urlParams.get('vfs')){
|
||||
if(!urlParams.get('vfs')){
|
||||
preselectedFlags.push('--memdb');
|
||||
}
|
||||
Object.keys(flags).sort().forEach(function(f){
|
||||
|
@ -5,7 +5,7 @@
|
||||
if(urlParams.has('sqlite3.dir')){
|
||||
speedtestJs = urlParams.get('sqlite3.dir') + '/' + speedtestJs;
|
||||
}
|
||||
importScripts('common/whwasmutil.js', speedtestJs);
|
||||
importScripts(speedtestJs);
|
||||
/**
|
||||
If this environment contains OPFS, this function initializes it and
|
||||
returns the name of the dir on which OPFS is mounted, else it returns
|
||||
@ -48,7 +48,7 @@
|
||||
const log = (...args)=>logMsg('stdout',args);
|
||||
const logErr = (...args)=>logMsg('stderr',args);
|
||||
|
||||
const runSpeedtest = function(cliFlagsArray){
|
||||
const runSpeedtest = async function(cliFlagsArray){
|
||||
const scope = App.wasm.scopedAllocPush();
|
||||
const dbFile = App.pDir+"/speedtest1.sqlite3";
|
||||
try{
|
||||
@ -56,7 +56,28 @@
|
||||
"speedtest1.wasm", ...cliFlagsArray, dbFile
|
||||
];
|
||||
App.logBuffer.length = 0;
|
||||
const ndxSahPool = argv.indexOf('opfs-sahpool');
|
||||
const realSahName = 'opfs-sahpool-speedtest1';
|
||||
if(ndxSahPool>0){
|
||||
argv[ndxSahPool] = realSahName;
|
||||
log("Updated argv for opfs-sahpool: --vfs",realSahName);
|
||||
}
|
||||
mPost('run-start', [...argv]);
|
||||
if(App.sqlite3.installOpfsSAHPoolVfs
|
||||
&& !App.sqlite3.$SAHPoolUtil
|
||||
&& ndxSahPool>0){
|
||||
log("Installing opfs-sahpool as",realSahName,"...");
|
||||
await App.sqlite3.installOpfsSAHPoolVfs({
|
||||
name: realSahName,
|
||||
initialCapacity: 3,
|
||||
clearOnInit: true,
|
||||
verbosity: 2
|
||||
}).then(PoolUtil=>{
|
||||
log("opfs-sahpool successfully installed as",realSahName);
|
||||
App.sqlite3.$SAHPoolUtil = PoolUtil;
|
||||
//console.log("sqlite3.oo1.OpfsSAHPoolDb =", App.sqlite3.oo1.OpfsSAHPoolDb);
|
||||
});
|
||||
}
|
||||
App.wasm.xCall('wasm_main', argv.length,
|
||||
App.wasm.scopedAllocMainArgv(argv));
|
||||
}catch(e){
|
||||
@ -71,20 +92,38 @@
|
||||
self.onmessage = function(msg){
|
||||
msg = msg.data;
|
||||
switch(msg.type){
|
||||
case 'run': runSpeedtest(msg.data || []); break;
|
||||
case 'run':
|
||||
runSpeedtest(msg.data || [])
|
||||
.catch(e=>mPost('error',e));
|
||||
break;
|
||||
default:
|
||||
logErr("Unhandled worker message type:",msg.type);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const sahpSanityChecks = function(sqlite3){
|
||||
log("Attempting OpfsSAHPoolDb sanity checks...");
|
||||
const db = new sqlite3.oo1.OpfsSAHPoolDb('opfs-sahpoool.db');
|
||||
const fn = db.filename;
|
||||
db.exec([
|
||||
'create table t(a);',
|
||||
'insert into t(a) values(1),(2),(3);'
|
||||
]);
|
||||
db.close();
|
||||
sqlite3.wasm.sqlite3_wasm_vfs_unlink(sqlite3_vfs_find("opfs-sahpool"), fn);
|
||||
log("SAH sanity checks done.");
|
||||
};
|
||||
|
||||
const EmscriptenModule = {
|
||||
print: log,
|
||||
printErr: logErr,
|
||||
setStatus: (text)=>mPost('load-status',text)
|
||||
};
|
||||
self.sqlite3InitModule(EmscriptenModule).then((sqlite3)=>{
|
||||
const S = sqlite3;
|
||||
log("Initializing speedtest1 module...");
|
||||
self.sqlite3InitModule(EmscriptenModule).then(async (sqlite3)=>{
|
||||
const S = globalThis.S = App.sqlite3 = sqlite3;
|
||||
log("Loaded speedtest1 module. Setting up...");
|
||||
App.vfsUnlink = function(pDb, fname){
|
||||
const pVfs = S.wasm.sqlite3_wasm_db_vfs(pDb, 0);
|
||||
if(pVfs) S.wasm.sqlite3_wasm_vfs_unlink(pVfs, fname||0);
|
||||
@ -95,5 +134,7 @@
|
||||
//else log("Using transient storage.");
|
||||
mPost('ready',true);
|
||||
log("Registered VFSes:", ...S.capi.sqlite3_js_vfs_list());
|
||||
}).catch(e=>{
|
||||
logErr(e);
|
||||
});
|
||||
})();
|
||||
|
@ -65,6 +65,14 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
const haveWasmCTests = ()=>{
|
||||
return !!wasm.exports.sqlite3_wasm_test_intptr;
|
||||
};
|
||||
const hasOpfs = ()=>{
|
||||
return globalThis.FileSystemHandle
|
||||
&& globalThis.FileSystemDirectoryHandle
|
||||
&& globalThis.FileSystemFileHandle
|
||||
&& globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle
|
||||
&& navigator?.storage?.getDirectory;
|
||||
};
|
||||
|
||||
{
|
||||
const mapToString = (v)=>{
|
||||
switch(typeof v){
|
||||
@ -159,8 +167,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
/** Running total of the number of tests run via
|
||||
this API. */
|
||||
counter: 0,
|
||||
/* Separator line for log messages. */
|
||||
separator: '------------------------------------------------------------',
|
||||
/**
|
||||
If expr is a function, it is called and its result
|
||||
is returned, coerced to a bool, else expr, coerced to
|
||||
@ -248,13 +254,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
return this;
|
||||
},
|
||||
run: async function(sqlite3){
|
||||
log(TestUtil.separator);
|
||||
logClass('group-start',"Group #"+this.number+':',this.name);
|
||||
const indent = ' ';
|
||||
if(this.predicate){
|
||||
const p = this.predicate(sqlite3);
|
||||
if(!p || 'string'===typeof p){
|
||||
logClass('warning',indent,
|
||||
logClass(['warning','skipping-group'],
|
||||
"SKIPPING group:", p ? p : "predicate says to" );
|
||||
return;
|
||||
}
|
||||
@ -266,26 +270,34 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
for(const t of this.tests){
|
||||
++i;
|
||||
const n = this.number+"."+i;
|
||||
log(indent, n+":", t.name);
|
||||
logClass('one-test-line', n+":", t.name);
|
||||
if(t.predicate){
|
||||
const p = t.predicate(sqlite3);
|
||||
if(!p || 'string'===typeof p){
|
||||
logClass('warning',indent,
|
||||
logClass(['warning','skipping-test'],
|
||||
"SKIPPING:", p ? p : "predicate says to" );
|
||||
skipped.push( n+': '+t.name );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
const tc = TestUtil.counter, now = performance.now();
|
||||
await t.test.call(groupState, sqlite3);
|
||||
let rc = t.test.call(groupState, sqlite3);
|
||||
/*if(rc instanceof Promise){
|
||||
rc = rc.catch((e)=>{
|
||||
error("Test failure:",e);
|
||||
throw e;
|
||||
});
|
||||
}*/
|
||||
await rc;
|
||||
const then = performance.now();
|
||||
runtime += then - now;
|
||||
logClass('faded',indent, indent,
|
||||
logClass(['faded','one-test-summary'],
|
||||
TestUtil.counter - tc, 'assertion(s) in',
|
||||
roundMs(then-now),'ms');
|
||||
}
|
||||
logClass('green',
|
||||
"Group #"+this.number+":",(TestUtil.counter - assertCount),
|
||||
logClass(['green','group-end'],
|
||||
"#"+this.number+":",
|
||||
(TestUtil.counter - assertCount),
|
||||
"assertion(s) in",roundMs(runtime),"ms");
|
||||
if(0 && skipped.length){
|
||||
logClass('warning',"SKIPPED test(s) in group",this.number+":",skipped);
|
||||
@ -321,8 +333,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
await g.run(sqlite3);
|
||||
runtime += performance.now() - now;
|
||||
}
|
||||
log(TestUtil.separator);
|
||||
logClass(['strong','green'],
|
||||
logClass(['strong','green','full-test-summary'],
|
||||
"Done running tests.",TestUtil.counter,"assertions in",
|
||||
roundMs(runtime),'ms');
|
||||
pok();
|
||||
@ -339,6 +350,11 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
T.g = T.addGroup;
|
||||
T.t = T.addTest;
|
||||
let capi, wasm/*assigned after module init*/;
|
||||
const sahPoolConfig = {
|
||||
name: 'opfs-sahpool-tester1',
|
||||
clearOnInit: true,
|
||||
initialCapacity: 3
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// End of infrastructure setup. Now define the tests...
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
@ -1288,7 +1304,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
if(1){
|
||||
const vfsList = capi.sqlite3_js_vfs_list();
|
||||
T.assert(vfsList.length>1);
|
||||
//log("vfsList =",vfsList);
|
||||
wasm.scopedAllocCall(()=>{
|
||||
const vfsArg = (v)=>wasm.xWrap.testConvertArg('sqlite3_vfs*',v);
|
||||
for(const v of vfsList){
|
||||
@ -2615,128 +2630,6 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
}/*kvvfs sqlite3_js_vfs_create_file()*/)
|
||||
;/* end kvvfs tests */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
T.g('OPFS: Origin-Private File System',
|
||||
(sqlite3)=>(sqlite3.opfs
|
||||
? true : "requires Worker thread in a compatible browser"))
|
||||
.t({
|
||||
name: 'OPFS db sanity checks',
|
||||
test: async function(sqlite3){
|
||||
const filename = this.opfsDbFile = 'sqlite3-tester1.db';
|
||||
const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
|
||||
T.assert(pVfs);
|
||||
const unlink = this.opfsUnlink =
|
||||
(fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)};
|
||||
unlink();
|
||||
let db = new sqlite3.oo1.OpfsDb(filename);
|
||||
try {
|
||||
db.exec([
|
||||
'create table p(a);',
|
||||
'insert into p(a) values(1),(2),(3)'
|
||||
]);
|
||||
T.assert(3 === db.selectValue('select count(*) from p'));
|
||||
db.close();
|
||||
db = new sqlite3.oo1.OpfsDb(filename);
|
||||
db.exec('insert into p(a) values(4),(5),(6)');
|
||||
T.assert(6 === db.selectValue('select count(*) from p'));
|
||||
this.opfsDbExport = capi.sqlite3_js_db_export(db);
|
||||
T.assert(this.opfsDbExport instanceof Uint8Array)
|
||||
.assert(this.opfsDbExport.byteLength>0
|
||||
&& 0===this.opfsDbExport.byteLength % 512);
|
||||
}finally{
|
||||
db.close();
|
||||
unlink();
|
||||
}
|
||||
}
|
||||
}/*OPFS db sanity checks*/)
|
||||
.t({
|
||||
name: 'OPFS export/import',
|
||||
test: async function(sqlite3){
|
||||
let db;
|
||||
try {
|
||||
const exp = this.opfsDbExport;
|
||||
delete this.opfsDbExport;
|
||||
capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp);
|
||||
const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
|
||||
T.assert(6 === db.selectValue('select count(*) from p'));
|
||||
}finally{
|
||||
if(db) db.close();
|
||||
}
|
||||
}
|
||||
}/*OPFS export/import*/)
|
||||
.t({
|
||||
name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()',
|
||||
test: async function(sqlite3){
|
||||
const filename = this.opfsDbFile;
|
||||
const pVfs = this.opfsVfs;
|
||||
const unlink = this.opfsUnlink;
|
||||
T.assert(filename && pVfs && !!unlink);
|
||||
delete this.opfsDbFile;
|
||||
delete this.opfsVfs;
|
||||
delete this.opfsUnlink;
|
||||
unlink();
|
||||
// Sanity-test sqlite3_js_vfs_create_file()...
|
||||
/**************************************************************
|
||||
ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended
|
||||
for client-side use. It is only for this project's own
|
||||
internal use. Its APIs are subject to change or removal at
|
||||
any time.
|
||||
***************************************************************/
|
||||
const opfs = sqlite3.opfs;
|
||||
const fSize = 1379;
|
||||
let sh;
|
||||
try{
|
||||
T.assert(!(await opfs.entryExists(filename)));
|
||||
capi.sqlite3_js_vfs_create_file(
|
||||
pVfs, filename, null, fSize
|
||||
);
|
||||
T.assert(await opfs.entryExists(filename));
|
||||
let fh = await opfs.rootDirectory.getFileHandle(filename);
|
||||
sh = await fh.createSyncAccessHandle();
|
||||
T.assert(fSize === await sh.getSize());
|
||||
await sh.close();
|
||||
sh = undefined;
|
||||
unlink();
|
||||
T.assert(!(await opfs.entryExists(filename)));
|
||||
|
||||
const ba = new Uint8Array([1,2,3,4,5]);
|
||||
capi.sqlite3_js_vfs_create_file(
|
||||
"opfs", filename, ba
|
||||
);
|
||||
T.assert(await opfs.entryExists(filename));
|
||||
fh = await opfs.rootDirectory.getFileHandle(filename);
|
||||
sh = await fh.createSyncAccessHandle();
|
||||
T.assert(ba.byteLength === await sh.getSize());
|
||||
await sh.close();
|
||||
sh = undefined;
|
||||
unlink();
|
||||
|
||||
T.mustThrowMatching(()=>{
|
||||
capi.sqlite3_js_vfs_create_file(
|
||||
"no-such-vfs", filename, ba
|
||||
);
|
||||
}, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs");
|
||||
}finally{
|
||||
if(sh) await sh.close();
|
||||
unlink();
|
||||
}
|
||||
|
||||
// Some sanity checks of the opfs utility functions...
|
||||
const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
|
||||
const aDir = testDir+'/test/dir';
|
||||
T.assert(await opfs.mkdir(aDir), "mkdir failed")
|
||||
.assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists")
|
||||
.assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)")
|
||||
.assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed")
|
||||
.assert(!(await opfs.unlink(testDir+'/test/dir')),
|
||||
"delete 2b should have failed (dir already deleted)")
|
||||
.assert((await opfs.unlink(testDir, true)), "delete 3 failed")
|
||||
.assert(!(await opfs.entryExists(testDir)),
|
||||
"entryExists(",testDir,") should have failed");
|
||||
}
|
||||
}/*OPFS util sanity checks*/)
|
||||
;/* end OPFS tests */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
T.g('Hook APIs')
|
||||
.t({
|
||||
@ -2942,8 +2835,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
.assert( capi.sqlite3session_enable(pSession, -1) > 0 )
|
||||
.assert(undefined === db1.selectValue('select a from t where rowid=2'));
|
||||
}else{
|
||||
warn("sqlite3session_enable() tests disabled due to unexpected results.",
|
||||
"(Possibly a tester misunderstanding, as opposed to a bug.)");
|
||||
warn("sqlite3session_enable() tests are currently disabled.");
|
||||
}
|
||||
let db1Count = db1.selectValue("select count(*) from t");
|
||||
T.assert( db1Count === (testSessionEnable ? 2 : 3) );
|
||||
@ -3007,6 +2899,205 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
}
|
||||
})/*session API sanity tests*/
|
||||
;/*end of session API group*/;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
T.g('OPFS: Origin-Private File System',
|
||||
(sqlite3)=>(sqlite3.capi.sqlite3_vfs_find("opfs")
|
||||
|| 'requires "opfs" VFS'))
|
||||
.t({
|
||||
name: 'OPFS db sanity checks',
|
||||
test: async function(sqlite3){
|
||||
const filename = this.opfsDbFile = 'sqlite3-tester1.db';
|
||||
const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs');
|
||||
T.assert(pVfs);
|
||||
const unlink = this.opfsUnlink =
|
||||
(fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)};
|
||||
unlink();
|
||||
let db = new sqlite3.oo1.OpfsDb(filename);
|
||||
try {
|
||||
db.exec([
|
||||
'create table p(a);',
|
||||
'insert into p(a) values(1),(2),(3)'
|
||||
]);
|
||||
T.assert(3 === db.selectValue('select count(*) from p'));
|
||||
db.close();
|
||||
db = new sqlite3.oo1.OpfsDb(filename);
|
||||
db.exec('insert into p(a) values(4),(5),(6)');
|
||||
T.assert(6 === db.selectValue('select count(*) from p'));
|
||||
this.opfsDbExport = capi.sqlite3_js_db_export(db);
|
||||
T.assert(this.opfsDbExport instanceof Uint8Array)
|
||||
.assert(this.opfsDbExport.byteLength>0
|
||||
&& 0===this.opfsDbExport.byteLength % 512);
|
||||
}finally{
|
||||
db.close();
|
||||
unlink();
|
||||
}
|
||||
}
|
||||
}/*OPFS db sanity checks*/)
|
||||
.t({
|
||||
name: 'OPFS export/import',
|
||||
test: async function(sqlite3){
|
||||
let db;
|
||||
try {
|
||||
const exp = this.opfsDbExport;
|
||||
delete this.opfsDbExport;
|
||||
capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp);
|
||||
const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile);
|
||||
T.assert(6 === db.selectValue('select count(*) from p'));
|
||||
}finally{
|
||||
if(db) db.close();
|
||||
}
|
||||
}
|
||||
}/*OPFS export/import*/)
|
||||
.t({
|
||||
name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()',
|
||||
test: async function(sqlite3){
|
||||
const filename = this.opfsDbFile;
|
||||
const pVfs = this.opfsVfs;
|
||||
const unlink = this.opfsUnlink;
|
||||
T.assert(filename && pVfs && !!unlink);
|
||||
delete this.opfsDbFile;
|
||||
delete this.opfsVfs;
|
||||
delete this.opfsUnlink;
|
||||
unlink();
|
||||
// Sanity-test sqlite3_js_vfs_create_file()...
|
||||
/**************************************************************
|
||||
ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended
|
||||
for client-side use. It is only for this project's own
|
||||
internal use. Its APIs are subject to change or removal at
|
||||
any time.
|
||||
***************************************************************/
|
||||
const opfs = sqlite3.opfs;
|
||||
const fSize = 1379;
|
||||
let sh;
|
||||
try{
|
||||
T.assert(!(await opfs.entryExists(filename)));
|
||||
capi.sqlite3_js_vfs_create_file(
|
||||
pVfs, filename, null, fSize
|
||||
);
|
||||
T.assert(await opfs.entryExists(filename));
|
||||
let fh = await opfs.rootDirectory.getFileHandle(filename);
|
||||
sh = await fh.createSyncAccessHandle();
|
||||
T.assert(fSize === await sh.getSize());
|
||||
await sh.close();
|
||||
sh = undefined;
|
||||
unlink();
|
||||
T.assert(!(await opfs.entryExists(filename)));
|
||||
|
||||
const ba = new Uint8Array([1,2,3,4,5]);
|
||||
capi.sqlite3_js_vfs_create_file(
|
||||
"opfs", filename, ba
|
||||
);
|
||||
T.assert(await opfs.entryExists(filename));
|
||||
fh = await opfs.rootDirectory.getFileHandle(filename);
|
||||
sh = await fh.createSyncAccessHandle();
|
||||
T.assert(ba.byteLength === await sh.getSize());
|
||||
await sh.close();
|
||||
sh = undefined;
|
||||
unlink();
|
||||
|
||||
T.mustThrowMatching(()=>{
|
||||
capi.sqlite3_js_vfs_create_file(
|
||||
"no-such-vfs", filename, ba
|
||||
);
|
||||
}, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs");
|
||||
}finally{
|
||||
if(sh) await sh.close();
|
||||
unlink();
|
||||
}
|
||||
|
||||
// Some sanity checks of the opfs utility functions...
|
||||
const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12);
|
||||
const aDir = testDir+'/test/dir';
|
||||
T.assert(await opfs.mkdir(aDir), "mkdir failed")
|
||||
.assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists")
|
||||
.assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)")
|
||||
.assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed")
|
||||
.assert(!(await opfs.unlink(testDir+'/test/dir')),
|
||||
"delete 2b should have failed (dir already deleted)")
|
||||
.assert((await opfs.unlink(testDir, true)), "delete 3 failed")
|
||||
.assert(!(await opfs.entryExists(testDir)),
|
||||
"entryExists(",testDir,") should have failed");
|
||||
}
|
||||
}/*OPFS util sanity checks*/)
|
||||
;/* end OPFS tests */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
T.g('OPFS SyncAccessHandle Pool VFS',
|
||||
(sqlite3)=>(hasOpfs() || "requires OPFS APIs"))
|
||||
.t({
|
||||
name: 'SAH sanity checks',
|
||||
test: async function(sqlite3){
|
||||
T.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
|
||||
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) < 0)
|
||||
const inst = sqlite3.installOpfsSAHPoolVfs,
|
||||
catcher = (e)=>{
|
||||
error("Cannot load SAH pool VFS.",
|
||||
"This might not be a problem,",
|
||||
"depending on the environment.");
|
||||
return false;
|
||||
};
|
||||
let u1, u2;
|
||||
// Ensure that two immediately-consecutive installations
|
||||
// resolve to the same Promise instead of triggering
|
||||
// a locking error.
|
||||
const P1 = inst(sahPoolConfig).then(u=>u1 = u).catch(catcher),
|
||||
P2 = inst(sahPoolConfig).then(u=>u2 = u).catch(catcher);
|
||||
await Promise.all([P1, P2]);
|
||||
if(!(await P1)) return;
|
||||
T.assert(u1 === u2)
|
||||
.assert(sahPoolConfig.name === u1.vfsName)
|
||||
.assert(sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name))
|
||||
.assert(u1.getCapacity() >= sahPoolConfig.initialCapacity
|
||||
/* If a test fails before we get to nuke the VFS, we
|
||||
can have more than the initial capacity on the next
|
||||
run. */)
|
||||
.assert(u1.getCapacity() + 2 === (await u2.addCapacity(2)))
|
||||
.assert(2 === (await u2.reduceCapacity(2)))
|
||||
.assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) >= 0);
|
||||
|
||||
T.assert(0 === u1.getFileCount());
|
||||
const dbName = '/foo.db';
|
||||
let db = new u1.OpfsSAHPoolDb(dbName);
|
||||
T.assert(db instanceof sqlite3.oo1.DB)
|
||||
.assert(1 === u1.getFileCount());
|
||||
db.exec([
|
||||
'create table t(a);',
|
||||
'insert into t(a) values(1),(2),(3)'
|
||||
]);
|
||||
T.assert(1 === u1.getFileCount());
|
||||
T.assert(3 === db.selectValue('select count(*) from t'));
|
||||
db.close();
|
||||
T.assert(1 === u1.getFileCount());
|
||||
db = new u2.OpfsSAHPoolDb(dbName);
|
||||
T.assert(1 === u1.getFileCount());
|
||||
db.close();
|
||||
T.assert(1 === u1.getFileCount())
|
||||
.assert(true === u1.unlink(dbName))
|
||||
.assert(false === u1.unlink(dbName))
|
||||
.assert(0 === u1.getFileCount());
|
||||
if(0){
|
||||
/* Enable this block to inspect vfs's contents via the dev
|
||||
console or OPFS Explorer browser extension. The
|
||||
following bits will remove them. */
|
||||
return;
|
||||
}
|
||||
T.assert(true === await u2.removeVfs())
|
||||
.assert(false === await u1.removeVfs())
|
||||
.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name));
|
||||
|
||||
let cErr, u3;
|
||||
const conf2 = JSON.parse(JSON.stringify(sahPoolConfig));
|
||||
conf2.$testThrowInInit = new Error("Testing throwing during init.");
|
||||
conf2.name = sahPoolConfig.name+'-err';
|
||||
const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e);
|
||||
T.assert(P3 === conf2.$testThrowInInit)
|
||||
.assert(cErr === P3)
|
||||
.assert(undefined === u3)
|
||||
.assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name));
|
||||
}
|
||||
}/*OPFS SAH Pool sanity checks*/)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
T.g('Bug Reports')
|
||||
.t({
|
||||
@ -3088,11 +3179,15 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
globalThis.sqlite3InitModule({
|
||||
print: log,
|
||||
printErr: error
|
||||
}).then(function(sqlite3){
|
||||
//console.log('sqlite3 =',sqlite3);
|
||||
}).then(async function(sqlite3){
|
||||
log("Done initializing WASM/JS bits. Running tests...");
|
||||
sqlite3.config.warn("Installing sqlite3 bits as global S for local dev/test purposes.");
|
||||
globalThis.S = sqlite3;
|
||||
/*await sqlite3.installOpfsSAHPoolVfs(sahPoolConfig)
|
||||
.then((u)=>log("Loaded",u.vfsName,"VFS"))
|
||||
.catch(e=>{
|
||||
log("Cannot install OpfsSAHPool.",e);
|
||||
});*/
|
||||
capi = sqlite3.capi;
|
||||
wasm = sqlite3.wasm;
|
||||
log("sqlite3 version:",capi.sqlite3_libversion(),
|
||||
@ -3107,6 +3202,7 @@ globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||
}else{
|
||||
logClass('warning',"sqlite3_wasm_test_...() APIs unavailable.");
|
||||
}
|
||||
log("registered vfs list =",capi.sqlite3_js_vfs_list().join(', '));
|
||||
TestUtil.runTests(sqlite3);
|
||||
});
|
||||
})(self);
|
||||
|
57
manifest
57
manifest
@ -1,5 +1,5 @@
|
||||
C More\sinfrastructure\schanges\stowards\simproving\sJSON\scache\sperformance.\nIncremental\scheck-in.
|
||||
D 2023-07-21T11:09:53.138
|
||||
C Merge\sthe\slatest\strunk\senhancements\sinto\sthe\sjson-opt\sbranch.
|
||||
D 2023-07-24T12:37:23.834
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -482,13 +482,13 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||
F ext/wasm/GNUmakefile 74e351ff45b4061cfed8df237d301819a04182ae304a99118883b064baa25fc2
|
||||
F ext/wasm/GNUmakefile 4e8260d05c52d9924b853efbdfe052bd483cfe42f055567c1bbf29d274794b22
|
||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
||||
F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9
|
||||
F ext/wasm/README.md 0895244c0539ae68cf8c70d59c2de512532fd47cfba313268e2b672e6359112e
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab
|
||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||
F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54
|
||||
F ext/wasm/api/README.md 5eb44fa02e9c693a1884a3692428647894b0380b24bca120866b7a24c8786134
|
||||
F ext/wasm/api/extern-post-js.c-pp.js 116749b7e55b7519129de06d3d353e19df68cfb24b12204aa4dc30c9a83023fe
|
||||
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
||||
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
|
||||
@ -497,13 +497,14 @@ F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057af
|
||||
F ext/wasm/api/sqlite3-api-cleanup.js 23ceec5ef74a0e649b19694ca985fd89e335771e21f24f50df352a626a8c81bf
|
||||
F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803
|
||||
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
|
||||
F ext/wasm/api/sqlite3-api-prologue.js 7d1c1ef59b9dcc42ad3a9cec9da972c42e29316a270cd126e7f660509b09027b
|
||||
F ext/wasm/api/sqlite3-api-prologue.js cbd7d6ba185f3a844a8b0020e954b49bbc2ca78b305d117bec2ceca21431795a
|
||||
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
|
||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 961bbc3ccc1fa4e91d6519a96e8811ad7ae60173bd969fee7775dacb6eee1da2
|
||||
F ext/wasm/api/sqlite3-v-helper.js e5c202a9ecde9ef818536d3f5faf26c03a1a9f5192b1ddea8bdabf30d75ef487
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 891f3a18d9ac9b0422b32fd975319dfcd0af5a8ca392f0cce850524e51b49c87
|
||||
F ext/wasm/api/sqlite3-wasm.c 12a096d8e58a0af0589142bae5a3c27a0c7e19846755a1a37d2c206352fbedda
|
||||
F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
|
||||
F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
|
||||
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 7931b50b63246a3d6b46a4c703c28820aa10c5b1ae7c0718e1f58dae2cf6db85
|
||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e7a690e0e78ff4d563f2eca468f91db69f001ff4b79c6d2304cbb6f62dca437d
|
||||
F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f
|
||||
F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
|
||||
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
|
||||
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
||||
@ -511,7 +512,7 @@ F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c2
|
||||
F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4
|
||||
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
|
||||
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
|
||||
F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f
|
||||
F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f
|
||||
F ext/wasm/common/whwasmutil.js ae263dec9d7384f4c530f324b99d00516a4d6f26424372daee65031e00eb49b3
|
||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||
@ -522,7 +523,7 @@ F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98
|
||||
F ext/wasm/demo-worker1-promiser.js 5e5c7d7c91cd7aae9cc733afd02569ba9c6928292db413b550e8b842f4b75e87
|
||||
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
|
||||
F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef
|
||||
F ext/wasm/dist.make 451fb1b732257849f6e898d2a862512a0401500ed369ef53bdfeddf9c77bc3b9
|
||||
F ext/wasm/dist.make 3a851858aad72e246a5d9c5aaf6b6a144305f1bf898ac1846760ea7bab95c9a3
|
||||
F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
|
||||
F ext/wasm/fiddle.make dbe36b90b8907ae28ecb9c0e9fd8389dbdaecf117ea4fb2ea33864bdfa498a94
|
||||
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||
@ -530,7 +531,7 @@ F ext/wasm/fiddle/fiddle-worker.js 163d6139a93fab4bcb72064923df050d4e7c0ff0d8aa0
|
||||
F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715
|
||||
F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2
|
||||
F ext/wasm/index-dist.html 22379774f0ad4edcaaa8cf9c674c82e794cc557719a8addabed74eb8069d412e
|
||||
F ext/wasm/index.html b768e8659b4fe311912e54d42906449d51c0f84b7f036cca47ec1f93bf3f91de
|
||||
F ext/wasm/index.html b4e55de741be9fb7656445ea55085f703a784aebde620e1c4852fa21c1ac1c5b
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
|
||||
F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb
|
||||
F ext/wasm/module-symbols.html 841de62fc198988b8330e238c260e70ec93028b096e1a1234db31b187a899d10
|
||||
@ -538,8 +539,8 @@ F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d
|
||||
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63
|
||||
F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d
|
||||
F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe
|
||||
F ext/wasm/speedtest1-worker.html 97c2bf5f8534091ce718de05801090d5a80c3f13575996f095ba23638e1bdca0
|
||||
F ext/wasm/speedtest1-worker.js 13b57c4a41729678a1194014afec2bd5b94435dcfc8d1039dfa9a533ac819ee1
|
||||
F ext/wasm/speedtest1-worker.html e33e2064bda572c0c3ebaec7306c35aa758d9d27e245d67e807f8cc4a9351cc5
|
||||
F ext/wasm/speedtest1-worker.js 315d26198c46be7c85e26fda15d80ef882424276abde25ffd8b026fb02a35d8c
|
||||
F ext/wasm/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da
|
||||
F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
|
||||
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
|
||||
@ -548,7 +549,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
||||
F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
|
||||
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
|
||||
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
|
||||
F ext/wasm/tester1.c-pp.js 4420eb97b6b4fc79e4e156b4b8010dd9f373365f4230dd76d823fb04ce28ffde
|
||||
F ext/wasm/tester1.c-pp.js f835c9f703b562142f23a3607fa4a34cb6aece5fb5d674ea5bd7d37b0e47e104
|
||||
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
|
||||
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
|
||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||
@ -587,17 +588,17 @@ F src/date.c f73f203b3877cef866c60ab402aec2bf89597219b60635cf50cbe3c5e4533e94
|
||||
F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
|
||||
F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
|
||||
F src/delete.c cd5f5cd06ed0b6a882ec1a8c2a0d73b3cecb28479ad19e9931c4706c5e2182be
|
||||
F src/expr.c 8d1656b65e26af3e34f78e947ac423f0d20c214ed25a67486e433bf16ca6b543
|
||||
F src/expr.c ef4a81822da6f767696bd7f4b9983328af061158958138540142285a5b1181b7
|
||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||
F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36
|
||||
F src/func.c 25f2e0204c011be56fc3c9a180534b68ca4866c61ec19806880136450434112d
|
||||
F src/func.c cc1da67fd643a43cfe691784158ec656d8ec6d13bb17e67018b01b38b3e4f5ab
|
||||
F src/global.c 29f56a330ed9d1b5cd9b79ac0ca36f97ac3afc730ff8bfa987b0db9e559d684d
|
||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
||||
F src/json.c 3bdc8916ee1acf47f63373278b7913befea89fc8f4bfc0299ae9a2b34b35ee07
|
||||
F src/json.c d34d10ea1520bb71ee69c500deb4a20847a57b4c59c1ecb807c935f53c870885
|
||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||
F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
|
||||
F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002
|
||||
@ -705,15 +706,15 @@ F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0
|
||||
F src/update.c 0aa36561167a7c40d01163238c297297962f31a15a8d742216b3c37cdf25f731
|
||||
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||
F src/util.c fea6fffdee3cdae917a66b70deec59d4f238057cfd6de623d15cf990c196940d
|
||||
F src/util.c c2aa170f2eb429235b1dddce8952770787ffa5124dc89d405bfbe8ebad8e7ebd
|
||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||
F src/vdbe.c 74282a947234513872a83b0bab1b8c644ece64b3e27b053ef17677c8ff9c81e0
|
||||
F src/vdbe.c 4cda877d413a18fa07346b08d6959b3d18ce982357921e7acb9649fca2534a12
|
||||
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
|
||||
F src/vdbeInt.h 7bd49eef8f89c1a271fbf12d80a206bf56c876814c5fc6bee340f4e1907095ae
|
||||
F src/vdbeapi.c de9703f8705afc393cc2864669ce28cf9516983c8331d59aa2b978de01634365
|
||||
F src/vdbeInt.h 401813862f9d75af01bdb2ab99253ad019e9d6ddcc8058e4fa61a43e9a60d1f7
|
||||
F src/vdbeapi.c dde6c4d0f87486f056b9db4d1ea185bb1d84a6839102b86e76316ba590d07cc7
|
||||
F src/vdbeaux.c b5e3f7e158518b4eca6f166ac43900640a3fe9735c710e12bfa119af21059339
|
||||
F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce
|
||||
F src/vdbemem.c cf4a1556dd5b18c071cf7c243373c29ce752eb516022e3ad49ba72f08b785033
|
||||
F src/vdbemem.c 40afb83ed848e235848ffdd3ba25adca4ba602111b8ed3b05ae3b1b12e0eacee
|
||||
F src/vdbesort.c 0d40dca073c94e158ead752ef4225f4fee22dee84145e8c00ca2309afb489015
|
||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||
F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac
|
||||
@ -1222,7 +1223,7 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff
|
||||
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
|
||||
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
|
||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
||||
F test/json/README.md 506af1f54574b524106acb50d1a341ab5ddfa6d83fe25095007892b07e663e85
|
||||
F test/json/README.md 0992b8ccbecd8424b84c1173f9ac56bcc0ae96d49912fd2d86c04eb1f3cba7af
|
||||
F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f
|
||||
F test/json/json-q1.txt 335a7c8ab291d354f33b7decc9559e99a2823d4142291c4be7aa339a631f3c2d
|
||||
F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x
|
||||
@ -2043,8 +2044,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 e384163a4763c10b5838cbf28f9c4d8ea799bbbed6e890e8aa91b2bd1458646d
|
||||
R 35c799f493c52a97264947f70c69a12e
|
||||
P 1955e66cfc4614df97b8d68b0e662f309513d62dc8aeec71af5a54e66b79c707 c1b080e39397c983c13a5e79303223827de7b4946c18a79396851ec1814782f3
|
||||
R 2ab9518ef262a1aca9fe7f6a2ac934e0
|
||||
U drh
|
||||
Z 7b5e59d8c6f3a8847c09c081e8b2a5bc
|
||||
Z 40e6676e6b6212e46c825865d3333a87
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
1955e66cfc4614df97b8d68b0e662f309513d62dc8aeec71af5a54e66b79c707
|
||||
00bfc4918be49ac74a3e7851c88ab7ec226e6a37853f8ad4c77f758751960456
|
@ -4690,8 +4690,7 @@ expr_code_doover:
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
|
||||
SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
|
||||
sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR);
|
||||
}else{
|
||||
r1 = 0;
|
||||
}
|
||||
|
@ -1227,6 +1227,7 @@ static void charFunc(
|
||||
*zOut++ = 0x80 + (u8)(c & 0x3F);
|
||||
} \
|
||||
}
|
||||
*zOut = 0;
|
||||
sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
|
||||
}
|
||||
|
||||
|
@ -517,7 +517,8 @@ static void jsonAppendValue(
|
||||
*/
|
||||
static void jsonResult(JsonString *p){
|
||||
if( p->bErr==0 ){
|
||||
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed,
|
||||
jsonAppendChar(p, 0);
|
||||
sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed-1,
|
||||
p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
|
||||
SQLITE_UTF8);
|
||||
jsonZero(p);
|
||||
|
@ -846,7 +846,9 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
|
||||
}else
|
||||
#endif /* SQLITE_OMIT_HEX_INTEGER */
|
||||
{
|
||||
return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8);
|
||||
int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789"));
|
||||
if( z[n] ) n++;
|
||||
return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -556,6 +556,9 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){
|
||||
sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.');
|
||||
}
|
||||
sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
|
||||
if( f & MEM_Term ){
|
||||
sqlite3_str_appendf(pStr, "(0-term)");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -3085,6 +3088,9 @@ op_column_restart:
|
||||
rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
|
||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
|
||||
if( (t&1)!=0 && encoding==SQLITE_UTF8 ){
|
||||
pDest->flags |= MEM_Term;
|
||||
}
|
||||
pDest->flags &= ~MEM_Ephem;
|
||||
}
|
||||
}
|
||||
|
@ -611,6 +611,7 @@ int sqlite3VdbeMemSetZeroBlob(Mem*,int);
|
||||
int sqlite3VdbeMemIsRowSet(const Mem*);
|
||||
#endif
|
||||
int sqlite3VdbeMemSetRowSet(Mem*);
|
||||
void sqlite3VdbeMemZeroTerminateIfAble(Mem*);
|
||||
int sqlite3VdbeMemMakeWriteable(Mem*);
|
||||
int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
||||
int sqlite3IntFloatCompare(i64,double);
|
||||
|
@ -514,6 +514,7 @@ void sqlite3_result_text64(
|
||||
(void)invokeValueDestructor(z, xDel, pCtx);
|
||||
}else{
|
||||
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
|
||||
sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut);
|
||||
}
|
||||
}
|
||||
#ifndef SQLITE_OMIT_UTF16
|
||||
|
@ -314,6 +314,32 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** If pMem is already a string, detect if it is a zero-terminated
|
||||
** string, or make it into one if possible, and mark it as such.
|
||||
**
|
||||
** This is an optimization. Correct operation continues even if
|
||||
** this routine is a no-op.
|
||||
*/
|
||||
void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){
|
||||
if( (pMem->flags & (MEM_Str|MEM_Term))!=MEM_Str ) return;
|
||||
if( pMem->enc!=SQLITE_UTF8 ) return;
|
||||
if( NEVER(pMem->z==0) ) return;
|
||||
if( pMem->flags & MEM_Dyn ){
|
||||
if( pMem->xDel==sqlite3_free
|
||||
&& sqlite3_msize(pMem->z) >= (u64)(pMem->n+1)
|
||||
){
|
||||
pMem->z[pMem->n] = 0;
|
||||
pMem->flags |= MEM_Term;
|
||||
return;
|
||||
}
|
||||
}else if( pMem->szMalloc>0 && pMem->szMalloc >= pMem->n+1 ){
|
||||
pMem->z[pMem->n] = 0;
|
||||
pMem->flags |= MEM_Term;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** It is already known that pMem contains an unterminated string.
|
||||
** Add the zero terminator.
|
||||
@ -803,6 +829,7 @@ int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
int rc;
|
||||
assert( aff==SQLITE_AFF_TEXT );
|
||||
assert( MEM_Str==(MEM_Blob>>3) );
|
||||
pMem->flags |= (pMem->flags&MEM_Blob)>>3;
|
||||
@ -810,7 +837,9 @@ int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
|
||||
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
|
||||
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
|
||||
if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1;
|
||||
return sqlite3VdbeChangeEncoding(pMem, encoding);
|
||||
rc = sqlite3VdbeChangeEncoding(pMem, encoding);
|
||||
if( rc ) return rc;
|
||||
sqlite3VdbeMemZeroTerminateIfAble(pMem);
|
||||
}
|
||||
}
|
||||
return SQLITE_OK;
|
||||
|
@ -25,3 +25,15 @@ of the SQLite JSON parser.
|
||||
|
||||
2. Run "`sh json-speed-check-1.sh x1`". The profile output will appear
|
||||
in jout-x1.txt. Substitute any label you want in place of "x1".
|
||||
|
||||
3. Run the script shown below in the CLI.
|
||||
Divide 2500 by the real elapse time from this test
|
||||
to get an estimate for number of MB/s that the JSON parser is
|
||||
able to process.
|
||||
|
||||
> ~~~~
|
||||
.open json100mb.db
|
||||
.timer on
|
||||
WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<25)
|
||||
SELECT sum(json_valid(x)) FROM c, data1;
|
||||
~~~~
|
||||
|
Loading…
Reference in New Issue
Block a user