mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Update the latest trunk enhancements into the wal-shm-exceptions branch.
FossilOrigin-Name: 3187ee3f69fc28a259ba0e951ac10a65c07ef2c3866acbefaf9544333a930cc6
This commit is contained in:
@@ -4655,9 +4655,13 @@ static void fts5SecureDeleteOverflow(
|
|||||||
int i1 = pLeaf->szLeaf;
|
int i1 = pLeaf->szLeaf;
|
||||||
int i2 = 0;
|
int i2 = 0;
|
||||||
|
|
||||||
|
i1 += fts5GetVarint32(&aPg[i1], iFirst);
|
||||||
|
if( iFirst<iNext ){
|
||||||
|
p->rc = FTS5_CORRUPT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
|
aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2);
|
||||||
if( aIdx==0 ) break;
|
if( aIdx==0 ) break;
|
||||||
i1 += fts5GetVarint32(&aPg[i1], iFirst);
|
|
||||||
i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift);
|
i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift);
|
||||||
if( i1<pLeaf->nn ){
|
if( i1<pLeaf->nn ){
|
||||||
memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1);
|
memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1);
|
||||||
|
@@ -18,8 +18,6 @@
|
|||||||
# quick, q = do just a minimal build (sqlite3.js/wasm, tester1) for
|
# quick, q = do just a minimal build (sqlite3.js/wasm, tester1) for
|
||||||
# faster development-mode turnaround.
|
# faster development-mode turnaround.
|
||||||
#
|
#
|
||||||
# qo2, qoz = a combination of quick+o2/oz.
|
|
||||||
#
|
|
||||||
# dist = create end user deliverables. Add dist.build=oX to build
|
# dist = create end user deliverables. Add dist.build=oX to build
|
||||||
# with a specific optimization level, where oX is one of the
|
# with a specific optimization level, where oX is one of the
|
||||||
# above-listed o? or qo? target names.
|
# above-listed o? or qo? target names.
|
||||||
@@ -46,11 +44,12 @@
|
|||||||
# $(eval), or at least centralize the setup of the numerous vars
|
# $(eval), or at least centralize the setup of the numerous vars
|
||||||
# related to each build variant $(JS_BUILD_MODES).
|
# related to each build variant $(JS_BUILD_MODES).
|
||||||
#
|
#
|
||||||
|
default: all
|
||||||
|
#default: quick
|
||||||
SHELL := $(shell which bash 2>/dev/null)
|
SHELL := $(shell which bash 2>/dev/null)
|
||||||
MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
MAKEFILE := $(lastword $(MAKEFILE_LIST))
|
||||||
CLEAN_FILES :=
|
CLEAN_FILES :=
|
||||||
DISTCLEAN_FILES := ./--dummy--
|
DISTCLEAN_FILES := ./--dummy--
|
||||||
default: all
|
|
||||||
release: oz
|
release: oz
|
||||||
# JS_BUILD_MODES exists solely to reduce repetition in documentation
|
# JS_BUILD_MODES exists solely to reduce repetition in documentation
|
||||||
# below.
|
# below.
|
||||||
@@ -68,13 +67,6 @@ ifeq (,$(emcc.version))
|
|||||||
else
|
else
|
||||||
$(info using emcc version [$(emcc.version)])
|
$(info using emcc version [$(emcc.version)])
|
||||||
endif
|
endif
|
||||||
emcc.version := $(shell "$(emcc.bin)" --version | sed -n 1p \
|
|
||||||
| sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;')
|
|
||||||
ifeq (,$(emcc.version))
|
|
||||||
$(warning Cannot determine emcc version. This might unduly impact build flags.)
|
|
||||||
else
|
|
||||||
$(info using emcc version [$(emcc.version)])
|
|
||||||
endif
|
|
||||||
|
|
||||||
wasm-strip ?= $(shell which wasm-strip 2>/dev/null)
|
wasm-strip ?= $(shell which wasm-strip 2>/dev/null)
|
||||||
ifeq (,$(filter clean,$(MAKECMDGOALS)))
|
ifeq (,$(filter clean,$(MAKECMDGOALS)))
|
||||||
@@ -159,6 +151,9 @@ endif
|
|||||||
# bundle.
|
# bundle.
|
||||||
#
|
#
|
||||||
# A custom sqlite3.c must not have any spaces in its name.
|
# A custom sqlite3.c must not have any spaces in its name.
|
||||||
|
# $(sqlite3.canonical.c) must point to the sqlite3.c in
|
||||||
|
# the sqlite3 canonical source tree, as that source file
|
||||||
|
# is required for certain utility and test code.
|
||||||
sqlite3.canonical.c := $(dir.top)/sqlite3.c
|
sqlite3.canonical.c := $(dir.top)/sqlite3.c
|
||||||
sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c))
|
sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c))
|
||||||
sqlite3.h := $(dir.top)/sqlite3.h
|
sqlite3.h := $(dir.top)/sqlite3.h
|
||||||
@@ -186,7 +181,7 @@ SQLITE_OPT = \
|
|||||||
-DSQLITE_OMIT_SHARED_CACHE \
|
-DSQLITE_OMIT_SHARED_CACHE \
|
||||||
-DSQLITE_OMIT_WAL \
|
-DSQLITE_OMIT_WAL \
|
||||||
-DSQLITE_THREADSAFE=0 \
|
-DSQLITE_THREADSAFE=0 \
|
||||||
-DSQLITE_TEMP_STORE=3 \
|
-DSQLITE_TEMP_STORE=2 \
|
||||||
-DSQLITE_OS_KV_OPTIONAL=1 \
|
-DSQLITE_OS_KV_OPTIONAL=1 \
|
||||||
'-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \
|
'-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \
|
||||||
-DSQLITE_USE_URI=1 \
|
-DSQLITE_USE_URI=1 \
|
||||||
@@ -379,20 +374,17 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-oo1.js
|
|||||||
sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.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-v-helper.js
|
||||||
sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.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
|
sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js
|
||||||
|
|
||||||
# "External" API files which are part of our distribution
|
# SOAP.js is an external API file which is part of our distribution
|
||||||
# but not part of the sqlite3-api.js amalgamation.
|
# but not part of the sqlite3-api.js amalgamation.
|
||||||
SOAP.js := $(dir.api)/sqlite3-opfs-async-proxy.js
|
SOAP.js := $(dir.api)/sqlite3-opfs-async-proxy.js
|
||||||
# COPY_XAPI = a $(call)able function to copy $1 to $(dir.dout), where
|
SOAP.js.bld := $(dir.dout)/$(notdir $(SOAP.js))
|
||||||
# $1 must be one of the "external" JS API files.
|
sqlite3-api.ext.jses += $(SOAP.js.bld)
|
||||||
define COPY_XAPI
|
$(SOAP.js.bld): $(SOAP.js)
|
||||||
sqlite3-api.ext.jses += $$(dir.dout)/$$(notdir $(1))
|
cp $< $@
|
||||||
$$(dir.dout)/$$(notdir $(1)): $(1) $$(MAKEFILE)
|
|
||||||
cp $$< $$@
|
|
||||||
endef
|
|
||||||
$(foreach X,$(SOAP.js),\
|
|
||||||
$(eval $(call COPY_XAPI,$(X))))
|
|
||||||
all quick: $(sqlite3-api.ext.jses)
|
all quick: $(sqlite3-api.ext.jses)
|
||||||
q: quick
|
q: quick
|
||||||
|
|
||||||
@@ -615,26 +607,40 @@ $(post-js.js.in): $(post-jses.js) $(MAKEFILE)
|
|||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# call-make-pre-post is a $(call)able which creates rules for
|
# call-make-pre-post is a $(call)able which creates rules for
|
||||||
# pre-js-$(1).js. $1 = the base name of the JS file on whose behalf
|
# pre-js-$(1)-$(2).js. $1 = the base name of the JS file on whose
|
||||||
# this pre-js is for (one of: sqlite3, sqlite3-wasmfs). $2 is the
|
# behalf this pre-js is for (one of: sqlite3, sqlite3-wasmfs). $2 is
|
||||||
# build mode: one of $(JS_BUILD_MODES). This
|
# the build mode: one of $(JS_BUILD_MODES). This sets up
|
||||||
# sets up --[extern-][pre/post]-js flags in
|
# --[extern-][pre/post]-js flags in $(pre-post-$(1)-$(2).flags) and
|
||||||
# $(pre-post-$(1).flags.$(2)) and dependencies in
|
# dependencies in $(pre-post-$(1)-$(2).deps). The resulting files get
|
||||||
# $(pre-post-$(1).deps.$(2)).
|
# filtered using $(C-PP.FILTER). Any flags necessary for such
|
||||||
|
# filtering need to be set in $(c-pp.D.$(1)-$(2)) before $(call)ing
|
||||||
|
# this.
|
||||||
define call-make-pre-post
|
define call-make-pre-post
|
||||||
pre-post-$(1).flags.$(2) ?=
|
pre-post-$(1)-$(2).flags ?=
|
||||||
$$(dir.tmp)/pre-js-$(1)-$(2).js: $$(pre-js.js.$(2)) $$(MAKEFILE)
|
pre-js.js.$(1)-$(2) := $$(dir.tmp)/pre-js.$(1)-$(2).intermediary.js
|
||||||
cp $$(pre-js.js.$(2)) $$@
|
$$(eval $$(call C-PP.FILTER,$$(pre-js.js.in),$$(pre-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2))))
|
||||||
|
post-js.js.$(1)-$(2) := $$(dir.tmp)/post-js.$(1)-$(2).js
|
||||||
|
$$(eval $$(call C-PP.FILTER,$$(post-js.js.in),$$(post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2))))
|
||||||
|
extern-post-js.js.$(1)-$(2) := $$(dir.tmp)/extern-post-js.$(1)-$(2).js
|
||||||
|
$$(eval $$(call C-PP.FILTER,$$(extern-post-js.js.in),$$(extern-post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2))))
|
||||||
|
pre-post-common.flags.$(1)-$(2) := \
|
||||||
|
$$(pre-post-common.flags) \
|
||||||
|
--post-js=$$(post-js.js.$(1)-$(2)) \
|
||||||
|
--extern-post-js=$$(extern-post-js.js.$(1)-$(2))
|
||||||
|
pre-post-jses.$(1)-$(2).deps := $$(pre-post-jses.deps.common) \
|
||||||
|
$$(post-js.js.$(1)-$(2)) $$(extern-post-js.js.$(1)-$(2))
|
||||||
|
$$(dir.tmp)/pre-js-$(1)-$(2).js: $$(pre-js.js.$(1)-$(2)) $$(MAKEFILE)
|
||||||
|
cp $$(pre-js.js.$(1)-$(2)) $$@
|
||||||
@if [ sqlite3-wasmfs = $(1) ]; then \
|
@if [ sqlite3-wasmfs = $(1) ]; then \
|
||||||
echo "delete Module[xNameOfInstantiateWasm] /*for WASMFS build*/;"; \
|
echo "delete Module[xNameOfInstantiateWasm] /*for WASMFS build*/;"; \
|
||||||
elif [ sqlite3 != $(1) ]; then \
|
elif [ sqlite3 != $(1) ]; then \
|
||||||
echo "Module[xNameOfInstantiateWasm].uri = '$(1).wasm';"; \
|
echo "Module[xNameOfInstantiateWasm].uri = '$(1).wasm';"; \
|
||||||
fi >> $$@
|
fi >> $$@
|
||||||
pre-post-$(1).deps.$(2) := \
|
pre-post-$(1)-$(2).deps := \
|
||||||
$$(pre-post-jses.deps.$(2)) \
|
$$(pre-post-jses.$(1)-$(2).deps) \
|
||||||
$$(dir.tmp)/pre-js-$(1)-$(2).js
|
$$(dir.tmp)/pre-js-$(1)-$(2).js
|
||||||
pre-post-$(1).flags.$(2) += \
|
pre-post-$(1)-$(2).flags += \
|
||||||
$$(pre-post-common.flags.$(2)) \
|
$$(pre-post-common.flags.$(1)-$(2)) \
|
||||||
--pre-js=$$(dir.tmp)/pre-js-$(1)-$(2).js
|
--pre-js=$$(dir.tmp)/pre-js-$(1)-$(2).js
|
||||||
endef
|
endef
|
||||||
# /post-js and pre-js
|
# /post-js and pre-js
|
||||||
@@ -645,7 +651,8 @@ endef
|
|||||||
# https://github.com/emscripten-core/emscripten/issues/14383
|
# https://github.com/emscripten-core/emscripten/issues/14383
|
||||||
sqlite3.wasm := $(dir.dout)/sqlite3.wasm
|
sqlite3.wasm := $(dir.dout)/sqlite3.wasm
|
||||||
sqlite3-wasm.c := $(dir.api)/sqlite3-wasm.c
|
sqlite3-wasm.c := $(dir.api)/sqlite3-wasm.c
|
||||||
sqlite3-wasm.cses := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
|
sqlite3-wasm.cfiles := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
|
||||||
|
sqlite3-wasmfs.cfiles := $(sqlite3-wasm.cfiles)
|
||||||
# sqlite3-wasm.o vs sqlite3-wasm.c: building against the latter
|
# sqlite3-wasm.o vs sqlite3-wasm.c: building against the latter
|
||||||
# (predictably) results in a slightly faster binary. We're close
|
# (predictably) results in a slightly faster binary. We're close
|
||||||
# enough to the target speed requirements that the 500ms makes a
|
# enough to the target speed requirements that the 500ms makes a
|
||||||
@@ -655,7 +662,8 @@ sqlite3-wasm.cses := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
|
|||||||
# SQLITE3.xJS.EXPORT-DEFAULT is part of SQLITE3-WASMFS.xJS.RECIPE and
|
# SQLITE3.xJS.EXPORT-DEFAULT is part of SQLITE3-WASMFS.xJS.RECIPE and
|
||||||
# SETUP_LIB_BUILD_MODE, factored into a separate piece to avoid code
|
# SETUP_LIB_BUILD_MODE, factored into a separate piece to avoid code
|
||||||
# duplication. $1 is 1 if the build mode needs this workaround (esm,
|
# duplication. $1 is 1 if the build mode needs this workaround (esm,
|
||||||
# bundler-friendly) and 0 if not (vanilla).
|
# bundler-friendly, node) and 0 if not (vanilla). $2 must be empty for
|
||||||
|
# all builds except sqlite3-wasmfs.mjs, in which case it must be 1.
|
||||||
#
|
#
|
||||||
# Reminder for ESM builds: even if we use -sEXPORT_ES6=0, emcc _still_
|
# Reminder for ESM builds: even if we use -sEXPORT_ES6=0, emcc _still_
|
||||||
# adds:
|
# adds:
|
||||||
@@ -671,11 +679,13 @@ sqlite3-wasm.cses := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c)
|
|||||||
# https://github.com/emscripten-core/emscripten/issues/18237
|
# https://github.com/emscripten-core/emscripten/issues/18237
|
||||||
define SQLITE3.xJS.ESM-EXPORT-DEFAULT
|
define SQLITE3.xJS.ESM-EXPORT-DEFAULT
|
||||||
if [ x1 = x$(1) ]; then \
|
if [ x1 = x$(1) ]; then \
|
||||||
echo "Fragile workaround for an Emscripten annoyance. See SQLITE3.xJS.RECIPE."; \
|
echo "Fragile workaround for emscripten/issues/18237. See SQLITE3.xJS.RECIPE."; \
|
||||||
sed -i -e '0,/^export default/{/^export default/d;}' $@ || exit $$?; \
|
sed -i -e '0,/^export default/{/^export default/d;}' $@ || exit $$?; \
|
||||||
if ! grep -q '^export default' $@; then \
|
if [ x != x$(2) ]; then \
|
||||||
echo "Cannot find export default." 1>&2; \
|
if ! grep -q '^export default' $@; then \
|
||||||
exit 1; \
|
echo "Cannot find export default." 1>&2; \
|
||||||
|
exit 1; \
|
||||||
|
fi; \
|
||||||
fi; \
|
fi; \
|
||||||
fi
|
fi
|
||||||
endef
|
endef
|
||||||
@@ -695,53 +705,57 @@ pre-post-jses.deps.common := $(extern-pre-js.js) $(sqlite3-license-version.js)
|
|||||||
# SETUP_LIB_BUILD_MODE is a $(call)'able which sets up numerous pieces
|
# SETUP_LIB_BUILD_MODE is a $(call)'able which sets up numerous pieces
|
||||||
# for one of the build modes.
|
# for one of the build modes.
|
||||||
#
|
#
|
||||||
# $1 = build mode name: one of $(JS_BUILD_MODES)
|
# $1 = one of: sqlite3, sqlite3-wasmfs
|
||||||
# $2 = 1 for ESM build mode, else 0
|
# $2 = build mode name: one of $(JS_BUILD_MODES)
|
||||||
# $3 = resulting sqlite-api JS/MJS file
|
# $3 = 1 for ESM build mode, else 0
|
||||||
# $4 = resulting JS/MJS file
|
# $4 = resulting sqlite-api JS/MJS file
|
||||||
# $5 = -D... flags for $(bin.c-pp)
|
# $5 = resulting JS/MJS file
|
||||||
# $6 = emcc -sXYZ flags (CURRENTLY UNUSED - was factored out)
|
# $6 = -D... flags for $(bin.c-pp)
|
||||||
|
# $7 = emcc -sXYZ flags (CURRENTLY UNUSED - was factored out)
|
||||||
#
|
#
|
||||||
# emcc.environment.$(1) must be set to a value for the -sENVIRONMENT flag.
|
# Maintenance reminder: be careful not to introduce spaces around args
|
||||||
|
# ($1, $2), otherwise string concatenation will malfunction.
|
||||||
|
#
|
||||||
|
# emcc.environment.$(2) must be set to a value for the -sENVIRONMENT flag.
|
||||||
|
#
|
||||||
|
# $(cflags.$(1)) and $(cflags.$(1).$(2)) may be defined to append
|
||||||
|
# CFLAGS to a given build mode.
|
||||||
|
#
|
||||||
|
# $(emcc.flags.$(1)) and $(emcc.flags.$(1).$(2)) may be defined to
|
||||||
|
# append emcc-specific flags to a given build mode.
|
||||||
define SETUP_LIB_BUILD_MODE
|
define SETUP_LIB_BUILD_MODE
|
||||||
$(info Setting up build [$(1)]: $(4))
|
$(info Setting up build [$(1)-$(2)]: $(5))
|
||||||
c-pp.D.$(1) := $(5)
|
c-pp.D.$(1)-$(2) := $(6)
|
||||||
pre-js.js.$(1) := $$(dir.tmp)/pre-js.$(1).js
|
$$(eval $$(call call-make-pre-post,$(1),$(2)))
|
||||||
$$(eval $$(call C-PP.FILTER,$$(pre-js.js.in),$$(pre-js.js.$(1)),$$(c-pp.D.$(1))))
|
emcc.flags.$(1).$(2) ?=
|
||||||
post-js.js.$(1) := $$(dir.tmp)/post-js.$(1).js
|
emcc.flags.$(1).$(2) += $(7)
|
||||||
$$(eval $$(call C-PP.FILTER,$$(post-js.js.in),$$(post-js.js.$(1)),$$(c-pp.D.$(1))))
|
$$(eval $$(call C-PP.FILTER, $$(sqlite3-api.js.in), $(4), $(6)))
|
||||||
extern-post-js.js.$(1) := $$(dir.tmp)/extern-post-js.$(1).js
|
$(5): $(4) $$(MAKEFILE) $$(sqlite3-wasm.cfiles) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-$(1)-$(2).deps)
|
||||||
$$(eval $$(call C-PP.FILTER,$$(extern-post-js.js.in),$$(extern-post-js.js.$(1)),$$(c-pp.D.$(1))))
|
|
||||||
pre-post-common.flags.$(1) := \
|
|
||||||
$$(pre-post-common.flags) \
|
|
||||||
--post-js=$$(post-js.js.$(1)) \
|
|
||||||
--extern-post-js=$$(extern-post-js.js.$(1))
|
|
||||||
pre-post-jses.deps.$(1) := $$(pre-post-jses.deps.common) \
|
|
||||||
$$(post-js.js.$(1)) $$(extern-post-js.js.$(1))
|
|
||||||
$$(eval $$(call call-make-pre-post,sqlite3,$(1)))
|
|
||||||
emcc.flags.sqlite3.$(1) := $(6)
|
|
||||||
$$(eval $$(call C-PP.FILTER, $$(sqlite3-api.js.in), $(3), $(5)))
|
|
||||||
$(4): $(3) $$(MAKEFILE) $$(sqlite3-wasm.cses) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-sqlite3.deps.$(1))
|
|
||||||
@echo "Building $$@ ..."
|
@echo "Building $$@ ..."
|
||||||
$$(emcc.bin) -o $$@ $$(emcc_opt_full) $$(emcc.flags) \
|
$$(emcc.bin) -o $$@ $$(emcc_opt_full) $$(emcc.flags) \
|
||||||
$$(emcc.jsflags) \
|
$$(emcc.jsflags) \
|
||||||
-sENVIRONMENT=$$(emcc.environment.$(1)) \
|
-sENVIRONMENT=$$(emcc.environment.$(2)) \
|
||||||
$$(pre-post-sqlite3.flags.$(1)) $$(emcc.flags.sqlite3.$(1)) \
|
$$(pre-post-$(1)-$(2).flags) \
|
||||||
$$(cflags.common) $$(SQLITE_OPT) $$(cflags.wasm_extra_init) $$(sqlite3-wasm.cses)
|
$$(emcc.flags.$(1)) $$(emcc.flags.$(1).$(2)) \
|
||||||
@$$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(2))
|
$$(cflags.common) $$(SQLITE_OPT) \
|
||||||
@case $(1) in \
|
$$(cflags.$(1)) $$(cflags.$(1).$(2)) \
|
||||||
|
$$(cflags.wasm_extra_init) $$(sqlite3-wasm.cfiles)
|
||||||
|
@$$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(3))
|
||||||
|
@dotwasm=$$(basename $$@).wasm; \
|
||||||
|
chmod -x $$$$dotwasm; \
|
||||||
|
$(maybe-wasm-strip) $$$$dotwasm; \
|
||||||
|
case $(2) in \
|
||||||
bundler-friendly|node) \
|
bundler-friendly|node) \
|
||||||
echo "Patching $(3) for sqlite3.wasm..."; \
|
echo "Patching $$@ for $(1).wasm..."; \
|
||||||
rm -f $$(dir.dout)/sqlite3-$(1).wasm; \
|
rm -f $$$$dotwasm; \
|
||||||
sed -i -e 's/sqlite3-$(1).wasm/sqlite3.wasm/g' $$@ || exit $$$$?; \
|
dotwasm=; \
|
||||||
|
sed -i -e 's/$(1)-$(2).wasm/$(1).wasm/g' $$@ || exit $$$$?; \
|
||||||
;; \
|
;; \
|
||||||
esac
|
esac; \
|
||||||
chmod -x $$(sqlite3.wasm)
|
ls -la $$$$dotwasm $$@
|
||||||
$$(maybe-wasm-strip) $$(sqlite3.wasm)
|
all: $(5)
|
||||||
@ls -la $@ $$(sqlite3.wasm)
|
#quick: $(5)
|
||||||
all: $(4)
|
CLEAN_FILES += $(4) $(5)
|
||||||
quick: $(4)
|
|
||||||
CLEAN_FILES += $(3) $(4)
|
|
||||||
endef
|
endef
|
||||||
# ^^^ /SETUP_LIB_BUILD_MODE
|
# ^^^ /SETUP_LIB_BUILD_MODE
|
||||||
########################################################################
|
########################################################################
|
||||||
@@ -753,21 +767,24 @@ sqlite3-api-bundler-friendly.mjs := $(dir.dout)/sqlite3-api-bundler-friendly.mjs
|
|||||||
sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs
|
sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs
|
||||||
sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs
|
sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs
|
||||||
sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs
|
sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs
|
||||||
# Maintenance reminder: careful not to introduce spaces around args $1, $2
|
#$(info $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0, $(sqlite3-api.js), $(sqlite3.js)))
|
||||||
#$(info $(call SETUP_LIB_BUILD_MODE,vanilla,0, $(sqlite3-api.js), $(sqlite3.js)))
|
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0,\
|
||||||
$(eval $(call SETUP_LIB_BUILD_MODE,vanilla,0, $(sqlite3-api.js), $(sqlite3.js)))
|
$(sqlite3-api.js), $(sqlite3.js)))
|
||||||
$(eval $(call SETUP_LIB_BUILD_MODE,esm,1, $(sqlite3-api.mjs), $(sqlite3.mjs), \
|
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,esm,1,\
|
||||||
|
$(sqlite3-api.mjs), $(sqlite3.mjs), \
|
||||||
-Dtarget=es6-module, -sEXPORT_ES6 -sUSE_ES6_IMPORT_META))
|
-Dtarget=es6-module, -sEXPORT_ES6 -sUSE_ES6_IMPORT_META))
|
||||||
$(eval $(call SETUP_LIB_BUILD_MODE,bundler-friendly,1,\
|
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,bundler-friendly,1,\
|
||||||
$(sqlite3-api-bundler-friendly.mjs),$(sqlite3-bundler-friendly.mjs),\
|
$(sqlite3-api-bundler-friendly.mjs),$(sqlite3-bundler-friendly.mjs),\
|
||||||
$(c-pp.D.esm) -Dtarget=es6-bundler-friendly))
|
$(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly))
|
||||||
$(eval $(call SETUP_LIB_BUILD_MODE,node,1,\
|
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,node,1,\
|
||||||
$(sqlite3-api-node.mjs),$(sqlite3-node.mjs),\
|
$(sqlite3-api-node.mjs),$(sqlite3-node.mjs),\
|
||||||
$(c-pp.D.bundler-friendly) -Dtarget=node))
|
$(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node))
|
||||||
# The various -D... values used by *.c-pp.js include:
|
# The various -D... values used by *.c-pp.js include:
|
||||||
#
|
#
|
||||||
# -Dtarget=es6-module: for all ESM module builds
|
# -Dtarget=es6-module: for all ESM module builds
|
||||||
#
|
#
|
||||||
|
# -Dtarget=node: for node.js builds
|
||||||
|
#
|
||||||
# -Dtarget=es6-module -Dtarget=es6-bundler-friendly: intended for
|
# -Dtarget=es6-module -Dtarget=es6-bundler-friendly: intended for
|
||||||
# "bundler-friendly" ESM module build. These have some restrictions
|
# "bundler-friendly" ESM module build. These have some restrictions
|
||||||
# on how URL() objects are constructed in some contexts: URLs which
|
# on how URL() objects are constructed in some contexts: URLs which
|
||||||
@@ -849,7 +866,7 @@ all: batch
|
|||||||
# emcc.speedtest1.common = emcc flags used by multiple builds of speedtest1
|
# emcc.speedtest1.common = emcc flags used by multiple builds of speedtest1
|
||||||
# emcc.speedtest1 = emcc flags used by main build of speedtest1
|
# emcc.speedtest1 = emcc flags used by main build of speedtest1
|
||||||
emcc.speedtest1.common := $(emcc_opt_full)
|
emcc.speedtest1.common := $(emcc_opt_full)
|
||||||
emcc.speedtest1 :=
|
emcc.speedtest1 := -I. -I$(dir $(sqlite3.canonical.c))
|
||||||
emcc.speedtest1 += -sENVIRONMENT=web
|
emcc.speedtest1 += -sENVIRONMENT=web
|
||||||
emcc.speedtest1 += -sALLOW_MEMORY_GROWTH
|
emcc.speedtest1 += -sALLOW_MEMORY_GROWTH
|
||||||
emcc.speedtest1 += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))
|
emcc.speedtest1 += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY))
|
||||||
@@ -892,22 +909,24 @@ $(EXPORTED_FUNCTIONS.speedtest1): $(EXPORTED_FUNCTIONS.api.main)
|
|||||||
@{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.main); } > $@
|
@{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.main); } > $@
|
||||||
speedtest1.js := $(dir.dout)/speedtest1.js
|
speedtest1.js := $(dir.dout)/speedtest1.js
|
||||||
speedtest1.wasm := $(dir.dout)/speedtest1.wasm
|
speedtest1.wasm := $(dir.dout)/speedtest1.wasm
|
||||||
cflags.speedtest1 := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM
|
emcc.flags.speedtest1-vanilla := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM
|
||||||
speedtest1.cses := $(speedtest1.c) $(sqlite3-wasm.c)
|
|
||||||
|
speedtest1.cfiles := $(speedtest1.c) $(sqlite3-wasm.c)
|
||||||
$(eval $(call call-make-pre-post,speedtest1,vanilla))
|
$(eval $(call call-make-pre-post,speedtest1,vanilla))
|
||||||
$(speedtest1.js): $(MAKEFILE) $(speedtest1.cses) \
|
$(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \
|
||||||
$(pre-post-speedtest1.deps.vanilla) \
|
$(pre-post-speedtest1-vanilla.deps) \
|
||||||
$(EXPORTED_FUNCTIONS.speedtest1)
|
$(EXPORTED_FUNCTIONS.speedtest1)
|
||||||
@echo "Building $@ ..."
|
@echo "Building $@ ..."
|
||||||
$(emcc.bin) \
|
$(emcc.bin) \
|
||||||
$(emcc.speedtest1) -I$(dir $(sqlite3.canonical.c)) \
|
$(emcc.speedtest1) \
|
||||||
$(emcc.speedtest1.common) \
|
$(emcc.speedtest1.common) \
|
||||||
$(cflags.speedtest1) $(pre-post-speedtest1.flags.vanilla) \
|
$(emcc.flags.speedtest1-vanilla) $(pre-post-speedtest1-vanilla.flags) \
|
||||||
$(SQLITE_OPT) \
|
$(SQLITE_OPT) \
|
||||||
-USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \
|
-USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \
|
||||||
$(speedtest1.exit-runtime0) \
|
$(speedtest1.exit-runtime0) \
|
||||||
-o $@ $(speedtest1.cses) -lm
|
-o $@ $(speedtest1.cfiles) -lm
|
||||||
$(maybe-wasm-strip) $(speedtest1.wasm)
|
$(maybe-wasm-strip) $(speedtest1.wasm)
|
||||||
|
chmod -x $(speedtest1.wasm)
|
||||||
ls -la $@ $(speedtest1.wasm)
|
ls -la $@ $(speedtest1.wasm)
|
||||||
|
|
||||||
speedtest1: $(speedtest1.js)
|
speedtest1: $(speedtest1.js)
|
||||||
@@ -933,13 +952,14 @@ CLEAN_FILES += $(speedtest1.js) $(speedtest1.wasm)
|
|||||||
#
|
#
|
||||||
# To create those, we filter tester1.c-pp.js with $(bin.c-pp)...
|
# To create those, we filter tester1.c-pp.js with $(bin.c-pp)...
|
||||||
$(eval $(call C-PP.FILTER,tester1.c-pp.js,tester1.js))
|
$(eval $(call C-PP.FILTER,tester1.c-pp.js,tester1.js))
|
||||||
$(eval $(call C-PP.FILTER,tester1.c-pp.js,tester1.mjs,$(c-pp.D.esm)))
|
$(eval $(call C-PP.FILTER,tester1.c-pp.js,tester1.mjs,$(c-pp.D.sqlite3-esm)))
|
||||||
$(eval $(call C-PP.FILTER,tester1.c-pp.html,tester1.html))
|
$(eval $(call C-PP.FILTER,tester1.c-pp.html,tester1.html))
|
||||||
$(eval $(call C-PP.FILTER,tester1.c-pp.html,tester1-esm.html,$(c-pp.D.esm)))
|
$(eval $(call C-PP.FILTER,tester1.c-pp.html,tester1-esm.html,$(c-pp.D.sqlite3-esm)))
|
||||||
tester1: tester1.js tester1.mjs tester1.html tester1-esm.html
|
tester1: tester1.js tester1.mjs tester1.html tester1-esm.html
|
||||||
# Note that we do not include $(sqlite3-bundler-friendly.mjs) in this
|
# Note that we do not include $(sqlite3-bundler-friendly.mjs) in this
|
||||||
# because bundlers are client-specific.
|
# because bundlers are client-specific.
|
||||||
all quick: tester1
|
all quick: tester1
|
||||||
|
quick: $(sqlite3.js)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Convenience rules to rebuild with various -Ox levels. Much
|
# Convenience rules to rebuild with various -Ox levels. Much
|
||||||
@@ -959,8 +979,6 @@ o1: clean
|
|||||||
$(MAKE) -e "emcc_opt=-O1 $(o-xtra)"
|
$(MAKE) -e "emcc_opt=-O1 $(o-xtra)"
|
||||||
o2: clean
|
o2: clean
|
||||||
$(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)"
|
$(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)"
|
||||||
qo2: clean
|
|
||||||
$(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)" quick
|
|
||||||
o3: clean
|
o3: clean
|
||||||
$(MAKE) -e "emcc_opt=-O3 $(o-xtra)"
|
$(MAKE) -e "emcc_opt=-O3 $(o-xtra)"
|
||||||
os: clean
|
os: clean
|
||||||
@@ -968,8 +986,6 @@ os: clean
|
|||||||
$(MAKE) -e "emcc_opt=-Os $(o-xtra)"
|
$(MAKE) -e "emcc_opt=-Os $(o-xtra)"
|
||||||
oz: clean
|
oz: clean
|
||||||
$(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)"
|
$(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)"
|
||||||
qoz: clean
|
|
||||||
$(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)" quick
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# Sub-makes...
|
# Sub-makes...
|
||||||
@@ -981,6 +997,8 @@ include fiddle.make
|
|||||||
ifneq (,$(filter wasmfs,$(MAKECMDGOALS)))
|
ifneq (,$(filter wasmfs,$(MAKECMDGOALS)))
|
||||||
wasmfs.enable ?= 1
|
wasmfs.enable ?= 1
|
||||||
else
|
else
|
||||||
|
# Unconditionally enable wasmfs for [dist]clean so that the wasmfs
|
||||||
|
# sub-make can clean up.
|
||||||
wasmfs.enable ?= $(if $(filter %clean,$(MAKECMDGOALS)),1,0)
|
wasmfs.enable ?= $(if $(filter %clean,$(MAKECMDGOALS)),1,0)
|
||||||
endif
|
endif
|
||||||
ifeq (1,$(wasmfs.enable))
|
ifeq (1,$(wasmfs.enable))
|
||||||
|
@@ -82,7 +82,7 @@ features in the apps which use them.
|
|||||||
|
|
||||||
# Testing on a remote machine that is accessed via SSH
|
# 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
|
* Remote: Install git, emsdk, and althttpd
|
||||||
* Use a [version of althttpd][althttpd] from
|
* 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: Install the SQLite source tree. CD to ext/wasm
|
||||||
* Remote: "`make`" to build WASM
|
* Remote: "`make`" to build WASM
|
||||||
* Remote: `althttpd --enable-sab --port 8080 --popup`
|
* 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
|
* 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),
|
In order to enable [SharedArrayBuffer][], the web-browser requires
|
||||||
the web-browser requires that the two extra Cross-Origin lines be present
|
that the two extra Cross-Origin lines be present in HTTP reply headers
|
||||||
in HTTP reply headers and that the request must come from "localhost".
|
and that the request must come from "localhost" (_or_ over an SSL
|
||||||
Since the web-server is on a different machine from
|
connection). Since the web-server is on a different machine from the
|
||||||
the web-broser, the localhost requirement means that the connection must be tunneled
|
web-broser, the localhost requirement means that the connection must
|
||||||
using SSH.
|
be tunneled using SSH.
|
||||||
|
|
||||||
|
|
||||||
[emscripten]: https://emscripten.org
|
[emscripten]: https://emscripten.org
|
||||||
[althttpd]: https://sqlite.org/althttpd
|
[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`
|
helpers for use by downstream code which creates `sqlite3_vfs`
|
||||||
and `sqlite3_module` implementations.
|
and `sqlite3_module` implementations.
|
||||||
- **`sqlite3-vfs-opfs.c-pp.js`**\
|
- **`sqlite3-vfs-opfs.c-pp.js`**\
|
||||||
is an sqlite3 VFS implementation which supports Google Chrome's
|
is an sqlite3 VFS implementation which supports the Origin-Private
|
||||||
Origin-Private FileSystem (OPFS) as a storage layer to provide
|
FileSystem (OPFS) as a storage layer to provide persistent storage
|
||||||
persistent storage for database files in a browser. It requires...
|
for database files in a browser. It requires...
|
||||||
- **`sqlite3-opfs-async-proxy.js`**\
|
- **`sqlite3-opfs-async-proxy.js`**\
|
||||||
is the asynchronous backend part of the OPFS proxy. It speaks
|
is the asynchronous backend part of the OPFS proxy. It speaks
|
||||||
directly to the (async) OPFS API and channels those results back
|
directly to the (async) OPFS API and channels those results back
|
||||||
to its synchronous counterpart. This file, because it must be
|
to its synchronous counterpart. This file, because it must be
|
||||||
started in its own Worker, is not part of the amalgamation.
|
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
|
The previous files do not immediately extend the library. Instead
|
||||||
they add callback functions to be called during its
|
they add callback functions to be called during its
|
||||||
bootstrapping. Some also temporarily create global objects in order
|
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
|
with `c-pp`](#c-pp), noting that such preprocessing may be applied
|
||||||
after all of the relevant files are concatenated. That extension is
|
after all of the relevant files are concatenated. That extension is
|
||||||
used primarily to keep the code maintainers cognisant of the fact that
|
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
|
The build process glues those files together, resulting in
|
||||||
`sqlite3-api.js`, which is everything except for the `post-js-*.js`
|
`sqlite3-api.js`, which is everything except for the
|
||||||
files, and `sqlite3.js`, which is the Emscripten-generated amalgamated
|
`pre/post-js-*.js` files, and `sqlite3.js`, which is the
|
||||||
output and includes the `post-js-*.js` parts, as well as the
|
Emscripten-generated amalgamated output and includes the
|
||||||
Emscripten-provided module loading pieces.
|
`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
|
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
|
`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
|
Certain files in the build require preprocessing to filter in/out
|
||||||
parts which differ between vanilla JS builds and ES6 Module
|
parts which differ between vanilla JS, ES6 Modules, and node.js
|
||||||
(a.k.a. esm) builds. The preprocessor application itself is in
|
builds. The preprocessor application itself is in
|
||||||
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
|
[`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details
|
||||||
of such preprocessing are maintained in
|
of such preprocessing are maintained in
|
||||||
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
|
[`GNUMakefile`](/file/ext/wasm/GNUmakefile).
|
||||||
|
@@ -23,10 +23,7 @@ const toExportForESM =
|
|||||||
impls which Emscripten installs at some point in the file above
|
impls which Emscripten installs at some point in the file above
|
||||||
this.
|
this.
|
||||||
*/
|
*/
|
||||||
const originalInit =
|
const originalInit = sqlite3InitModule;
|
||||||
/* Maintenance reminder: DO NOT use `self.` here. It's correct
|
|
||||||
for non-ES6 Module cases but wrong for ES6 modules because those
|
|
||||||
resolve this symbol differently. */ sqlite3InitModule;
|
|
||||||
if(!originalInit){
|
if(!originalInit){
|
||||||
throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build.");
|
throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build.");
|
||||||
}
|
}
|
||||||
@@ -66,18 +63,16 @@ const toExportForESM =
|
|||||||
//console.warn("Using replaced sqlite3InitModule()",globalThis.location);
|
//console.warn("Using replaced sqlite3InitModule()",globalThis.location);
|
||||||
return originalInit(...args).then((EmscriptenModule)=>{
|
return originalInit(...args).then((EmscriptenModule)=>{
|
||||||
if('undefined'!==typeof WorkerGlobalScope &&
|
if('undefined'!==typeof WorkerGlobalScope &&
|
||||||
(EmscriptenModule['ENVIRONMENT_IS_PTHREAD']
|
EmscriptenModule['ENVIRONMENT_IS_PTHREAD']){
|
||||||
|| EmscriptenModule['_pthread_self']
|
|
||||||
|| 'function'===typeof threadAlert
|
|
||||||
|| globalThis?.location?.pathname?.endsWith?.('.worker.js')
|
|
||||||
)){
|
|
||||||
/** Workaround for wasmfs-generated worker, which calls this
|
/** Workaround for wasmfs-generated worker, which calls this
|
||||||
routine from each individual thread and requires that its
|
routine from each individual thread and requires that its
|
||||||
argument be returned. All of the criteria above are fragile,
|
argument be returned. The conditional criteria above are
|
||||||
based solely on inspection of the offending code, not public
|
fragile, based solely on inspection of the offending code,
|
||||||
Emscripten details. */
|
not public Emscripten details. */
|
||||||
|
//console.warn("sqlite3InitModule() returning E-module.",EmscriptenModule);
|
||||||
return EmscriptenModule;
|
return EmscriptenModule;
|
||||||
}
|
}
|
||||||
|
//console.warn("sqlite3InitModule() returning sqlite3 object.");
|
||||||
const s = EmscriptenModule.sqlite3;
|
const s = EmscriptenModule.sqlite3;
|
||||||
s.scriptInfo = initModuleState;
|
s.scriptInfo = initModuleState;
|
||||||
//console.warn("sqlite3.scriptInfo =",s.scriptInfo);
|
//console.warn("sqlite3.scriptInfo =",s.scriptInfo);
|
||||||
@@ -124,5 +119,5 @@ const toExportForESM =
|
|||||||
return globalThis.sqlite3InitModule /* required for ESM */;
|
return globalThis.sqlite3InitModule /* required for ESM */;
|
||||||
})();
|
})();
|
||||||
//#if target=es6-module
|
//#if target=es6-module
|
||||||
export default toExportForESM;
|
export { toExportForESM as default, toExportForESM as sqlite3InitModule }
|
||||||
//#endif
|
//#endif
|
||||||
|
@@ -23,7 +23,7 @@ if('undefined' !== typeof Module){ // presumably an Emscripten build
|
|||||||
const SABC = Object.assign(
|
const SABC = Object.assign(
|
||||||
Object.create(null), {
|
Object.create(null), {
|
||||||
exports: Module['asm'],
|
exports: Module['asm'],
|
||||||
memory: Module.wasmMemory /* gets set if built with -sIMPORT_MEMORY */
|
memory: Module.wasmMemory /* gets set if built with -sIMPORTED_MEMORY */
|
||||||
},
|
},
|
||||||
globalThis.sqlite3ApiConfig || {}
|
globalThis.sqlite3ApiConfig || {}
|
||||||
);
|
);
|
||||||
|
@@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
- `memory`[^1]: optional WebAssembly.Memory object, defaulting to
|
- `memory`[^1]: optional WebAssembly.Memory object, defaulting to
|
||||||
`exports.memory`. In Emscripten environments this should be set
|
`exports.memory`. In Emscripten environments this should be set
|
||||||
to `Module.wasmMemory` if the build uses `-sIMPORT_MEMORY`, or be
|
to `Module.wasmMemory` if the build uses `-sIMPORTED_MEMORY`, or be
|
||||||
left undefined/falsy to default to `exports.memory` when using
|
left undefined/falsy to default to `exports.memory` when using
|
||||||
WASM-exported memory.
|
WASM-exported memory.
|
||||||
|
|
||||||
@@ -88,12 +88,12 @@
|
|||||||
can be replaced with (e.g.) empty functions to squelch all such
|
can be replaced with (e.g.) empty functions to squelch all such
|
||||||
output.
|
output.
|
||||||
|
|
||||||
- `wasmfsOpfsDir`[^1]: As of 2022-12-17, this feature does not
|
- `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the OPFS-backed
|
||||||
currently work due to incompatible Emscripten-side changes made
|
filesystem in WASMFS-capable builds.
|
||||||
in the WASMFS+OPFS combination. This option is currently ignored.
|
|
||||||
|
|
||||||
[^1] = This property may optionally be a function, in which case this
|
|
||||||
function re-assigns calls that function to fetch the value,
|
[^1] = This property may optionally be a function, in which case
|
||||||
|
this function calls that function to fetch the value,
|
||||||
enabling delayed evaluation.
|
enabling delayed evaluation.
|
||||||
|
|
||||||
The returned object is the top-level sqlite3 namespace object.
|
The returned object is the top-level sqlite3 namespace object.
|
||||||
@@ -125,11 +125,11 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
log: console.log.bind(console),
|
log: console.log.bind(console),
|
||||||
wasmfsOpfsDir: '/opfs',
|
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
|
docs guarantee that this is false in the canonical builds. For
|
||||||
99% of purposes it doesn't matter which allocators we use, but
|
99% of purposes it doesn't matter which allocators we use, but
|
||||||
it becomes significant with, e.g., sqlite3_deserialize()
|
it becomes significant with, e.g., sqlite3_deserialize() and
|
||||||
and certain wasm.xWrap.resultAdapter()s.
|
certain wasm.xWrap.resultAdapter()s.
|
||||||
*/
|
*/
|
||||||
useStdAlloc: false
|
useStdAlloc: false
|
||||||
}, apiConfig || {});
|
}, apiConfig || {});
|
||||||
@@ -149,11 +149,6 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
config[k] = config[k]();
|
config[k] = config[k]();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
config.wasmOpfsDir =
|
|
||||||
/* 2022-12-17: WASMFS+OPFS can no longer be activated from the
|
|
||||||
main thread (aborts via a failed assert() if it's attempted),
|
|
||||||
which eliminates any(?) benefit to supporting it. */ false;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The main sqlite3 binding API gets installed into this object,
|
The main sqlite3 binding API gets installed into this object,
|
||||||
mimicking the C API as closely as we can. The numerous members
|
mimicking the C API as closely as we can. The numerous members
|
||||||
@@ -809,7 +804,7 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
|| toss3("Missing API config.exports (WASM module exports)."),
|
|| toss3("Missing API config.exports (WASM module exports)."),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
When Emscripten compiles with `-sIMPORT_MEMORY`, it
|
When Emscripten compiles with `-sIMPORTED_MEMORY`, it
|
||||||
initalizes the heap and imports it into wasm, as opposed to
|
initalizes the heap and imports it into wasm, as opposed to
|
||||||
the other way around. In this case, the memory is not
|
the other way around. In this case, the memory is not
|
||||||
available via this.exports.memory.
|
available via this.exports.memory.
|
||||||
@@ -1177,31 +1172,31 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
/** State for sqlite3_wasmfs_opfs_dir(). */
|
/** State for sqlite3_wasmfs_opfs_dir(). */
|
||||||
let __wasmfsOpfsDir = undefined;
|
let __wasmfsOpfsDir = undefined;
|
||||||
/**
|
/**
|
||||||
2022-12-17: incompatible WASMFS changes have made WASMFS+OPFS
|
|
||||||
unavailable from the main thread, which eliminates the most
|
|
||||||
significant benefit of supporting WASMFS. This function is now a
|
|
||||||
no-op which always returns a falsy value. Before that change,
|
|
||||||
this function behaved as documented below (and how it will again
|
|
||||||
if we can find a compelling reason to support it).
|
|
||||||
|
|
||||||
If the wasm environment has a WASMFS/OPFS-backed persistent
|
If the wasm environment has a WASMFS/OPFS-backed persistent
|
||||||
storage directory, its path is returned by this function. If it
|
storage directory, its path is returned by this function. If it
|
||||||
does not then it returns "" (noting that "" is a falsy value).
|
does not then it returns "" (noting that "" is a falsy value).
|
||||||
|
|
||||||
The first time this is called, this function inspects the current
|
The first time this is called, this function inspects the current
|
||||||
environment to determine whether persistence support is available
|
environment to determine whether persistence support is available
|
||||||
and, if it is, enables it (if needed).
|
and, if it is, enables it (if needed). After the first call it
|
||||||
|
always returns the cached result.
|
||||||
|
|
||||||
This function currently only recognizes the WASMFS/OPFS storage
|
If the returned string is not empty, any files stored under the
|
||||||
combination and its path refers to storage rooted in the
|
given path (recursively) are housed in OPFS storage. If the
|
||||||
Emscripten-managed virtual filesystem.
|
returned string is empty, this particular persistent storage
|
||||||
|
option is not available on the client.
|
||||||
|
|
||||||
|
Though the mount point name returned by this function is intended
|
||||||
|
to remain stable, clients should not hard-coded it anywhere. Always call this function to get the path.
|
||||||
|
|
||||||
|
Note that this function is a no-op in must builds of this
|
||||||
|
library, as the WASMFS capability requires a custom
|
||||||
|
build.
|
||||||
*/
|
*/
|
||||||
capi.sqlite3_wasmfs_opfs_dir = function(){
|
capi.sqlite3_wasmfs_opfs_dir = function(){
|
||||||
if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
|
if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir;
|
||||||
// If we have no OPFS, there is no persistent dir
|
// If we have no OPFS, there is no persistent dir
|
||||||
const pdir = config.wasmfsOpfsDir;
|
const pdir = config.wasmfsOpfsDir;
|
||||||
console.error("sqlite3_wasmfs_opfs_dir() can no longer work due "+
|
|
||||||
"to incompatible WASMFS changes. It will be removed.");
|
|
||||||
if(!pdir
|
if(!pdir
|
||||||
|| !globalThis.FileSystemHandle
|
|| !globalThis.FileSystemHandle
|
||||||
|| !globalThis.FileSystemDirectoryHandle
|
|| !globalThis.FileSystemDirectoryHandle
|
||||||
@@ -1223,8 +1218,6 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Experimental and subject to change or removal.
|
|
||||||
|
|
||||||
Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
|
Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a
|
||||||
non-empty string and the given name starts with (that string +
|
non-empty string and the given name starts with (that string +
|
||||||
'/'), else returns false.
|
'/'), else returns false.
|
||||||
@@ -1234,13 +1227,6 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
return (p && name) ? name.startsWith(p+'/') : false;
|
return (p && name) ? name.startsWith(p+'/') : false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This bit is highly arguable and is incompatible with the fiddle shell.
|
|
||||||
if(false && 0===wasm.exports.sqlite3_vfs_find(0)){
|
|
||||||
/* Assume that sqlite3_initialize() has not yet been called.
|
|
||||||
This will be the case in an SQLITE_OS_KV build. */
|
|
||||||
wasm.exports.sqlite3_initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Given an `sqlite3*`, an sqlite3_vfs name, and an optional db name
|
Given an `sqlite3*`, an sqlite3_vfs name, and an optional db name
|
||||||
(defaulting to "main"), returns a truthy value (see below) if
|
(defaulting to "main"), returns a truthy value (see below) if
|
||||||
@@ -1875,6 +1861,9 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
client: undefined,
|
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
|
Performs any optional asynchronous library-level initialization
|
||||||
which might be required. This function returns a Promise which
|
which might be required. This function returns a Promise which
|
||||||
resolves to the sqlite3 namespace object. Any error in the
|
resolves to the sqlite3 namespace object. Any error in the
|
||||||
@@ -1890,27 +1879,19 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
then it must be called by client-level code, which must not use
|
then it must be called by client-level code, which must not use
|
||||||
the library until the returned promise resolves.
|
the library until the returned promise resolves.
|
||||||
|
|
||||||
Bug: if called while a prior call is still resolving, the 2nd
|
If called multiple times it will return the same promise on
|
||||||
call will resolve prematurely, before the 1st call has finished
|
subsequent calls. The current build setup precludes that
|
||||||
resolving. The current build setup precludes that possibility,
|
possibility, so it's only a hypothetical problem if/when this
|
||||||
so it's only a hypothetical problem if/when this function
|
function ever needs to be invoked by clients.
|
||||||
ever needs to be invoked by clients.
|
|
||||||
|
|
||||||
In Emscripten-based builds, this function is called
|
In Emscripten-based builds, this function is called
|
||||||
automatically and deleted from this object.
|
automatically and deleted from this object.
|
||||||
*/
|
*/
|
||||||
asyncPostInit: async function(){
|
asyncPostInit: async function ff(){
|
||||||
let lip = sqlite3ApiBootstrap.initializersAsync;
|
if(ff.isReady instanceof Promise) return ff.isReady;
|
||||||
|
let lia = sqlite3ApiBootstrap.initializersAsync;
|
||||||
delete sqlite3ApiBootstrap.initializersAsync;
|
delete sqlite3ApiBootstrap.initializersAsync;
|
||||||
if(!lip || !lip.length) return Promise.resolve(sqlite3);
|
const postInit = async ()=>{
|
||||||
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 = ()=>{
|
|
||||||
if(!sqlite3.__isUnderTest){
|
if(!sqlite3.__isUnderTest){
|
||||||
/* Delete references to internal-only APIs which are used by
|
/* Delete references to internal-only APIs which are used by
|
||||||
some initializers. Retain them when running in test mode
|
some initializers. Retain them when running in test mode
|
||||||
@@ -1919,23 +1900,25 @@ globalThis.sqlite3ApiBootstrap = function sqlite3ApiBootstrap(
|
|||||||
/* It's conceivable that we might want to expose
|
/* It's conceivable that we might want to expose
|
||||||
StructBinder to client-side code, but it's only useful if
|
StructBinder to client-side code, but it's only useful if
|
||||||
clients build their own sqlite3.wasm which contains their
|
clients build their own sqlite3.wasm which contains their
|
||||||
one C struct types. */
|
own C struct types. */
|
||||||
delete sqlite3.StructBinder;
|
delete sqlite3.StructBinder;
|
||||||
}
|
}
|
||||||
return sqlite3;
|
return sqlite3;
|
||||||
};
|
};
|
||||||
if(1){
|
const catcher = (e)=>{
|
||||||
/* Run all initializers in sequence. The advantage is that it
|
config.error("an async sqlite3 initializer failed:",e);
|
||||||
allows us to have post-init cleanup defined outside of this
|
throw e;
|
||||||
routine at the end of the list and have it run at a
|
};
|
||||||
well-defined time. */
|
if(!lia || !lia.length){
|
||||||
let p = lip.shift();
|
return ff.isReady = postInit().catch(catcher);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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
|
scriptInfo ideally gets injected into this object by the
|
||||||
@@ -1995,7 +1978,7 @@ globalThis.sqlite3ApiBootstrap.initializers = [];
|
|||||||
specifically for initializers which are asynchronous. All entries in
|
specifically for initializers which are asynchronous. All entries in
|
||||||
this list must be either async functions, non-async functions which
|
this list must be either async functions, non-async functions which
|
||||||
return a Promise, or a Promise. Each function in the list is called
|
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 resolved value of any Promise is ignored and rejection will kill
|
||||||
the asyncPostInit() process (at an indeterminate point because all
|
the asyncPostInit() process (at an indeterminate point because all
|
||||||
|
@@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
https://developer.chrome.com/blog/sync-methods-for-accesshandles/
|
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
|
We cannot change to the sync forms at this point without breaking
|
||||||
clients who use Chrome v104-ish or higher. truncate(), getSize(),
|
clients who use Chrome v104-ish or higher. truncate(), getSize(),
|
||||||
flush(), and close() are now (as of v108) synchronous. Calling them
|
flush(), and close() are now (as of v108) synchronous. Calling them
|
||||||
|
@@ -295,7 +295,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
|
|
||||||
- If `struct.$zName` is falsy and the entry has a string-type
|
- If `struct.$zName` is falsy and the entry has a string-type
|
||||||
`name` property, `struct.$zName` is set to the C-string form of
|
`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.
|
On success returns this object. Throws on error.
|
||||||
*/
|
*/
|
||||||
|
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
|
2022-09-18
|
||||||
|
|
||||||
@@ -23,7 +24,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
|
|||||||
installOpfsVfs() returns a Promise which, on success, installs an
|
installOpfsVfs() returns a Promise which, on success, installs an
|
||||||
sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
|
sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs
|
||||||
which accept a VFS. It is intended to be called via
|
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
|
The installed VFS uses the Origin-Private FileSystem API for
|
||||||
all file storage. On error it is rejected with an exception
|
all file storage. On error it is rejected with an exception
|
||||||
@@ -101,6 +102,10 @@ const installOpfsVfs = function callee(options){
|
|||||||
options = Object.create(null);
|
options = Object.create(null);
|
||||||
}
|
}
|
||||||
const urlParams = new URL(globalThis.location.href).searchParams;
|
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){
|
if(undefined===options.verbose){
|
||||||
options.verbose = urlParams.has('opfs-verbose')
|
options.verbose = urlParams.has('opfs-verbose')
|
||||||
? (+urlParams.get('opfs-verbose') || 2) : 1;
|
? (+urlParams.get('opfs-verbose') || 2) : 1;
|
||||||
@@ -118,11 +123,11 @@ const installOpfsVfs = function callee(options){
|
|||||||
options.proxyUri = options.proxyUri();
|
options.proxyUri = options.proxyUri();
|
||||||
}
|
}
|
||||||
const thePromise = new Promise(function(promiseResolve_, promiseReject_){
|
const thePromise = new Promise(function(promiseResolve_, promiseReject_){
|
||||||
const loggers = {
|
const loggers = [
|
||||||
0:sqlite3.config.error,
|
sqlite3.config.error,
|
||||||
1:sqlite3.config.warn,
|
sqlite3.config.warn,
|
||||||
2:sqlite3.config.log
|
sqlite3.config.log
|
||||||
};
|
];
|
||||||
const logImpl = (level,...args)=>{
|
const logImpl = (level,...args)=>{
|
||||||
if(options.verbose>level) loggers[level]("OPFS syncer:",...args);
|
if(options.verbose>level) loggers[level]("OPFS syncer:",...args);
|
||||||
};
|
};
|
||||||
@@ -191,17 +196,18 @@ const installOpfsVfs = function callee(options){
|
|||||||
s.count = s.time = 0;
|
s.count = s.time = 0;
|
||||||
}
|
}
|
||||||
}/*metrics*/;
|
}/*metrics*/;
|
||||||
const opfsVfs = new sqlite3_vfs();
|
|
||||||
const opfsIoMethods = new sqlite3_io_methods();
|
const opfsIoMethods = new sqlite3_io_methods();
|
||||||
|
const opfsVfs = new sqlite3_vfs()
|
||||||
|
.addOnDispose( ()=>opfsIoMethods.dispose());
|
||||||
let promiseWasRejected = undefined;
|
let promiseWasRejected = undefined;
|
||||||
const promiseReject = (err)=>{
|
const promiseReject = (err)=>{
|
||||||
promiseWasRejected = true;
|
promiseWasRejected = true;
|
||||||
opfsVfs.dispose();
|
opfsVfs.dispose();
|
||||||
return promiseReject_(err);
|
return promiseReject_(err);
|
||||||
};
|
};
|
||||||
const promiseResolve = (value)=>{
|
const promiseResolve = ()=>{
|
||||||
promiseWasRejected = false;
|
promiseWasRejected = false;
|
||||||
return promiseResolve_(value);
|
return promiseResolve_(sqlite3);
|
||||||
};
|
};
|
||||||
const W =
|
const W =
|
||||||
//#if target=es6-bundler-friendly
|
//#if target=es6-bundler-friendly
|
||||||
@@ -235,17 +241,17 @@ const installOpfsVfs = function callee(options){
|
|||||||
? new sqlite3_vfs(pDVfs)
|
? new sqlite3_vfs(pDVfs)
|
||||||
: null /* dVfs will be null when sqlite3 is built with
|
: null /* dVfs will be null when sqlite3 is built with
|
||||||
SQLITE_OS_OTHER. */;
|
SQLITE_OS_OTHER. */;
|
||||||
|
opfsIoMethods.$iVersion = 1;
|
||||||
opfsVfs.$iVersion = 2/*yes, two*/;
|
opfsVfs.$iVersion = 2/*yes, two*/;
|
||||||
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof;
|
||||||
opfsVfs.$mxPathname = 1024/*sure, why not?*/;
|
opfsVfs.$mxPathname = 1024/*sure, why not?*/;
|
||||||
opfsVfs.$zName = wasm.allocCString("opfs");
|
opfsVfs.$zName = wasm.allocCString("opfs");
|
||||||
// All C-side memory of opfsVfs is zeroed out, but just to be explicit:
|
// All C-side memory of opfsVfs is zeroed out, but just to be explicit:
|
||||||
opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null;
|
opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null;
|
||||||
opfsVfs.ondispose = [
|
opfsVfs.addOnDispose(
|
||||||
'$zName', opfsVfs.$zName,
|
'$zName', opfsVfs.$zName,
|
||||||
'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null),
|
'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null)
|
||||||
'cleanup opfsIoMethods', ()=>opfsIoMethods.dispose()
|
);
|
||||||
];
|
|
||||||
/**
|
/**
|
||||||
Pedantic sidebar about opfsVfs.ondispose: the entries in that array
|
Pedantic sidebar about opfsVfs.ondispose: the entries in that array
|
||||||
are items to clean up when opfsVfs.dispose() is called, but in this
|
are items to clean up when opfsVfs.dispose() is called, but in this
|
||||||
@@ -298,6 +304,7 @@ const installOpfsVfs = function callee(options){
|
|||||||
lock contention to free up.
|
lock contention to free up.
|
||||||
*/
|
*/
|
||||||
state.asyncIdleWaitTime = 150;
|
state.asyncIdleWaitTime = 150;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Whether the async counterpart should log exceptions to
|
Whether the async counterpart should log exceptions to
|
||||||
the serialization channel. That produces a great deal of
|
the serialization channel. That produces a great deal of
|
||||||
@@ -832,22 +839,19 @@ const installOpfsVfs = function callee(options){
|
|||||||
/* If it turns out that we need to adjust for timezone, see:
|
/* If it turns out that we need to adjust for timezone, see:
|
||||||
https://stackoverflow.com/a/11760121/1458521 */
|
https://stackoverflow.com/a/11760121/1458521 */
|
||||||
wasm.poke(pOut, 2440587.5 + (new Date().getTime()/86400000),
|
wasm.poke(pOut, 2440587.5 + (new Date().getTime()/86400000),
|
||||||
'double');
|
'double');
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
xCurrentTimeInt64: function(pVfs,pOut){
|
xCurrentTimeInt64: function(pVfs,pOut){
|
||||||
// TODO: confirm that this calculation is correct
|
|
||||||
wasm.poke(pOut, (2440587.5 * 86400000) + new Date().getTime(),
|
wasm.poke(pOut, (2440587.5 * 86400000) + new Date().getTime(),
|
||||||
'i64');
|
'i64');
|
||||||
return 0;
|
return 0;
|
||||||
},
|
},
|
||||||
xDelete: function(pVfs, zName, doSyncDir){
|
xDelete: function(pVfs, zName, doSyncDir){
|
||||||
mTimeStart('xDelete');
|
mTimeStart('xDelete');
|
||||||
opRun('xDelete', wasm.cstrToJs(zName), doSyncDir, false);
|
const rc = opRun('xDelete', wasm.cstrToJs(zName), doSyncDir, false);
|
||||||
/* We're ignoring errors because we cannot yet differentiate
|
|
||||||
between harmless and non-harmless failures. */
|
|
||||||
mTimeEnd();
|
mTimeEnd();
|
||||||
return 0;
|
return rc;
|
||||||
},
|
},
|
||||||
xFullPathname: function(pVfs,zName,nOut,pOut){
|
xFullPathname: function(pVfs,zName,nOut,pOut){
|
||||||
/* Until/unless we have some notion of "current dir"
|
/* Until/unless we have some notion of "current dir"
|
||||||
@@ -1089,7 +1093,7 @@ const installOpfsVfs = function callee(options){
|
|||||||
propagate any exception on error, rather than returning false.
|
propagate any exception on error, rather than returning false.
|
||||||
*/
|
*/
|
||||||
opfsUtil.unlink = async function(fsEntryName, recursive = false,
|
opfsUtil.unlink = async function(fsEntryName, recursive = false,
|
||||||
throwOnError = false){
|
throwOnError = false){
|
||||||
try {
|
try {
|
||||||
const [hDir, filenamePart] =
|
const [hDir, filenamePart] =
|
||||||
await opfsUtil.getDirForFilename(fsEntryName, false);
|
await opfsUtil.getDirForFilename(fsEntryName, false);
|
||||||
@@ -1186,19 +1190,23 @@ const installOpfsVfs = function callee(options){
|
|||||||
contention. */
|
contention. */
|
||||||
sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000);
|
sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000);
|
||||||
sqlite3.capi.sqlite3_exec(oo1Db, [
|
sqlite3.capi.sqlite3_exec(oo1Db, [
|
||||||
/* Truncate journal mode is faster than delete for
|
/* As of July 2023, the PERSIST journal mode on OPFS is
|
||||||
this vfs, per speedtest1. That gap seems to have closed with
|
somewhat slower than DELETE or TRUNCATE (it was faster
|
||||||
Chrome version 108 or 109, but "persist" is very roughly 5-6%
|
before Chrome version 108 or 109). TRUNCATE and DELETE
|
||||||
faster than truncate in initial tests.
|
have very similar performance on OPFS.
|
||||||
|
|
||||||
For later analysis: Roy Hashimoto notes that TRUNCATE
|
Roy Hashimoto notes that TRUNCATE and PERSIST modes may
|
||||||
and PERSIST modes may decrease OPFS concurrency because
|
decrease OPFS concurrency because multiple connections
|
||||||
multiple connections can open the journal file in those
|
can open the journal file in those modes:
|
||||||
modes:
|
|
||||||
|
|
||||||
https://github.com/rhashimoto/wa-sqlite/issues/68
|
https://github.com/rhashimoto/wa-sqlite/issues/68
|
||||||
|
|
||||||
|
Given that, and the fact that testing has not revealed
|
||||||
|
any appreciable difference between performance of
|
||||||
|
TRUNCATE and DELETE modes on OPFS, we currently (as of
|
||||||
|
2023-07-13) default to DELETE mode.
|
||||||
*/
|
*/
|
||||||
"pragma journal_mode=persist;",
|
"pragma journal_mode=DELETE;",
|
||||||
/*
|
/*
|
||||||
This vfs benefits hugely from cache on moderate/large
|
This vfs benefits hugely from cache on moderate/large
|
||||||
speedtest1 --size 50 and --size 100 workloads. We
|
speedtest1 --size 50 and --size 100 workloads. We
|
||||||
@@ -1319,10 +1327,10 @@ const installOpfsVfs = function callee(options){
|
|||||||
sqlite3.opfs = opfsUtil;
|
sqlite3.opfs = opfsUtil;
|
||||||
opfsUtil.rootDirectory = d;
|
opfsUtil.rootDirectory = d;
|
||||||
log("End of OPFS sqlite3_vfs setup.", opfsVfs);
|
log("End of OPFS sqlite3_vfs setup.", opfsVfs);
|
||||||
promiseResolve(sqlite3);
|
promiseResolve();
|
||||||
}).catch(promiseReject);
|
}).catch(promiseReject);
|
||||||
}else{
|
}else{
|
||||||
promiseResolve(sqlite3);
|
promiseResolve();
|
||||||
}
|
}
|
||||||
}catch(e){
|
}catch(e){
|
||||||
error(e);
|
error(e);
|
||||||
@@ -1359,7 +1367,10 @@ globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{
|
|||||||
});
|
});
|
||||||
}catch(e){
|
}catch(e){
|
||||||
sqlite3.config.error("installOpfsVfs() exception:",e);
|
sqlite3.config.error("installOpfsVfs() exception:",e);
|
||||||
throw e;
|
return Promise.reject(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}/*sqlite3ApiBootstrap.initializers.push()*/);
|
}/*sqlite3ApiBootstrap.initializers.push()*/);
|
||||||
|
//#else
|
||||||
|
/* The OPFS VFS parts are elided from builds targeting node.js. */
|
||||||
|
//#endif target=node
|
||||||
|
@@ -1,69 +0,0 @@
|
|||||||
/**
|
|
||||||
Dummy function stubs to get sqlite3.c compiling with
|
|
||||||
wasi-sdk. This requires, in addition:
|
|
||||||
|
|
||||||
-D_WASI_EMULATED_MMAN -D_WASI_EMULATED_GETPID
|
|
||||||
|
|
||||||
-lwasi-emulated-getpid
|
|
||||||
*/
|
|
||||||
typedef unsigned mode_t;
|
|
||||||
int fchmod(int fd, mode_t mode);
|
|
||||||
int fchmod(int fd, mode_t mode){
|
|
||||||
return (fd && mode) ? 0 : 0;
|
|
||||||
}
|
|
||||||
typedef unsigned uid_t;
|
|
||||||
typedef uid_t gid_t;
|
|
||||||
int fchown(int fd, uid_t owner, gid_t group);
|
|
||||||
int fchown(int fd, uid_t owner, gid_t group){
|
|
||||||
return (fd && owner && group) ? 0 : 0;
|
|
||||||
}
|
|
||||||
uid_t geteuid(void);
|
|
||||||
uid_t geteuid(void){return 0;}
|
|
||||||
#if !defined(F_WRLCK)
|
|
||||||
enum {
|
|
||||||
F_WRLCK,
|
|
||||||
F_RDLCK,
|
|
||||||
F_GETLK,
|
|
||||||
F_SETLK,
|
|
||||||
F_UNLCK
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef HAVE_PREAD
|
|
||||||
|
|
||||||
#include <wasi/api.h>
|
|
||||||
#define WASM__KEEP __attribute__((used))
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**
|
|
||||||
wasi-sdk cannot build sqlite3's default VFS without at least the following
|
|
||||||
functions. They are apparently syscalls which clients have to implement or
|
|
||||||
otherwise obtain.
|
|
||||||
|
|
||||||
https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md
|
|
||||||
*/
|
|
||||||
environ_get
|
|
||||||
environ_sizes_get
|
|
||||||
clock_time_get
|
|
||||||
fd_close
|
|
||||||
fd_fdstat_get
|
|
||||||
fd_fdstat_set_flags
|
|
||||||
fd_filestat_get
|
|
||||||
fd_filestat_set_size
|
|
||||||
fd_pread
|
|
||||||
fd_prestat_get
|
|
||||||
fd_prestat_dir_name
|
|
||||||
fd_read
|
|
||||||
fd_seek
|
|
||||||
fd_sync
|
|
||||||
fd_write
|
|
||||||
path_create_directory
|
|
||||||
path_filestat_get
|
|
||||||
path_filestat_set_times
|
|
||||||
path_open
|
|
||||||
path_readlink
|
|
||||||
path_remove_directory
|
|
||||||
path_unlink_file
|
|
||||||
poll_oneoff
|
|
||||||
proc_exit
|
|
||||||
#endif
|
|
@@ -151,7 +151,7 @@
|
|||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
/* SQLITE_T... */
|
/* SQLITE_T... */
|
||||||
#ifndef SQLITE_TEMP_STORE
|
#ifndef SQLITE_TEMP_STORE
|
||||||
# define SQLITE_TEMP_STORE 3
|
# define SQLITE_TEMP_STORE 2
|
||||||
#endif
|
#endif
|
||||||
#ifndef SQLITE_THREADSAFE
|
#ifndef SQLITE_THREADSAFE
|
||||||
# define SQLITE_THREADSAFE 0
|
# define SQLITE_THREADSAFE 0
|
||||||
|
@@ -40,8 +40,41 @@ span.labeled-input {
|
|||||||
.tests-pass { background-color: green; color: white }
|
.tests-pass { background-color: green; color: white }
|
||||||
.tests-fail { background-color: red; color: yellow }
|
.tests-fail { background-color: red; color: yellow }
|
||||||
.faded { opacity: 0.5; }
|
.faded { opacity: 0.5; }
|
||||||
.group-start { color: blue; }
|
.group-start {
|
||||||
.group-end { color: blue; }
|
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 {
|
.input-wrapper {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@@ -1656,25 +1656,11 @@ globalThis.WhWasmUtilInstaller = function(target){
|
|||||||
? opt.callProxy : undefined;
|
? opt.callProxy : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** If true, the constructor emits a warning. The intent is that
|
/**
|
||||||
this be set to true after bootstrapping of the higher-level
|
Note that static class members are defined outside of the class
|
||||||
client library is complete, to warn downstream clients that
|
to work around an emcc toolchain build problem: one of the
|
||||||
they shouldn't be relying on this implemenation detail which
|
tools in emsdk v3.1.42 does not support the static keyword.
|
||||||
does not have a stable interface. */
|
*/
|
||||||
static warnOnUse = false;
|
|
||||||
|
|
||||||
/** If true, convertArg() will FuncPtrAdapter.debugOut() when it
|
|
||||||
(un)installs a function binding to/from WASM. Note that
|
|
||||||
deinstallation of bindScope=transient bindings happens
|
|
||||||
via scopedAllocPop() so will not be output. */
|
|
||||||
static debugFuncInstall = false;
|
|
||||||
|
|
||||||
/** Function used for debug output. */
|
|
||||||
static debugOut = console.debug.bind(console);
|
|
||||||
|
|
||||||
static bindScopes = [
|
|
||||||
'transient', 'context', 'singleton', 'permanent'
|
|
||||||
];
|
|
||||||
|
|
||||||
/* Dummy impl. Overwritten per-instance as needed. */
|
/* Dummy impl. Overwritten per-instance as needed. */
|
||||||
contextKey(argv,argIndex){
|
contextKey(argv,argIndex){
|
||||||
@@ -1761,6 +1747,26 @@ globalThis.WhWasmUtilInstaller = function(target){
|
|||||||
}/*convertArg()*/
|
}/*convertArg()*/
|
||||||
}/*FuncPtrAdapter*/;
|
}/*FuncPtrAdapter*/;
|
||||||
|
|
||||||
|
/** If true, the constructor emits a warning. The intent is that
|
||||||
|
this be set to true after bootstrapping of the higher-level
|
||||||
|
client library is complete, to warn downstream clients that
|
||||||
|
they shouldn't be relying on this implemenation detail which
|
||||||
|
does not have a stable interface. */
|
||||||
|
xArg.FuncPtrAdapter.warnOnUse = false;
|
||||||
|
|
||||||
|
/** If true, convertArg() will FuncPtrAdapter.debugOut() when it
|
||||||
|
(un)installs a function binding to/from WASM. Note that
|
||||||
|
deinstallation of bindScope=transient bindings happens
|
||||||
|
via scopedAllocPop() so will not be output. */
|
||||||
|
xArg.FuncPtrAdapter.debugFuncInstall = false;
|
||||||
|
|
||||||
|
/** Function used for debug output. */
|
||||||
|
xArg.FuncPtrAdapter.debugOut = console.debug.bind(console);
|
||||||
|
|
||||||
|
xArg.FuncPtrAdapter.bindScopes = [
|
||||||
|
'transient', 'context', 'singleton', 'permanent'
|
||||||
|
];
|
||||||
|
|
||||||
const __xArgAdapterCheck =
|
const __xArgAdapterCheck =
|
||||||
(t)=>xArg.get(t) || toss("Argument adapter not found:",t);
|
(t)=>xArg.get(t) || toss("Argument adapter not found:",t);
|
||||||
|
|
||||||
|
@@ -38,7 +38,7 @@ dist-name := $(dist-name-prefix)-TEMP
|
|||||||
# date. Our general policy is that we want the smallest binaries for
|
# 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
|
# dist zip files, so use the oz build unless there is a compelling
|
||||||
# reason not to.
|
# reason not to.
|
||||||
dist.build ?= qoz
|
dist.build ?= oz
|
||||||
|
|
||||||
dist-dir.top := $(dist-name)
|
dist-dir.top := $(dist-name)
|
||||||
dist-dir.jswasm := $(dist-dir.top)/$(notdir $(dir.dout))
|
dist-dir.jswasm := $(dist-dir.top)/$(notdir $(dir.dout))
|
||||||
|
@@ -93,9 +93,13 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a href='speedtest1.html'>speedtest1</a>: a main-thread WASM build of speedtest1.</li>
|
<li><a href='speedtest1.html'>speedtest1</a>: a main-thread WASM build of speedtest1.</li>
|
||||||
<li><a href='speedtest1.html?vfs=kvvfs'>speedtest1?vfs=kvvfs</a>: speedtest1 with the kvvfs.</li>
|
<li><a href='speedtest1.html?vfs=kvvfs'>speedtest1?vfs=kvvfs</a>: speedtest1 with the kvvfs.</li>
|
||||||
<li><a href='speedtest1-worker.html?size=25'>speedtest1-worker</a>: an interactive Worker-thread variant of speedtest1.</li>
|
<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=25'>speedtest1-worker?vfs=opfs</a>: speedtest1-worker with the
|
<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>
|
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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>The obligatory "misc." category...
|
<li>The obligatory "misc." category...
|
||||||
@@ -117,18 +121,19 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<!--li>WASMFS-specific tests which currently do not work due to incompatible changes
|
<li><strong>WASMFS</strong>-specific tests which require that
|
||||||
made to the WASMFS+OPFS combination.
|
the WASMFS build is available on this server (it is not by
|
||||||
|
default) and that this server emits the COOP/COEP headers.
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href='speedtest1-wasmfs.html?flags=--size,25'>speedtest1-wasmfs</a>:
|
<li><a href='scratchpad-wasmfs.html'>scratchpad-wasmfs</a>:
|
||||||
|
experimenting with WASMFS/OPFS-based persistence.
|
||||||
|
</li>
|
||||||
|
<li><a href='speedtest1-wasmfs.html?flags=--size,15'>speedtest1-wasmfs</a>:
|
||||||
a variant of speedtest1 built solely for the wasmfs/opfs
|
a variant of speedtest1 built solely for the wasmfs/opfs
|
||||||
feature.</li>
|
feature.
|
||||||
<li><a href='scratchpad-wasmfs-main.html'>scratchpad-wasmfs-main</a>:
|
</li>
|
||||||
experimenting with WASMFS/OPFS-based persistence. Maintenance
|
|
||||||
reminder: we cannot currently (2022-09-15) load WASMFS in a
|
|
||||||
worker due to an Emscripten wasm loader limitation.</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li-->
|
</li>
|
||||||
<!--li><a href='x.html'></a></li-->
|
<!--li><a href='x.html'></a></li-->
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,70 +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.
|
|
||||||
|
|
||||||
***********************************************************************
|
|
||||||
|
|
||||||
A basic test script for sqlite3-api.js. This file must be run in
|
|
||||||
main JS thread and sqlite3.js must have been loaded before it.
|
|
||||||
*/
|
|
||||||
'use strict';
|
|
||||||
(function(){
|
|
||||||
const toss = function(...args){throw new Error(args.join(' '))};
|
|
||||||
const log = console.log.bind(console),
|
|
||||||
warn = console.warn.bind(console),
|
|
||||||
error = console.error.bind(console);
|
|
||||||
|
|
||||||
const stdout = log;
|
|
||||||
const stderr = error;
|
|
||||||
|
|
||||||
const test1 = function(db){
|
|
||||||
db.exec("create table if not exists t(a);")
|
|
||||||
.transaction(function(db){
|
|
||||||
db.prepare("insert into t(a) values(?)")
|
|
||||||
.bind(new Date().getTime())
|
|
||||||
.stepFinalize();
|
|
||||||
stdout("Number of values in table t:",
|
|
||||||
db.selectValue("select count(*) from t"));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const runTests = function(sqlite3){
|
|
||||||
const capi = sqlite3.capi,
|
|
||||||
oo = sqlite3.oo1,
|
|
||||||
wasm = sqlite3.wasm;
|
|
||||||
stdout("Loaded sqlite3:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
|
|
||||||
const persistentDir = capi.sqlite3_wasmfs_opfs_dir();
|
|
||||||
if(persistentDir){
|
|
||||||
stdout("Persistent storage dir:",persistentDir);
|
|
||||||
}else{
|
|
||||||
stderr("No persistent storage available.");
|
|
||||||
}
|
|
||||||
const startTime = performance.now();
|
|
||||||
let db;
|
|
||||||
try {
|
|
||||||
db = new oo.DB(persistentDir+'/foo.db');
|
|
||||||
stdout("DB filename:",db.filename);
|
|
||||||
const banner1 = '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',
|
|
||||||
banner2 = '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<';
|
|
||||||
[
|
|
||||||
test1
|
|
||||||
].forEach((f)=>{
|
|
||||||
const n = performance.now();
|
|
||||||
stdout(banner1,"Running",f.name+"()...");
|
|
||||||
f(db, sqlite3);
|
|
||||||
stdout(banner2,f.name+"() took ",(performance.now() - n),"ms");
|
|
||||||
});
|
|
||||||
}finally{
|
|
||||||
if(db) db.close();
|
|
||||||
}
|
|
||||||
stdout("Total test time:",(performance.now() - startTime),"ms");
|
|
||||||
};
|
|
||||||
|
|
||||||
sqlite3InitModule(self.sqlite3TestModule).then(runTests);
|
|
||||||
})();
|
|
@@ -10,20 +10,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header id='titlebar'><span>sqlite3 WASMFS/OPFS Main-thread Scratchpad</span></header>
|
<header id='titlebar'><span>sqlite3 WASMFS/OPFS Main-thread Scratchpad</span></header>
|
||||||
<!-- emscripten bits -->
|
|
||||||
<figure id="module-spinner">
|
|
||||||
<div class="spinner"></div>
|
|
||||||
<div class='center'><strong>Initializing app...</strong></div>
|
|
||||||
<div class='center'>
|
|
||||||
On a slow internet connection this may take a moment. If this
|
|
||||||
message displays for "a long time", intialization may have
|
|
||||||
failed and the JavaScript console may contain clues as to why.
|
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
<div class="emscripten" id="module-status">Downloading...</div>
|
|
||||||
<div class="emscripten">
|
|
||||||
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
|
|
||||||
</div><!-- /emscripten bits -->
|
|
||||||
<p>Scratchpad/test app for the WASMF/OPFS integration in the
|
<p>Scratchpad/test app for the WASMF/OPFS integration in the
|
||||||
main window thread. This page requires that the sqlite3 API have
|
main window thread. This page requires that the sqlite3 API have
|
||||||
been built with WASMFS support. If OPFS support is available then
|
been built with WASMFS support. If OPFS support is available then
|
||||||
@@ -33,8 +19,12 @@
|
|||||||
<p>All stuff on this page happens in the dev console.</p>
|
<p>All stuff on this page happens in the dev console.</p>
|
||||||
<hr>
|
<hr>
|
||||||
<div id='test-output'></div>
|
<div id='test-output'></div>
|
||||||
<script src="sqlite3-wasmfs.js"></script>
|
<script>
|
||||||
<script src="common/SqliteTestUtil.js"></script>
|
(function(){
|
||||||
<script src="scratchpad-wasmfs-main.js"></script>
|
const W = new Worker('scratchpad-wasmfs.mjs',{
|
||||||
|
type: 'module'
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
70
ext/wasm/scratchpad-wasmfs.mjs
Normal file
70
ext/wasm/scratchpad-wasmfs.mjs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
2022-05-22
|
||||||
|
|
||||||
|
The author disclaims copyright to this source code. In place of a
|
||||||
|
legal notice, here is a blessing:
|
||||||
|
|
||||||
|
* May you do good and not evil.
|
||||||
|
* May you find forgiveness for yourself and forgive others.
|
||||||
|
* May you share freely, never taking more than you give.
|
||||||
|
|
||||||
|
***********************************************************************
|
||||||
|
|
||||||
|
A basic test script for sqlite3-api.js. This file must be run in
|
||||||
|
main JS thread and sqlite3.js must have been loaded before it.
|
||||||
|
*/
|
||||||
|
import sqlite3InitModule from './jswasm/sqlite3-wasmfs.mjs';
|
||||||
|
//console.log('sqlite3InitModule =',sqlite3InitModule);
|
||||||
|
const toss = function(...args){throw new Error(args.join(' '))};
|
||||||
|
const log = console.log.bind(console),
|
||||||
|
warn = console.warn.bind(console),
|
||||||
|
error = console.error.bind(console);
|
||||||
|
|
||||||
|
const stdout = log;
|
||||||
|
const stderr = error;
|
||||||
|
|
||||||
|
const test1 = function(db){
|
||||||
|
db.exec("create table if not exists t(a);")
|
||||||
|
.transaction(function(db){
|
||||||
|
db.prepare("insert into t(a) values(?)")
|
||||||
|
.bind(new Date().getTime())
|
||||||
|
.stepFinalize();
|
||||||
|
stdout("Number of values in table t:",
|
||||||
|
db.selectValue("select count(*) from t"));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const runTests = function(sqlite3){
|
||||||
|
const capi = sqlite3.capi,
|
||||||
|
oo = sqlite3.oo1,
|
||||||
|
wasm = sqlite3.wasm;
|
||||||
|
stdout("Loaded module:",sqlite3);
|
||||||
|
stdout("Loaded sqlite3:",capi.sqlite3_libversion(), capi.sqlite3_sourceid());
|
||||||
|
const persistentDir = capi.sqlite3_wasmfs_opfs_dir();
|
||||||
|
if(persistentDir){
|
||||||
|
stdout("Persistent storage dir:",persistentDir);
|
||||||
|
}else{
|
||||||
|
stderr("No persistent storage available.");
|
||||||
|
}
|
||||||
|
const startTime = performance.now();
|
||||||
|
let db;
|
||||||
|
try {
|
||||||
|
db = new oo.DB(persistentDir+'/foo.db');
|
||||||
|
stdout("DB filename:",db.filename);
|
||||||
|
const banner1 = '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>',
|
||||||
|
banner2 = '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<';
|
||||||
|
[
|
||||||
|
test1
|
||||||
|
].forEach((f)=>{
|
||||||
|
const n = performance.now();
|
||||||
|
stdout(banner1,"Running",f.name+"()...");
|
||||||
|
f(db, sqlite3);
|
||||||
|
stdout(banner2,f.name+"() took ",(performance.now() - n),"ms");
|
||||||
|
});
|
||||||
|
}finally{
|
||||||
|
if(db) db.close();
|
||||||
|
}
|
||||||
|
stdout("Total test time:",(performance.now() - startTime),"ms");
|
||||||
|
};
|
||||||
|
|
||||||
|
sqlite3InitModule().then(runTests);
|
@@ -10,141 +10,46 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header id='titlebar'><span>speedtest1-wasmfs.wasm</span></header>
|
<header id='titlebar'><span>speedtest1-wasmfs.wasm</span></header>
|
||||||
<div>See also: <a href='speedtest1-worker.html'>A Worker-thread variant of this page.</a></div>
|
<div>See also: <a href='speedtest1-worker.html'>speedtest1-worker</a></div>
|
||||||
<!-- emscripten bits -->
|
|
||||||
<figure id="module-spinner">
|
|
||||||
<div class="spinner"></div>
|
|
||||||
<div class='center'><strong>Initializing app...</strong></div>
|
|
||||||
<div class='center'>
|
|
||||||
On a slow internet connection this may take a moment. If this
|
|
||||||
message displays for "a long time", intialization may have
|
|
||||||
failed and the JavaScript console may contain clues as to why.
|
|
||||||
</div>
|
|
||||||
</figure>
|
|
||||||
<div class="emscripten" id="module-status">Downloading...</div>
|
|
||||||
<div class="emscripten">
|
|
||||||
<progress value="0" max="100" id="module-progress" hidden='1'></progress>
|
|
||||||
</div><!-- /emscripten bits -->
|
|
||||||
<div class='warning'>This page starts running the main exe when it loads, which will
|
|
||||||
block the UI until it finishes! Adding UI controls to manually configure and start it
|
|
||||||
are TODO.</div>
|
|
||||||
</div>
|
|
||||||
<div class='warning'>Achtung: running it with the dev tools open may
|
<div class='warning'>Achtung: running it with the dev tools open may
|
||||||
<em>drastically</em> slow it down. For faster results, keep the dev
|
<em>drastically</em> slow it down. For faster results, keep the dev
|
||||||
tools closed when running it!
|
tools closed when running it!
|
||||||
</div>
|
</div>
|
||||||
<div>Output is delayed/buffered because we cannot update the UI while the
|
|
||||||
speedtest is running. Output will appear below when ready...
|
|
||||||
<div id='test-output'></div>
|
<div id='test-output'></div>
|
||||||
<script src="common/SqliteTestUtil.js"></script>
|
<script>
|
||||||
<script src="speedtest1-wasmfs.js"></script>
|
(function(){
|
||||||
<script>(function(){
|
const eOut = document.querySelector('#test-output');
|
||||||
/**
|
const log2 = function(cssClass,...args){
|
||||||
If this environment contains OPFS, this function initializes it and
|
const ln = document.createElement('div');
|
||||||
returns the name of the dir on which OPFS is mounted, else it returns
|
if(cssClass) ln.classList.add(cssClass);
|
||||||
an empty string.
|
ln.append(document.createTextNode(args.join(' ')));
|
||||||
*/
|
eOut.append(ln);
|
||||||
const wasmfsDir = function f(wasmUtil,dirName="/opfs"){
|
//this.e.output.lastElementChild.scrollIntoViewIfNeeded();
|
||||||
if(undefined !== f._) return f._;
|
};
|
||||||
if( !self.FileSystemHandle
|
/* can't update DOM while speedtest is running unless we run
|
||||||
|| !self.FileSystemDirectoryHandle
|
speedtest in a worker thread. */;
|
||||||
|| !self.FileSystemFileHandle){
|
const log = (...args)=>{
|
||||||
return f._ = "";
|
console.log(...args);
|
||||||
}
|
log2('',...args);
|
||||||
try{
|
};
|
||||||
if(0===wasmUtil.xCallWrapped(
|
const logErr = function(...args){
|
||||||
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], dirName
|
console.error(...args);
|
||||||
)){
|
log2('error',...args);
|
||||||
return f._ = dirName;
|
};
|
||||||
}else{
|
const W = new Worker(
|
||||||
return f._ = "";
|
'speedtest1-wasmfs.mjs'+globalThis.location.search,{
|
||||||
}
|
type: 'module'
|
||||||
}catch(e){
|
});
|
||||||
// sqlite3_wasm_init_wasmfs() is not available
|
log("Starting up...");
|
||||||
return f._ = "";
|
W.onmessage = function({data}){
|
||||||
}
|
switch(data.type){
|
||||||
};
|
case 'log': log(...data.args); break;
|
||||||
wasmfsDir._ = undefined;
|
case 'logErr': logErr(...data.args); break;
|
||||||
|
default:
|
||||||
const eOut = document.querySelector('#test-output');
|
break;
|
||||||
const log2 = function(cssClass,...args){
|
}
|
||||||
const ln = document.createElement('div');
|
};
|
||||||
if(cssClass) ln.classList.add(cssClass);
|
})();
|
||||||
ln.append(document.createTextNode(args.join(' ')));
|
</script>
|
||||||
eOut.append(ln);
|
|
||||||
//this.e.output.lastElementChild.scrollIntoViewIfNeeded();
|
|
||||||
};
|
|
||||||
const logList = [];
|
|
||||||
const dumpLogList = function(){
|
|
||||||
logList.forEach((v)=>log2('',v));
|
|
||||||
logList.length = 0;
|
|
||||||
};
|
|
||||||
/* can't update DOM while speedtest is running unless we run
|
|
||||||
speedtest in a worker thread. */;
|
|
||||||
const log = (...args)=>{
|
|
||||||
console.log(...args);
|
|
||||||
logList.push(args.join(' '));
|
|
||||||
};
|
|
||||||
const logErr = function(...args){
|
|
||||||
console.error(...args);
|
|
||||||
logList.push('ERROR: '+args.join(' '));
|
|
||||||
};
|
|
||||||
|
|
||||||
const runTests = function(sqlite3){
|
|
||||||
console.log("Module inited.");
|
|
||||||
const wasm = sqlite3.wasm;
|
|
||||||
const __unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["*","string"]);
|
|
||||||
const unlink = (fn)=>__unlink(0,fn);
|
|
||||||
const pDir = wasmfsDir(wasm);
|
|
||||||
if(pDir) log2('',"Persistent storage:",pDir);
|
|
||||||
else{
|
|
||||||
log2('error',"Expecting persistent storage in this build.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const scope = wasm.scopedAllocPush();
|
|
||||||
const dbFile = pDir+"/speedtest1.db";
|
|
||||||
const urlParams = new URL(self.location.href).searchParams;
|
|
||||||
const argv = ["speedtest1"];
|
|
||||||
if(urlParams.has('flags')){
|
|
||||||
argv.push(...(urlParams.get('flags').split(',')));
|
|
||||||
let i = argv.indexOf('--vfs');
|
|
||||||
if(i>=0) argv.splice(i,2);
|
|
||||||
}else{
|
|
||||||
argv.push(
|
|
||||||
"--singlethread",
|
|
||||||
"--nomutex",
|
|
||||||
"--nosync",
|
|
||||||
"--nomemstat"
|
|
||||||
);
|
|
||||||
//"--memdb", // note that memdb trumps the filename arg
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argv.indexOf('--memdb')>=0){
|
|
||||||
log2('error',"WARNING: --memdb flag trumps db filename.");
|
|
||||||
}
|
|
||||||
argv.push("--big-transactions"/*important for tests 410 and 510!*/,
|
|
||||||
dbFile);
|
|
||||||
console.log("argv =",argv);
|
|
||||||
// These log messages are not emitted to the UI until after main() returns. Fixing that
|
|
||||||
// requires moving the main() call and related cleanup into a timeout handler.
|
|
||||||
if(pDir) unlink(dbFile);
|
|
||||||
log2('',"Starting native app:\n ",argv.join(' '));
|
|
||||||
log2('',"This will take a while and the browser might warn about the runaway JS.",
|
|
||||||
"Give it time...");
|
|
||||||
logList.length = 0;
|
|
||||||
setTimeout(function(){
|
|
||||||
wasm.xCall('wasm_main', argv.length,
|
|
||||||
wasm.scopedAllocMainArgv(argv));
|
|
||||||
wasm.scopedAllocPop(scope);
|
|
||||||
if(pDir) unlink(dbFile);
|
|
||||||
logList.unshift("Done running native main(). Output:");
|
|
||||||
dumpLogList();
|
|
||||||
}, 25);
|
|
||||||
}/*runTests()*/;
|
|
||||||
|
|
||||||
self.sqlite3TestModule.print = log;
|
|
||||||
self.sqlite3TestModule.printErr = logErr;
|
|
||||||
sqlite3InitModule(self.sqlite3TestModule).then(runTests);
|
|
||||||
})();</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
90
ext/wasm/speedtest1-wasmfs.mjs
Normal file
90
ext/wasm/speedtest1-wasmfs.mjs
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import sqlite3InitModule from './jswasm/speedtest1-wasmfs.mjs';
|
||||||
|
const wMsg = (type,...args)=>{
|
||||||
|
postMessage({type, args});
|
||||||
|
};
|
||||||
|
wMsg('log',"speedtest1-wasmfs starting...");
|
||||||
|
/**
|
||||||
|
If this environment contains OPFS, this function initializes it and
|
||||||
|
returns the name of the dir on which OPFS is mounted, else it returns
|
||||||
|
an empty string.
|
||||||
|
*/
|
||||||
|
const wasmfsDir = function f(wasmUtil,dirName="/opfs"){
|
||||||
|
if(undefined !== f._) return f._;
|
||||||
|
if( !self.FileSystemHandle
|
||||||
|
|| !self.FileSystemDirectoryHandle
|
||||||
|
|| !self.FileSystemFileHandle){
|
||||||
|
return f._ = "";
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
if(0===wasmUtil.xCallWrapped(
|
||||||
|
'sqlite3_wasm_init_wasmfs', 'i32', ['string'], dirName
|
||||||
|
)){
|
||||||
|
return f._ = dirName;
|
||||||
|
}else{
|
||||||
|
return f._ = "";
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
// sqlite3_wasm_init_wasmfs() is not available
|
||||||
|
return f._ = "";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wasmfsDir._ = undefined;
|
||||||
|
|
||||||
|
const log = (...args)=>wMsg('log',...args);
|
||||||
|
const logErr = (...args)=>wMsg('logErr',...args);
|
||||||
|
|
||||||
|
const runTests = function(sqlite3){
|
||||||
|
console.log("Module inited.",sqlite3);
|
||||||
|
const wasm = sqlite3.wasm;
|
||||||
|
const __unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["*","string"]);
|
||||||
|
const unlink = (fn)=>__unlink(0,fn);
|
||||||
|
const pDir = wasmfsDir(wasm);
|
||||||
|
if(pDir) log("Persistent storage:",pDir);
|
||||||
|
else{
|
||||||
|
logErr("Expecting persistent storage in this build.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const scope = wasm.scopedAllocPush();
|
||||||
|
const dbFile = pDir+"/speedtest1.db";
|
||||||
|
const urlParams = new URL(self.location.href).searchParams;
|
||||||
|
const argv = ["speedtest1"];
|
||||||
|
if(urlParams.has('flags')){
|
||||||
|
argv.push(...(urlParams.get('flags').split(',')));
|
||||||
|
let i = argv.indexOf('--vfs');
|
||||||
|
if(i>=0) argv.splice(i,2);
|
||||||
|
}else{
|
||||||
|
argv.push(
|
||||||
|
"--singlethread",
|
||||||
|
"--nomutex",
|
||||||
|
//"--nosync",
|
||||||
|
"--nomemstat",
|
||||||
|
"--size", "10"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(argv.indexOf('--memdb')>=0){
|
||||||
|
logErr("WARNING: --memdb flag trumps db filename.");
|
||||||
|
}
|
||||||
|
argv.push("--big-transactions"/*important for tests 410 and 510!*/,
|
||||||
|
dbFile);
|
||||||
|
//log("argv =",argv);
|
||||||
|
// These log messages are not emitted to the UI until after main() returns. Fixing that
|
||||||
|
// requires moving the main() call and related cleanup into a timeout handler.
|
||||||
|
if(pDir) unlink(dbFile);
|
||||||
|
log("Starting native app:\n ",argv.join(' '));
|
||||||
|
log("This will take a while and the browser might warn about the runaway JS.",
|
||||||
|
"Give it time...");
|
||||||
|
setTimeout(function(){
|
||||||
|
if(pDir) unlink(dbFile);
|
||||||
|
wasm.xCall('wasm_main', argv.length,
|
||||||
|
wasm.scopedAllocMainArgv(argv));
|
||||||
|
wasm.scopedAllocPop(scope);
|
||||||
|
if(pDir) unlink(dbFile);
|
||||||
|
log("Done running native main()");
|
||||||
|
}, 25);
|
||||||
|
}/*runTests()*/;
|
||||||
|
|
||||||
|
sqlite3InitModule({
|
||||||
|
print: log,
|
||||||
|
printErr: logErr
|
||||||
|
}).then(runTests);
|
@@ -171,7 +171,8 @@
|
|||||||
const urlParams = new URL(self.location.href).searchParams;
|
const urlParams = new URL(self.location.href).searchParams;
|
||||||
const W = new Worker(
|
const W = new Worker(
|
||||||
"speedtest1-worker.js?sqlite3.dir=jswasm"+
|
"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){
|
const mPost = function(msgType,payload){
|
||||||
W.postMessage({type: msgType, data: payload});
|
W.postMessage({type: msgType, data: payload});
|
||||||
@@ -259,7 +260,7 @@
|
|||||||
flags["--utf16be"] = "Set text encoding to UTF-16BE";
|
flags["--utf16be"] = "Set text encoding to UTF-16BE";
|
||||||
flags["--utf16le"] = "Set text encoding to UTF-16LE";
|
flags["--utf16le"] = "Set text encoding to UTF-16LE";
|
||||||
flags["--verify"] = "Run additional verification steps.";
|
flags["--verify"] = "Run additional verification steps.";
|
||||||
flags["--without"] = "rowid Use WITHOUT ROWID where appropriate";
|
flags["--without-rowid"] = "Use WITHOUT ROWID where appropriate";
|
||||||
const preselectedFlags = [
|
const preselectedFlags = [
|
||||||
'--big-transactions',
|
'--big-transactions',
|
||||||
'--singlethread'
|
'--singlethread'
|
||||||
@@ -267,7 +268,7 @@
|
|||||||
if(urlParams.has('flags')){
|
if(urlParams.has('flags')){
|
||||||
preselectedFlags.push(...urlParams.get('flags').split(','));
|
preselectedFlags.push(...urlParams.get('flags').split(','));
|
||||||
}
|
}
|
||||||
if('opfs'!==urlParams.get('vfs')){
|
if(!urlParams.get('vfs')){
|
||||||
preselectedFlags.push('--memdb');
|
preselectedFlags.push('--memdb');
|
||||||
}
|
}
|
||||||
Object.keys(flags).sort().forEach(function(f){
|
Object.keys(flags).sort().forEach(function(f){
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
if(urlParams.has('sqlite3.dir')){
|
if(urlParams.has('sqlite3.dir')){
|
||||||
speedtestJs = urlParams.get('sqlite3.dir') + '/' + speedtestJs;
|
speedtestJs = urlParams.get('sqlite3.dir') + '/' + speedtestJs;
|
||||||
}
|
}
|
||||||
importScripts('common/whwasmutil.js', speedtestJs);
|
importScripts(speedtestJs);
|
||||||
/**
|
/**
|
||||||
If this environment contains OPFS, this function initializes it and
|
If this environment contains OPFS, this function initializes it and
|
||||||
returns the name of the dir on which OPFS is mounted, else it returns
|
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 log = (...args)=>logMsg('stdout',args);
|
||||||
const logErr = (...args)=>logMsg('stderr',args);
|
const logErr = (...args)=>logMsg('stderr',args);
|
||||||
|
|
||||||
const runSpeedtest = function(cliFlagsArray){
|
const runSpeedtest = async function(cliFlagsArray){
|
||||||
const scope = App.wasm.scopedAllocPush();
|
const scope = App.wasm.scopedAllocPush();
|
||||||
const dbFile = App.pDir+"/speedtest1.sqlite3";
|
const dbFile = App.pDir+"/speedtest1.sqlite3";
|
||||||
try{
|
try{
|
||||||
@@ -56,7 +56,28 @@
|
|||||||
"speedtest1.wasm", ...cliFlagsArray, dbFile
|
"speedtest1.wasm", ...cliFlagsArray, dbFile
|
||||||
];
|
];
|
||||||
App.logBuffer.length = 0;
|
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]);
|
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.xCall('wasm_main', argv.length,
|
||||||
App.wasm.scopedAllocMainArgv(argv));
|
App.wasm.scopedAllocMainArgv(argv));
|
||||||
}catch(e){
|
}catch(e){
|
||||||
@@ -71,20 +92,38 @@
|
|||||||
self.onmessage = function(msg){
|
self.onmessage = function(msg){
|
||||||
msg = msg.data;
|
msg = msg.data;
|
||||||
switch(msg.type){
|
switch(msg.type){
|
||||||
case 'run': runSpeedtest(msg.data || []); break;
|
case 'run':
|
||||||
|
runSpeedtest(msg.data || [])
|
||||||
|
.catch(e=>mPost('error',e));
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
logErr("Unhandled worker message type:",msg.type);
|
logErr("Unhandled worker message type:",msg.type);
|
||||||
break;
|
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 = {
|
const EmscriptenModule = {
|
||||||
print: log,
|
print: log,
|
||||||
printErr: logErr,
|
printErr: logErr,
|
||||||
setStatus: (text)=>mPost('load-status',text)
|
setStatus: (text)=>mPost('load-status',text)
|
||||||
};
|
};
|
||||||
self.sqlite3InitModule(EmscriptenModule).then((sqlite3)=>{
|
log("Initializing speedtest1 module...");
|
||||||
const S = sqlite3;
|
self.sqlite3InitModule(EmscriptenModule).then(async (sqlite3)=>{
|
||||||
|
const S = globalThis.S = App.sqlite3 = sqlite3;
|
||||||
|
log("Loaded speedtest1 module. Setting up...");
|
||||||
App.vfsUnlink = function(pDb, fname){
|
App.vfsUnlink = function(pDb, fname){
|
||||||
const pVfs = S.wasm.sqlite3_wasm_db_vfs(pDb, 0);
|
const pVfs = S.wasm.sqlite3_wasm_db_vfs(pDb, 0);
|
||||||
if(pVfs) S.wasm.sqlite3_wasm_vfs_unlink(pVfs, fname||0);
|
if(pVfs) S.wasm.sqlite3_wasm_vfs_unlink(pVfs, fname||0);
|
||||||
@@ -95,5 +134,7 @@
|
|||||||
//else log("Using transient storage.");
|
//else log("Using transient storage.");
|
||||||
mPost('ready',true);
|
mPost('ready',true);
|
||||||
log("Registered VFSes:", ...S.capi.sqlite3_js_vfs_list());
|
log("Registered VFSes:", ...S.capi.sqlite3_js_vfs_list());
|
||||||
|
}).catch(e=>{
|
||||||
|
logErr(e);
|
||||||
});
|
});
|
||||||
})();
|
})();
|
||||||
|
@@ -45,7 +45,7 @@
|
|||||||
*/
|
*/
|
||||||
//#if target=es6-module
|
//#if target=es6-module
|
||||||
import {default as sqlite3InitModule} from './jswasm/sqlite3.mjs';
|
import {default as sqlite3InitModule} from './jswasm/sqlite3.mjs';
|
||||||
self.sqlite3InitModule = sqlite3InitModule;
|
globalThis.sqlite3InitModule = sqlite3InitModule;
|
||||||
//#else
|
//#else
|
||||||
'use strict';
|
'use strict';
|
||||||
//#endif
|
//#endif
|
||||||
@@ -57,7 +57,7 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
*/
|
*/
|
||||||
let logClass;
|
let logClass;
|
||||||
/* Predicate for tests/groups. */
|
/* Predicate for tests/groups. */
|
||||||
const isUIThread = ()=>(self.window===self && self.document);
|
const isUIThread = ()=>(globalThis.window===self && globalThis.document);
|
||||||
/* Predicate for tests/groups. */
|
/* Predicate for tests/groups. */
|
||||||
const isWorker = ()=>!isUIThread();
|
const isWorker = ()=>!isUIThread();
|
||||||
/* Predicate for tests/groups. */
|
/* Predicate for tests/groups. */
|
||||||
@@ -65,6 +65,14 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
const haveWasmCTests = ()=>{
|
const haveWasmCTests = ()=>{
|
||||||
return !!wasm.exports.sqlite3_wasm_test_intptr;
|
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)=>{
|
const mapToString = (v)=>{
|
||||||
switch(typeof v){
|
switch(typeof v){
|
||||||
@@ -159,8 +167,6 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
/** Running total of the number of tests run via
|
/** Running total of the number of tests run via
|
||||||
this API. */
|
this API. */
|
||||||
counter: 0,
|
counter: 0,
|
||||||
/* Separator line for log messages. */
|
|
||||||
separator: '------------------------------------------------------------',
|
|
||||||
/**
|
/**
|
||||||
If expr is a function, it is called and its result
|
If expr is a function, it is called and its result
|
||||||
is returned, coerced to a bool, else expr, coerced to
|
is returned, coerced to a bool, else expr, coerced to
|
||||||
@@ -248,13 +254,11 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
run: async function(sqlite3){
|
run: async function(sqlite3){
|
||||||
log(TestUtil.separator);
|
|
||||||
logClass('group-start',"Group #"+this.number+':',this.name);
|
logClass('group-start',"Group #"+this.number+':',this.name);
|
||||||
const indent = ' ';
|
|
||||||
if(this.predicate){
|
if(this.predicate){
|
||||||
const p = this.predicate(sqlite3);
|
const p = this.predicate(sqlite3);
|
||||||
if(!p || 'string'===typeof p){
|
if(!p || 'string'===typeof p){
|
||||||
logClass('warning',indent,
|
logClass(['warning','skipping-group'],
|
||||||
"SKIPPING group:", p ? p : "predicate says to" );
|
"SKIPPING group:", p ? p : "predicate says to" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -266,26 +270,34 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
for(const t of this.tests){
|
for(const t of this.tests){
|
||||||
++i;
|
++i;
|
||||||
const n = this.number+"."+i;
|
const n = this.number+"."+i;
|
||||||
log(indent, n+":", t.name);
|
logClass('one-test-line', n+":", t.name);
|
||||||
if(t.predicate){
|
if(t.predicate){
|
||||||
const p = t.predicate(sqlite3);
|
const p = t.predicate(sqlite3);
|
||||||
if(!p || 'string'===typeof p){
|
if(!p || 'string'===typeof p){
|
||||||
logClass('warning',indent,
|
logClass(['warning','skipping-test'],
|
||||||
"SKIPPING:", p ? p : "predicate says to" );
|
"SKIPPING:", p ? p : "predicate says to" );
|
||||||
skipped.push( n+': '+t.name );
|
skipped.push( n+': '+t.name );
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const tc = TestUtil.counter, now = performance.now();
|
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();
|
const then = performance.now();
|
||||||
runtime += then - now;
|
runtime += then - now;
|
||||||
logClass('faded',indent, indent,
|
logClass(['faded','one-test-summary'],
|
||||||
TestUtil.counter - tc, 'assertion(s) in',
|
TestUtil.counter - tc, 'assertion(s) in',
|
||||||
roundMs(then-now),'ms');
|
roundMs(then-now),'ms');
|
||||||
}
|
}
|
||||||
logClass('green',
|
logClass(['green','group-end'],
|
||||||
"Group #"+this.number+":",(TestUtil.counter - assertCount),
|
"#"+this.number+":",
|
||||||
|
(TestUtil.counter - assertCount),
|
||||||
"assertion(s) in",roundMs(runtime),"ms");
|
"assertion(s) in",roundMs(runtime),"ms");
|
||||||
if(0 && skipped.length){
|
if(0 && skipped.length){
|
||||||
logClass('warning',"SKIPPED test(s) in group",this.number+":",skipped);
|
logClass('warning',"SKIPPED test(s) in group",this.number+":",skipped);
|
||||||
@@ -321,8 +333,7 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
await g.run(sqlite3);
|
await g.run(sqlite3);
|
||||||
runtime += performance.now() - now;
|
runtime += performance.now() - now;
|
||||||
}
|
}
|
||||||
log(TestUtil.separator);
|
logClass(['strong','green','full-test-summary'],
|
||||||
logClass(['strong','green'],
|
|
||||||
"Done running tests.",TestUtil.counter,"assertions in",
|
"Done running tests.",TestUtil.counter,"assertions in",
|
||||||
roundMs(runtime),'ms');
|
roundMs(runtime),'ms');
|
||||||
pok();
|
pok();
|
||||||
@@ -339,6 +350,11 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
T.g = T.addGroup;
|
T.g = T.addGroup;
|
||||||
T.t = T.addTest;
|
T.t = T.addTest;
|
||||||
let capi, wasm/*assigned after module init*/;
|
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...
|
// End of infrastructure setup. Now define the tests...
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -1288,7 +1304,6 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
if(1){
|
if(1){
|
||||||
const vfsList = capi.sqlite3_js_vfs_list();
|
const vfsList = capi.sqlite3_js_vfs_list();
|
||||||
T.assert(vfsList.length>1);
|
T.assert(vfsList.length>1);
|
||||||
//log("vfsList =",vfsList);
|
|
||||||
wasm.scopedAllocCall(()=>{
|
wasm.scopedAllocCall(()=>{
|
||||||
const vfsArg = (v)=>wasm.xWrap.testConvertArg('sqlite3_vfs*',v);
|
const vfsArg = (v)=>wasm.xWrap.testConvertArg('sqlite3_vfs*',v);
|
||||||
for(const v of vfsList){
|
for(const v of vfsList){
|
||||||
@@ -2615,128 +2630,6 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
}/*kvvfs sqlite3_js_vfs_create_file()*/)
|
}/*kvvfs sqlite3_js_vfs_create_file()*/)
|
||||||
;/* end kvvfs tests */
|
;/* 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.g('Hook APIs')
|
||||||
.t({
|
.t({
|
||||||
@@ -2942,8 +2835,7 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
.assert( capi.sqlite3session_enable(pSession, -1) > 0 )
|
.assert( capi.sqlite3session_enable(pSession, -1) > 0 )
|
||||||
.assert(undefined === db1.selectValue('select a from t where rowid=2'));
|
.assert(undefined === db1.selectValue('select a from t where rowid=2'));
|
||||||
}else{
|
}else{
|
||||||
warn("sqlite3session_enable() tests disabled due to unexpected results.",
|
warn("sqlite3session_enable() tests are currently disabled.");
|
||||||
"(Possibly a tester misunderstanding, as opposed to a bug.)");
|
|
||||||
}
|
}
|
||||||
let db1Count = db1.selectValue("select count(*) from t");
|
let db1Count = db1.selectValue("select count(*) from t");
|
||||||
T.assert( db1Count === (testSessionEnable ? 2 : 3) );
|
T.assert( db1Count === (testSessionEnable ? 2 : 3) );
|
||||||
@@ -3007,6 +2899,205 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
}
|
}
|
||||||
})/*session API sanity tests*/
|
})/*session API sanity tests*/
|
||||||
;/*end of session API group*/;
|
;/*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.g('Bug Reports')
|
||||||
.t({
|
.t({
|
||||||
@@ -3050,14 +3141,15 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
log("Loading and initializing sqlite3 WASM module...");
|
log("Loading and initializing sqlite3 WASM module...");
|
||||||
if(0){
|
if(0){
|
||||||
self.sqlite3ApiConfig = {
|
globalThis.sqlite3ApiConfig = {
|
||||||
debug: ()=>{},
|
debug: ()=>{},
|
||||||
log: ()=>{},
|
log: ()=>{},
|
||||||
warn: ()=>{},
|
warn: ()=>{},
|
||||||
error: ()=>{}
|
error: ()=>{}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!self.sqlite3InitModule && !isUIThread()){
|
//#ifnot target=es6-module
|
||||||
|
if(!globalThis.sqlite3InitModule && !isUIThread()){
|
||||||
/* Vanilla worker, as opposed to an ES6 module worker */
|
/* Vanilla worker, as opposed to an ES6 module worker */
|
||||||
/*
|
/*
|
||||||
If sqlite3.js is in a directory other than this script, in order
|
If sqlite3.js is in a directory other than this script, in order
|
||||||
@@ -3070,27 +3162,32 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
that's not needed.
|
that's not needed.
|
||||||
|
|
||||||
URL arguments passed as part of the filename via importScripts()
|
URL arguments passed as part of the filename via importScripts()
|
||||||
are simply lost, and such scripts see the self.location of
|
are simply lost, and such scripts see the globalThis.location of
|
||||||
_this_ script.
|
_this_ script.
|
||||||
*/
|
*/
|
||||||
let sqlite3Js = 'sqlite3.js';
|
let sqlite3Js = 'sqlite3.js';
|
||||||
const urlParams = new URL(self.location.href).searchParams;
|
const urlParams = new URL(globalThis.location.href).searchParams;
|
||||||
if(urlParams.has('sqlite3.dir')){
|
if(urlParams.has('sqlite3.dir')){
|
||||||
sqlite3Js = urlParams.get('sqlite3.dir') + '/' + sqlite3Js;
|
sqlite3Js = urlParams.get('sqlite3.dir') + '/' + sqlite3Js;
|
||||||
}
|
}
|
||||||
importScripts(sqlite3Js);
|
importScripts(sqlite3Js);
|
||||||
}
|
}
|
||||||
self.sqlite3InitModule.__isUnderTest =
|
//#endif
|
||||||
|
globalThis.sqlite3InitModule.__isUnderTest =
|
||||||
true /* disables certain API-internal cleanup so that we can
|
true /* disables certain API-internal cleanup so that we can
|
||||||
test internal APIs from here */;
|
test internal APIs from here */;
|
||||||
self.sqlite3InitModule({
|
globalThis.sqlite3InitModule({
|
||||||
print: log,
|
print: log,
|
||||||
printErr: error
|
printErr: error
|
||||||
}).then(function(sqlite3){
|
}).then(async function(sqlite3){
|
||||||
//console.log('sqlite3 =',sqlite3);
|
|
||||||
log("Done initializing WASM/JS bits. Running tests...");
|
log("Done initializing WASM/JS bits. Running tests...");
|
||||||
sqlite3.config.warn("Installing sqlite3 bits as global S for local dev/test purposes.");
|
sqlite3.config.warn("Installing sqlite3 bits as global S for local dev/test purposes.");
|
||||||
self.S = sqlite3;
|
globalThis.S = sqlite3;
|
||||||
|
/*await sqlite3.installOpfsSAHPoolVfs(sahPoolConfig)
|
||||||
|
.then((u)=>log("Loaded",u.vfsName,"VFS"))
|
||||||
|
.catch(e=>{
|
||||||
|
log("Cannot install OpfsSAHPool.",e);
|
||||||
|
});*/
|
||||||
capi = sqlite3.capi;
|
capi = sqlite3.capi;
|
||||||
wasm = sqlite3.wasm;
|
wasm = sqlite3.wasm;
|
||||||
log("sqlite3 version:",capi.sqlite3_libversion(),
|
log("sqlite3 version:",capi.sqlite3_libversion(),
|
||||||
@@ -3105,6 +3202,7 @@ self.sqlite3InitModule = sqlite3InitModule;
|
|||||||
}else{
|
}else{
|
||||||
logClass('warning',"sqlite3_wasm_test_...() APIs unavailable.");
|
logClass('warning',"sqlite3_wasm_test_...() APIs unavailable.");
|
||||||
}
|
}
|
||||||
|
log("registered vfs list =",capi.sqlite3_js_vfs_list().join(', '));
|
||||||
TestUtil.runTests(sqlite3);
|
TestUtil.runTests(sqlite3);
|
||||||
});
|
});
|
||||||
})(self);
|
})(self);
|
||||||
|
@@ -6,14 +6,10 @@
|
|||||||
# GNUMakefile.
|
# GNUMakefile.
|
||||||
########################################################################
|
########################################################################
|
||||||
MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST))
|
MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST))
|
||||||
|
$(warning The WASMFS build is currently incomplete.)
|
||||||
|
|
||||||
# Maintenance reminder: these particular files cannot be built into a
|
#dir.wasmfs := $(dir.wasm)
|
||||||
# subdirectory because loading of the auxiliary
|
dir.wasmfs := $(dir.dout)
|
||||||
# sqlite3-wasmfs.worker.js file it creates fails if sqlite3-wasmfs.js
|
|
||||||
# is loaded from any directory other than the one in which the
|
|
||||||
# containing HTML lives. Similarly, they cannot be loaded from a
|
|
||||||
# Worker to an Emscripten quirk regarding loading nested Workers.
|
|
||||||
dir.wasmfs := $(dir.wasm)
|
|
||||||
sqlite3-wasmfs.js := $(dir.wasmfs)/sqlite3-wasmfs.js
|
sqlite3-wasmfs.js := $(dir.wasmfs)/sqlite3-wasmfs.js
|
||||||
sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs
|
sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs
|
||||||
sqlite3-wasmfs.wasm := $(dir.wasmfs)/sqlite3-wasmfs.wasm
|
sqlite3-wasmfs.wasm := $(dir.wasmfs)/sqlite3-wasmfs.wasm
|
||||||
@@ -28,105 +24,92 @@ CLEAN_FILES += $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.wasm) \
|
|||||||
cflags.sqlite3-wasmfs :=
|
cflags.sqlite3-wasmfs :=
|
||||||
cflags.sqlite3-wasmfs += -std=c99 -fPIC
|
cflags.sqlite3-wasmfs += -std=c99 -fPIC
|
||||||
cflags.sqlite3-wasmfs += -pthread
|
cflags.sqlite3-wasmfs += -pthread
|
||||||
cflags.sqlite3-wasmfs += $(cflags.speedtest1)
|
cflags.sqlite3-wasmfs += -DSQLITE_ENABLE_WASMFS
|
||||||
cflags.sqlite3-wasmfs += $(SQLITE_OPT) -DSQLITE_ENABLE_WASMFS
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# emcc flags specific to building the final .js/.wasm file...
|
# emcc flags specific to building the final .js/.wasm file...
|
||||||
emcc.flags.sqlite3-wasmfs := -fPIC
|
emcc.flags.sqlite3-wasmfs :=
|
||||||
emcc.flags.sqlite3-wasmfs += --no-entry
|
emcc.flags.sqlite3-wasmfs += \
|
||||||
emcc.flags.sqlite3-wasmfs += --minify 0
|
-sEXPORTED_RUNTIME_METHODS=wasmMemory,allocateUTF8OnStack,stringToUTF8OnStack
|
||||||
emcc.flags.sqlite3-wasmfs += -sMODULARIZE
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sEXPORT_NAME=$(sqlite3.js.init-func)
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sSTRICT_JS
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sDYNAMIC_EXECUTION=0
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sNO_POLYFILL
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sWASM_BIGINT=$(emcc.WASM_BIGINT)
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sEXPORTED_FUNCTIONS=@$(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api)
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory,allocateUTF8OnStack
|
|
||||||
# wasmMemory ==> for -sIMPORTED_MEMORY
|
# wasmMemory ==> for -sIMPORTED_MEMORY
|
||||||
# allocateUTF8OnStack ==> wasmfs internals
|
# *OnStack ==> wasmfs internals (leaky abstraction)
|
||||||
emcc.flags.sqlite3-wasmfs += -sUSE_CLOSURE_COMPILER=0
|
emcc.flags.sqlite3-wasmfs += -sUSE_CLOSURE_COMPILER=0
|
||||||
emcc.flags.sqlite3-wasmfs += -Wno-limited-postlink-optimizations
|
emcc.flags.sqlite3-wasmfs += -Wno-limited-postlink-optimizations
|
||||||
# ^^^^^ it likes to warn when we have "limited optimizations" via the -g3 flag.
|
# ^^^^^ it likes to warn when we have "limited optimizations" via the -g3 flag.
|
||||||
emcc.flags.sqlite3-wasmfs += -sALLOW_TABLE_GROWTH
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sSTACK_SIZE=512KB
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sGLOBAL_BASE=4096 # HYPOTHETICALLY keep func table indexes from overlapping w/ heap addr.
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sMEMORY64=0
|
emcc.flags.sqlite3-wasmfs += -sMEMORY64=0
|
||||||
emcc.flags.sqlite3-wasmfs += -sIMPORTED_MEMORY
|
|
||||||
emcc.flags.sqlite3-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128)
|
emcc.flags.sqlite3-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128)
|
||||||
# ^^^^ 64MB is not enough for WASMFS/OPFS test runs using batch-runner.js
|
# ^^^^ 64MB is not enough for WASMFS/OPFS test runs using batch-runner.js
|
||||||
sqlite3-wasmfs.fsflags := -pthread -sWASMFS \
|
sqlite3-wasmfs.fsflags := -pthread -sWASMFS \
|
||||||
-sPTHREAD_POOL_SIZE=2 -sENVIRONMENT=web,worker \
|
-sPTHREAD_POOL_SIZE=1 \
|
||||||
-sERROR_ON_UNDEFINED_SYMBOLS=0 -sLLD_REPORT_UNDEFINED
|
-sERROR_ON_UNDEFINED_SYMBOLS=0 -sLLD_REPORT_UNDEFINED
|
||||||
# ^^^^^ why undefined symbols are necessary for the wasmfs build is anyone's guess.
|
# ^^^^^ why undefined symbols are necessary for the wasmfs build is anyone's guess.
|
||||||
emcc.flags.sqlite3-wasmfs += $(sqlite3-wasmfs.fsflags)
|
emcc.flags.sqlite3-wasmfs += $(sqlite3-wasmfs.fsflags)
|
||||||
#emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH
|
emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH=0
|
||||||
#^^^ using ALLOW_MEMORY_GROWTH produces a warning from emcc:
|
#^^^ using ALLOW_MEMORY_GROWTH produces a warning from emcc:
|
||||||
# USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly,
|
# USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly,
|
||||||
# see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth]
|
# see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth]
|
||||||
# And, indeed, it runs slowly if memory is permitted to grow.
|
# And, indeed, it runs slowly if memory is permitted to grow.
|
||||||
emcc.flags.sqlite3-wasmfs.vanilla :=
|
#emcc.flags.sqlite3-wasmfs.vanilla :=
|
||||||
emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META
|
#emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META
|
||||||
$(eval $(call call-make-pre-js,sqlite3-wasmfs,vanilla))
|
sqlite3-api.mjs.wasmfs := $(dir.tmp)/sqlite3-api-wasmfs.mjs
|
||||||
$(eval $(call call-make-pre-js,sqlite3-wasmfs,esm))
|
$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3-wasmfs,esm,1,\
|
||||||
Xemcc.flags.sqlite3-wasmfs.vanilla += \
|
$(sqlite3-api.mjs.wasmfs), $(sqlite3-wasmfs.mjs),\
|
||||||
$(pre-post-common.flags.vanilla) \
|
$(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs,\
|
||||||
$(pre-post-sqlite3-wasmfs.flags.vanilla)
|
-sEXPORT_ES6 -sUSE_ES6_IMPORT_META\
|
||||||
Xemcc.flags.sqlite3-wasmfs.esm += \
|
))
|
||||||
$(pre-post-common.flags.esm) \
|
$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs)
|
||||||
$(pre-post-sqlite3-wasmfs.flags.esm)
|
########################################################################
|
||||||
$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(sqlite3-wasm.c) \
|
# Build quirk: we cannot build BOTH .js and .mjs with our current
|
||||||
$(EXPORTED_FUNCTIONS.api) $(MAKEFILE) $(MAKEFILE.wasmfs)
|
# build infrastructure because the supplemental *.worker.js files get
|
||||||
$(sqlite3-wasmfs.js): $(pre-post-sqlite3-wasmfs.deps.vanilla)
|
# generated with the name of the main module file
|
||||||
$(sqlite3-wasmfs.mjs): $(pre-post-sqlite3-wasmfs.deps.esm)
|
# ($(sqlite3-wasmfs.{js,mjs})) hard-coded in them. Thus the last one
|
||||||
# SQLITE3-WASMFS.xJS.RECIPE is the wasmfs-specific counterpart
|
# to get built gets the *.worker.js files mapped to it. In order to
|
||||||
# of SQLITE3.xJS.RECIPE from the main makefile.
|
# build both modes they would need to have distinct base names or
|
||||||
define SQLITE3-WASMFS.xJS.RECIPE
|
# output directories. "The problem" with giving them distinct base
|
||||||
@echo "Building $@ ..."
|
# names is that it means that the corresponding .wasm file is also
|
||||||
$(emcc.bin) -o $@ $(emcc_opt_full) $(emcc.flags) \
|
# built/saved multiple times.
|
||||||
$(cflags.sqlite3-wasmfs) \
|
#
|
||||||
$(emcc.flags.sqlite3-wasmfs) $(emcc.flags.sqlite3-wasmfs.$(1)) \
|
wasmfs.build.ext := mjs
|
||||||
$(pre-post-sqlite3-wasmfs.flags.$(1)) \
|
$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(SOAP.js.bld)
|
||||||
$(sqlite3-wasm.c)
|
ifeq (js,$(wasmfs.build.ext))
|
||||||
@$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(1))
|
$(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.js)
|
||||||
chmod -x $(sqlite3-wasmfs.wasm)
|
wasmfs: $(sqlite3-wasmfs.js)
|
||||||
$(maybe-wasm-strip) $(sqlite3-wasmfs.wasm)
|
else
|
||||||
@ls -la $(sqlite3-wasmfs.wasm) sqlite3-wasmfs*js
|
$(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.mjs)
|
||||||
endef
|
wasmfs: $(sqlite3-wasmfs.mjs)
|
||||||
$(sqlite3-wasmfs.js):
|
endif
|
||||||
$(call SQLITE3-WASMFS.xJS.RECIPE,vanilla)
|
|
||||||
$(sqlite3-wasmfs.mjs): $(sqlite3-wasmfs.js)
|
|
||||||
$(call SQLITE3-WASMFS.xJS.RECIPE,esm)
|
|
||||||
$(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.js)
|
|
||||||
wasmfs: $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs)
|
|
||||||
#all: wasmfs
|
#all: wasmfs
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
# speedtest1 for wasmfs.
|
# speedtest1 for wasmfs.
|
||||||
speedtest1-wasmfs.js := $(dir.wasmfs)/speedtest1-wasmfs.js
|
speedtest1-wasmfs.mjs := $(dir.wasmfs)/speedtest1-wasmfs.mjs
|
||||||
speedtest1-wasmfs.wasm := $(subst .js,.wasm,$(speedtest1-wasmfs.js))
|
speedtest1-wasmfs.wasm := $(subst .mjs,.wasm,$(speedtest1-wasmfs.mjs))
|
||||||
emcc.flags.speedtest1-wasmfs := $(sqlite3-wasmfs.fsflags)
|
emcc.flags.speedtest1-wasmfs := $(sqlite3-wasmfs.fsflags)
|
||||||
emcc.flags.speedtest1-wasmfs += $(SQLITE_OPT) -DSQLITE_ENABLE_WASMFS
|
emcc.flags.speedtest1-wasmfs += $(SQLITE_OPT)
|
||||||
emcc.flags.speedtest1-wasmfs += -sALLOW_MEMORY_GROWTH=0
|
emcc.flags.speedtest1-wasmfs += -sALLOW_MEMORY_GROWTH=0
|
||||||
emcc.flags.speedtest1-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128)
|
emcc.flags.speedtest1-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128)
|
||||||
#$(eval $(call call-make-pre-js,speedtest1-wasmfs,vanilla))
|
#$(eval $(call call-make-pre-js,speedtest1-wasmfs,ems))
|
||||||
$(speedtest1-wasmfs.js): $(speedtest1.cses) $(sqlite3-wasmfs.js) \
|
$(speedtest1-wasmfs.mjs): $(speedtest1.cfiles) $(sqlite3-wasmfs.js) \
|
||||||
$(MAKEFILE) $(MAKEFILE.wasmfs) \
|
$(MAKEFILE) $(MAKEFILE.wasmfs) \
|
||||||
$(pre-post-sqlite3-wasmfs.deps) \
|
$(pre-post-sqlite3-wasmfs-esm.deps) \
|
||||||
$(EXPORTED_FUNCTIONS.speedtest1)
|
$(EXPORTED_FUNCTIONS.speedtest1)
|
||||||
@echo "Building $@ ..."
|
@echo "Building $@ ..."
|
||||||
$(emcc.bin) \
|
$(emcc.bin) \
|
||||||
$(emcc.speedtest1.common) $(emcc.flags.speedtest1-wasmfs) \
|
$(pre-post-sqlite3-wasmfs-esm.flags) \
|
||||||
$(pre-post-sqlite3-wasmfs.flags.vanilla) \
|
$(cflags.common) \
|
||||||
$(cflags.sqlite3-wasmfs) \
|
$(cflags.sqlite3-wasmfs) \
|
||||||
-o $@ $(speedtest1.cses) -lm
|
$(emcc.speedtest1.common) \
|
||||||
|
$(emcc.flags.speedtest1-vanilla) \
|
||||||
|
$(emcc.flags.sqlite3-wasmfs) \
|
||||||
|
$(emcc.flags.speedtest1-wasmfs) \
|
||||||
|
-o $@ $(speedtest1.cfiles) -lm
|
||||||
|
@$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1)
|
||||||
$(maybe-wasm-strip) $(speedtest1-wasmfs.wasm)
|
$(maybe-wasm-strip) $(speedtest1-wasmfs.wasm)
|
||||||
|
chmod -x $(speedtest1-wasmfs.wasm)
|
||||||
ls -la $@ $(speedtest1-wasmfs.wasm)
|
ls -la $@ $(speedtest1-wasmfs.wasm)
|
||||||
|
|
||||||
#speedtest1: $(speedtest1-wasmfs.js)
|
wasmfs: $(speedtest1-wasmfs.mjs)
|
||||||
wasmfs: $(speedtest1-wasmfs.js)
|
CLEAN_FILES += $(speedtest1-wasmfs.mjs) $(speedtest1-wasmfs.wasm) \
|
||||||
CLEAN_FILES += $(speedtest1-wasmfs.js) $(speedtest1-wasmfs.wasm) \
|
$(subst .js,.worker.js,$(speedtest1-wasmfs.mjs))
|
||||||
$(subst .js,.worker.js,$(speedtest1-wasmfs.js))
|
|
||||||
# end speedtest1.js
|
# end speedtest1.js
|
||||||
########################################################################
|
########################################################################
|
||||||
|
83
manifest
83
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Get\sfault\sinjection\sfor\stesting\sworking\scorrectly.\s\sOther\scode\sclean-up.
|
C Update\sthe\slatest\strunk\senhancements\sinto\sthe\swal-shm-exceptions\sbranch.
|
||||||
D 2023-07-11T15:52:52.116
|
D 2023-07-24T12:59:53.689
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@@ -92,7 +92,7 @@ F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b7292
|
|||||||
F ext/fts5/fts5_config.c 051056a9052f5d3a4d1c695f996fd364f920e341f136c60ab2c04aa7e267113f
|
F ext/fts5/fts5_config.c 051056a9052f5d3a4d1c695f996fd364f920e341f136c60ab2c04aa7e267113f
|
||||||
F ext/fts5/fts5_expr.c 58fb8ceddfb1cefcd54510f9f2f33c220ef9d1b3fa77462111f5ae2a825ab7b1
|
F ext/fts5/fts5_expr.c 58fb8ceddfb1cefcd54510f9f2f33c220ef9d1b3fa77462111f5ae2a825ab7b1
|
||||||
F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982
|
F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982
|
||||||
F ext/fts5/fts5_index.c fe98ebd8835760b9c787d20f6b50d648a761afd8e3b55780e718ee34c694743b
|
F ext/fts5/fts5_index.c 430d3edfc5b51d02f0671e2b8268c12bf485f7dc80db2b61c996e74814bc46b0
|
||||||
F ext/fts5/fts5_main.c b4dba04a36aaf9b8e8cef0100b6dbb422cc74753eacc11d6401cac7a87c0f38d
|
F ext/fts5/fts5_main.c b4dba04a36aaf9b8e8cef0100b6dbb422cc74753eacc11d6401cac7a87c0f38d
|
||||||
F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082
|
F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082
|
||||||
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
|
F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae
|
||||||
@@ -482,29 +482,29 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
|||||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||||
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c
|
||||||
F ext/wasm/GNUmakefile 38700d5074af690f004e4e5f3533164ab49693b9d0832929c4ecf97a0bc09494
|
F ext/wasm/GNUmakefile 4e8260d05c52d9924b853efbdfe052bd483cfe42f055567c1bbf29d274794b22
|
||||||
F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576
|
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-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab
|
||||||
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b
|
||||||
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287
|
||||||
F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54
|
F ext/wasm/api/README.md 5eb44fa02e9c693a1884a3692428647894b0380b24bca120866b7a24c8786134
|
||||||
F ext/wasm/api/extern-post-js.c-pp.js 393ab78b807da94096eae1a68bfddb999a2299936a185d910162fe87a57a9a3a
|
F ext/wasm/api/extern-post-js.c-pp.js 116749b7e55b7519129de06d3d353e19df68cfb24b12204aa4dc30c9a83023fe
|
||||||
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41
|
||||||
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
|
F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1
|
||||||
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62
|
||||||
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219
|
F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219
|
||||||
F ext/wasm/api/sqlite3-api-cleanup.js cc21e3486da748463e02bbe51e2464c6ac136587cdfd5aa00cd0b5385f6ca808
|
F ext/wasm/api/sqlite3-api-cleanup.js 23ceec5ef74a0e649b19694ca985fd89e335771e21f24f50df352a626a8c81bf
|
||||||
F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803
|
F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803
|
||||||
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
|
F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8
|
||||||
F ext/wasm/api/sqlite3-api-prologue.js 17f4ec398ba34c5c666fea8e8c4eb82064a35b302f2f2eb355283cd8d3f68ed5
|
F ext/wasm/api/sqlite3-api-prologue.js cbd7d6ba185f3a844a8b0020e954b49bbc2ca78b305d117bec2ceca21431795a
|
||||||
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
|
F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b1738645c0134562bb84e88e2fec
|
||||||
F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
|
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-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
|
||||||
F ext/wasm/api/sqlite3-v-helper.js e5c202a9ecde9ef818536d3f5faf26c03a1a9f5192b1ddea8bdabf30d75ef487
|
F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 05f2563ddebfdc7a0f0ac0eb7cb381bb72043299aae1600ba9367c12f52b3fcc
|
F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 7931b50b63246a3d6b46a4c703c28820aa10c5b1ae7c0718e1f58dae2cf6db85
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js e7a690e0e78ff4d563f2eca468f91db69f001ff4b79c6d2304cbb6f62dca437d
|
||||||
F ext/wasm/api/sqlite3-wasm.c 12a096d8e58a0af0589142bae5a3c27a0c7e19846755a1a37d2c206352fbedda
|
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-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
|
||||||
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
|
F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75
|
||||||
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
||||||
@@ -512,8 +512,8 @@ F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c2
|
|||||||
F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4
|
F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4
|
||||||
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
|
F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51
|
||||||
F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15
|
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 03407d7b61b817fd135c82401987e56688a45ee4d6b9c0eced160c0000d6e4c2
|
F ext/wasm/common/whwasmutil.js ae263dec9d7384f4c530f324b99d00516a4d6f26424372daee65031e00eb49b3
|
||||||
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed
|
||||||
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508
|
||||||
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
|
F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6
|
||||||
@@ -523,7 +523,7 @@ F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98
|
|||||||
F ext/wasm/demo-worker1-promiser.js 5e5c7d7c91cd7aae9cc733afd02569ba9c6928292db413b550e8b842f4b75e87
|
F ext/wasm/demo-worker1-promiser.js 5e5c7d7c91cd7aae9cc733afd02569ba9c6928292db413b550e8b842f4b75e87
|
||||||
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
|
F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d
|
||||||
F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef
|
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/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f
|
||||||
F ext/wasm/fiddle.make dbe36b90b8907ae28ecb9c0e9fd8389dbdaecf117ea4fb2ea33864bdfa498a94
|
F ext/wasm/fiddle.make dbe36b90b8907ae28ecb9c0e9fd8389dbdaecf117ea4fb2ea33864bdfa498a94
|
||||||
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f
|
||||||
@@ -531,15 +531,16 @@ F ext/wasm/fiddle/fiddle-worker.js 163d6139a93fab4bcb72064923df050d4e7c0ff0d8aa0
|
|||||||
F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715
|
F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715
|
||||||
F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2
|
F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2
|
||||||
F ext/wasm/index-dist.html 22379774f0ad4edcaaa8cf9c674c82e794cc557719a8addabed74eb8069d412e
|
F ext/wasm/index-dist.html 22379774f0ad4edcaaa8cf9c674c82e794cc557719a8addabed74eb8069d412e
|
||||||
F ext/wasm/index.html dd900891844caebd9cadbddd704f66bd841d7c12fd69ce5af490e2c10fb49f45
|
F ext/wasm/index.html b4e55de741be9fb7656445ea55085f703a784aebde620e1c4852fa21c1ac1c5b
|
||||||
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
|
F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54
|
||||||
F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb
|
F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb
|
||||||
F ext/wasm/module-symbols.html 841de62fc198988b8330e238c260e70ec93028b096e1a1234db31b187a899d10
|
F ext/wasm/module-symbols.html 841de62fc198988b8330e238c260e70ec93028b096e1a1234db31b187a899d10
|
||||||
F ext/wasm/scratchpad-wasmfs-main.html 20cf6f1a8f368e70d01e8c17200e3eaa90f1c8e1029186d836d14b83845fbe06
|
F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 w ext/wasm/scratchpad-wasmfs-main.html
|
||||||
F ext/wasm/scratchpad-wasmfs-main.js 4c140457f4d6da9d646a49addd91edb6e9ad1643c6c48e3258b5bce24725dc18
|
F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 w ext/wasm/scratchpad-wasmfs-main.js
|
||||||
F ext/wasm/speedtest1-wasmfs.html 7a301f4f5b6ad4f5d37fd6e7ca03a2f5d5547fd289da60a39075a93d7646d354
|
F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d
|
||||||
F ext/wasm/speedtest1-worker.html 82869822e641c1bef3ec0cd2d7d2b6a42d0b4f68a7b160fb2e1dd0b523940a9b
|
F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe
|
||||||
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/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da
|
||||||
F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
|
F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x
|
||||||
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
|
F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0
|
||||||
@@ -548,12 +549,12 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
|
|||||||
F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
|
F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
|
||||||
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
|
F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c
|
||||||
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
|
F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2
|
||||||
F ext/wasm/tester1.c-pp.js 1a05497ae2b2fcca008d43b37072f9b841e1c970c06c01eb0faf675db567bfc8
|
F ext/wasm/tester1.c-pp.js f835c9f703b562142f23a3607fa4a34cb6aece5fb5d674ea5bd7d37b0e47e104
|
||||||
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
|
F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1
|
||||||
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
|
F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
|
||||||
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
|
||||||
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
|
F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5
|
||||||
F ext/wasm/wasmfs.make cf9a68162d92ca2bcb0b9528b244cb36d5cc2d84ccc9c2d398461927d6e75aea
|
F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966f1bc16a
|
||||||
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
|
||||||
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
|
||||||
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0
|
||||||
@@ -576,7 +577,7 @@ F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4
|
|||||||
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523
|
||||||
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
|
F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645
|
||||||
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
|
F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522
|
||||||
F src/btree.c c9400cc1509116a29120dc06feb00ca7e26b5a4a6dba80758b1ba109d8fce5a4
|
F src/btree.c 2281facb0531d53fb42c03d1f32bc1b5903564d782ec5ff4ffc63171d960e2aa
|
||||||
F src/btree.h aa354b9bad4120af71e214666b35132712b8f2ec11869cb2315c52c81fad45cc
|
F src/btree.h aa354b9bad4120af71e214666b35132712b8f2ec11869cb2315c52c81fad45cc
|
||||||
F src/btreeInt.h 3b4eff7155c0cea6971dc51f62e3529934a15a6640ec607dd42a767e379cb3a9
|
F src/btreeInt.h 3b4eff7155c0cea6971dc51f62e3529934a15a6640ec607dd42a767e379cb3a9
|
||||||
F src/build.c a8ae3b32d9aa9bbd2c0e97d7c0dd80def9fbca408425de1608f57ee6f47f45f4
|
F src/build.c a8ae3b32d9aa9bbd2c0e97d7c0dd80def9fbca408425de1608f57ee6f47f45f4
|
||||||
@@ -587,17 +588,17 @@ F src/date.c f73f203b3877cef866c60ab402aec2bf89597219b60635cf50cbe3c5e4533e94
|
|||||||
F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
|
F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387
|
||||||
F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
|
F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
|
||||||
F src/delete.c cd5f5cd06ed0b6a882ec1a8c2a0d73b3cecb28479ad19e9931c4706c5e2182be
|
F src/delete.c cd5f5cd06ed0b6a882ec1a8c2a0d73b3cecb28479ad19e9931c4706c5e2182be
|
||||||
F src/expr.c 8d1656b65e26af3e34f78e947ac423f0d20c214ed25a67486e433bf16ca6b543
|
F src/expr.c ef4a81822da6f767696bd7f4b9983328af061158958138540142285a5b1181b7
|
||||||
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
|
||||||
F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36
|
F src/fkey.c a7fcbf7e66d14dbb73cf49f31489ebf66d0e6006c62b95246924a3bae9f37b36
|
||||||
F src/func.c cffa6edb4aa4865d8e237022399ba9c2b22fd11e5581efba7c5b524b525952ca
|
F src/func.c cc1da67fd643a43cfe691784158ec656d8ec6d13bb17e67018b01b38b3e4f5ab
|
||||||
F src/global.c 29f56a330ed9d1b5cd9b79ac0ca36f97ac3afc730ff8bfa987b0db9e559d684d
|
F src/global.c 29f56a330ed9d1b5cd9b79ac0ca36f97ac3afc730ff8bfa987b0db9e559d684d
|
||||||
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220
|
||||||
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
||||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||||
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
||||||
F src/json.c 14c474fb1249a46eb44e878e2361f36abfe686b134039b0d1883d93d61505b4a
|
F src/json.c 46ea5566e1363f4f353db79b0378c2bf8ffdf9d4667daee3df67b14669767bed
|
||||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||||
F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
|
F src/loadext.c 176d6b2cb18a6ad73b133db17f6fc351c4d9a2d510deebdb76c22bde9cfd1465
|
||||||
F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002
|
F src/main.c 512b1d45bc556edf4471a845afb7ba79e64bd5b832ab222dc195c469534cd002
|
||||||
@@ -642,7 +643,7 @@ F src/shell.c.in d320d8a13636de06d777cc1eab981caca304e175464e98183cf4ea68d93db81
|
|||||||
F src/sqlite.h.in 6a0ffe5886af2528baff6087efb34a4915d2ff394d15df32e6e2de8524b756d2
|
F src/sqlite.h.in 6a0ffe5886af2528baff6087efb34a4915d2ff394d15df32e6e2de8524b756d2
|
||||||
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
|
||||||
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
|
||||||
F src/sqliteInt.h 002a6c3e24752d123468c5d948a80e2cd4acf01badce268f9dd98b581cd7bb96
|
F src/sqliteInt.h dcb1a885e8b6cb78df618944b89d44361a99d0fe33e1bba2c150a855f7dc5599
|
||||||
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
|
F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6
|
||||||
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
|
||||||
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
|
||||||
@@ -705,24 +706,24 @@ F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0
|
|||||||
F src/update.c 0aa36561167a7c40d01163238c297297962f31a15a8d742216b3c37cdf25f731
|
F src/update.c 0aa36561167a7c40d01163238c297297962f31a15a8d742216b3c37cdf25f731
|
||||||
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145
|
||||||
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
|
||||||
F src/util.c 161e49e88b080c2370a4990aa55f51f9edcaf8c41c3cb06cd4c37ffde1c85e6d
|
F src/util.c 987e31e45aa9a7f206b8b86b0d09dd440263b869b627931a8dace5f39638e698
|
||||||
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104
|
||||||
F src/vdbe.c 74282a947234513872a83b0bab1b8c644ece64b3e27b053ef17677c8ff9c81e0
|
F src/vdbe.c 4cda877d413a18fa07346b08d6959b3d18ce982357921e7acb9649fca2534a12
|
||||||
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
|
F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0
|
||||||
F src/vdbeInt.h 7bd49eef8f89c1a271fbf12d80a206bf56c876814c5fc6bee340f4e1907095ae
|
F src/vdbeInt.h 401813862f9d75af01bdb2ab99253ad019e9d6ddcc8058e4fa61a43e9a60d1f7
|
||||||
F src/vdbeapi.c de9703f8705afc393cc2864669ce28cf9516983c8331d59aa2b978de01634365
|
F src/vdbeapi.c dde6c4d0f87486f056b9db4d1ea185bb1d84a6839102b86e76316ba590d07cc7
|
||||||
F src/vdbeaux.c d56f179577cee110d1d60129a07d37035e85b0d39a272d7587f3dbb99b40b94a
|
F src/vdbeaux.c d56f179577cee110d1d60129a07d37035e85b0d39a272d7587f3dbb99b40b94a
|
||||||
F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce
|
F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce
|
||||||
F src/vdbemem.c cf4a1556dd5b18c071cf7c243373c29ce752eb516022e3ad49ba72f08b785033
|
F src/vdbemem.c 40afb83ed848e235848ffdd3ba25adca4ba602111b8ed3b05ae3b1b12e0eacee
|
||||||
F src/vdbesort.c 0d40dca073c94e158ead752ef4225f4fee22dee84145e8c00ca2309afb489015
|
F src/vdbesort.c 0d40dca073c94e158ead752ef4225f4fee22dee84145e8c00ca2309afb489015
|
||||||
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
|
||||||
F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac
|
F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac
|
||||||
F src/vtab.c 1ecf8c3745d29275688d583e12822fa984d421e0286b5ef50c137bc3bf6d7a64
|
F src/vtab.c 1ecf8c3745d29275688d583e12822fa984d421e0286b5ef50c137bc3bf6d7a64
|
||||||
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
|
||||||
F src/wal.c e4bfb243cc1f6f89c7fba5dd8872ae38a8c1dcc760c276dbb164edb7290072a6
|
F src/wal.c 17a7ec957bd66e46a7d6403a8d55ce92518fb382ec598a5f50e2326de0206a80
|
||||||
F src/wal.h 04a9e53121d5076f2a173b0f2facb39d33047093fee71bd3bbe6b1f6f1f5fd4b
|
F src/wal.h 04a9e53121d5076f2a173b0f2facb39d33047093fee71bd3bbe6b1f6f1f5fd4b
|
||||||
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
|
F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2
|
||||||
F src/where.c 2dc708cf8b6a691fb79f16bbc46567497ee6f991043318d421e294b2da114d93
|
F src/where.c 477fcc5e561ef169e6002499602af6b805156c2aae6b2f5c2c93ef8c1cd64768
|
||||||
F src/whereInt.h c7d19902863beadec1d04e66aca39c0bcd60b74f05f0eaa7422c7005dfc5d51a
|
F src/whereInt.h c7d19902863beadec1d04e66aca39c0bcd60b74f05f0eaa7422c7005dfc5d51a
|
||||||
F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1
|
F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1
|
||||||
F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00
|
F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00
|
||||||
@@ -1222,7 +1223,7 @@ F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ff
|
|||||||
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
|
F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946
|
||||||
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
|
F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d
|
||||||
F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa
|
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-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f
|
||||||
F test/json/json-q1.txt 335a7c8ab291d354f33b7decc9559e99a2823d4142291c4be7aa339a631f3c2d
|
F test/json/json-q1.txt 335a7c8ab291d354f33b7decc9559e99a2823d4142291c4be7aa339a631f3c2d
|
||||||
F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x
|
F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x
|
||||||
@@ -2044,8 +2045,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 4c950872c870a5968fa4cb8840cf60569a66c0e508811ee79992825ec9c02da3
|
P ff492277ed00c1f637a5b4ccd6d8193ea22f6781f90073861588a2b7d5c045b7 c1b080e39397c983c13a5e79303223827de7b4946c18a79396851ec1814782f3
|
||||||
R 966aa4944515db815a2a3b1d2b09adbd
|
R 2d227170a4d38cef4891eb7e41ae2e61
|
||||||
U drh
|
U drh
|
||||||
Z 4e4c72cb034026cb3cf7caeaeea5ca69
|
Z bee2c2751faa3281b3853d97c12aa683
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
ff492277ed00c1f637a5b4ccd6d8193ea22f6781f90073861588a2b7d5c045b7
|
3187ee3f69fc28a259ba0e951ac10a65c07ef2c3866acbefaf9544333a930cc6
|
@@ -1534,7 +1534,7 @@ static void ptrmapPutOvflPtr(MemPage *pPage, MemPage *pSrc, u8 *pCell,int *pRC){
|
|||||||
pPage->xParseCell(pPage, pCell, &info);
|
pPage->xParseCell(pPage, pCell, &info);
|
||||||
if( info.nLocal<info.nPayload ){
|
if( info.nLocal<info.nPayload ){
|
||||||
Pgno ovfl;
|
Pgno ovfl;
|
||||||
if( SQLITE_WITHIN(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
|
if( SQLITE_OVERFLOW(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){
|
||||||
testcase( pSrc!=pPage );
|
testcase( pSrc!=pPage );
|
||||||
*pRC = SQLITE_CORRUPT_BKPT;
|
*pRC = SQLITE_CORRUPT_BKPT;
|
||||||
return;
|
return;
|
||||||
@@ -8695,7 +8695,7 @@ static int balance_nonroot(
|
|||||||
assert( iOvflSpace <= (int)pBt->pageSize );
|
assert( iOvflSpace <= (int)pBt->pageSize );
|
||||||
for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){}
|
for(k=0; ALWAYS(k<NB*2) && b.ixNx[k]<=j; k++){}
|
||||||
pSrcEnd = b.apEnd[k];
|
pSrcEnd = b.apEnd[k];
|
||||||
if( SQLITE_WITHIN(pSrcEnd, pCell, pCell+sz) ){
|
if( SQLITE_OVERFLOW(pSrcEnd, pCell, pCell+sz) ){
|
||||||
rc = SQLITE_CORRUPT_BKPT;
|
rc = SQLITE_CORRUPT_BKPT;
|
||||||
goto balance_cleanup;
|
goto balance_cleanup;
|
||||||
}
|
}
|
||||||
|
@@ -4690,8 +4690,7 @@ expr_code_doover:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlite3ExprCodeExprList(pParse, pFarg, r1, 0,
|
sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR);
|
||||||
SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR);
|
|
||||||
}else{
|
}else{
|
||||||
r1 = 0;
|
r1 = 0;
|
||||||
}
|
}
|
||||||
|
@@ -1227,6 +1227,7 @@ static void charFunc(
|
|||||||
*zOut++ = 0x80 + (u8)(c & 0x3F);
|
*zOut++ = 0x80 + (u8)(c & 0x3F);
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
*zOut = 0;
|
||||||
sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
|
sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1764,11 +1765,10 @@ static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){
|
|||||||
p->ovrfl = 1;
|
p->ovrfl = 1;
|
||||||
kahanBabuskaNeumaierInit(p, p->iSum);
|
kahanBabuskaNeumaierInit(p, p->iSum);
|
||||||
p->approx = 1;
|
p->approx = 1;
|
||||||
kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0]));
|
kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else{
|
}else{
|
||||||
p->approx = 1;
|
|
||||||
if( type==SQLITE_INTEGER ){
|
if( type==SQLITE_INTEGER ){
|
||||||
kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
|
kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0]));
|
||||||
}else{
|
}else{
|
||||||
|
136
src/json.c
136
src/json.c
@@ -218,12 +218,35 @@ static int jsonGrow(JsonString *p, u32 N){
|
|||||||
|
|
||||||
/* Append N bytes from zIn onto the end of the JsonString string.
|
/* Append N bytes from zIn onto the end of the JsonString string.
|
||||||
*/
|
*/
|
||||||
static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
|
static SQLITE_NOINLINE void jsonAppendExpand(
|
||||||
if( N==0 ) return;
|
JsonString *p,
|
||||||
if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return;
|
const char *zIn,
|
||||||
|
u32 N
|
||||||
|
){
|
||||||
|
assert( N>0 );
|
||||||
|
if( jsonGrow(p,N) ) return;
|
||||||
memcpy(p->zBuf+p->nUsed, zIn, N);
|
memcpy(p->zBuf+p->nUsed, zIn, N);
|
||||||
p->nUsed += N;
|
p->nUsed += N;
|
||||||
}
|
}
|
||||||
|
static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){
|
||||||
|
if( N==0 ) return;
|
||||||
|
if( N+p->nUsed >= p->nAlloc ){
|
||||||
|
jsonAppendExpand(p,zIn,N);
|
||||||
|
}else{
|
||||||
|
memcpy(p->zBuf+p->nUsed, zIn, N);
|
||||||
|
p->nUsed += N;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){
|
||||||
|
assert( N>0 );
|
||||||
|
if( N+p->nUsed >= p->nAlloc ){
|
||||||
|
jsonAppendExpand(p,zIn,N);
|
||||||
|
}else{
|
||||||
|
memcpy(p->zBuf+p->nUsed, zIn, N);
|
||||||
|
p->nUsed += N;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Append formatted text (not to exceed N bytes) to the JsonString.
|
/* Append formatted text (not to exceed N bytes) to the JsonString.
|
||||||
*/
|
*/
|
||||||
@@ -238,10 +261,17 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){
|
|||||||
|
|
||||||
/* Append a single character
|
/* Append a single character
|
||||||
*/
|
*/
|
||||||
static void jsonAppendChar(JsonString *p, char c){
|
static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){
|
||||||
if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return;
|
if( jsonGrow(p,1) ) return;
|
||||||
p->zBuf[p->nUsed++] = c;
|
p->zBuf[p->nUsed++] = c;
|
||||||
}
|
}
|
||||||
|
static void jsonAppendChar(JsonString *p, char c){
|
||||||
|
if( p->nUsed>=p->nAlloc ){
|
||||||
|
jsonAppendCharExpand(p,c);
|
||||||
|
}else{
|
||||||
|
p->zBuf[p->nUsed++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Append a comma separator to the output buffer, if the previous
|
/* Append a comma separator to the output buffer, if the previous
|
||||||
** character is not '[' or '{'.
|
** character is not '[' or '{'.
|
||||||
@@ -250,7 +280,8 @@ static void jsonAppendSeparator(JsonString *p){
|
|||||||
char c;
|
char c;
|
||||||
if( p->nUsed==0 ) return;
|
if( p->nUsed==0 ) return;
|
||||||
c = p->zBuf[p->nUsed-1];
|
c = p->zBuf[p->nUsed-1];
|
||||||
if( c!='[' && c!='{' ) jsonAppendChar(p, ',');
|
if( c=='[' || c=='{' ) return;
|
||||||
|
jsonAppendChar(p, ',');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append the N-byte string in zIn to the end of the JsonString string
|
/* Append the N-byte string in zIn to the end of the JsonString string
|
||||||
@@ -310,7 +341,7 @@ static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
|
|||||||
while( N>0 ){
|
while( N>0 ){
|
||||||
for(i=0; i<N && zIn[i]!='\\'; i++){}
|
for(i=0; i<N && zIn[i]!='\\'; i++){}
|
||||||
if( i>0 ){
|
if( i>0 ){
|
||||||
jsonAppendRaw(p, zIn, i);
|
jsonAppendRawNZ(p, zIn, i);
|
||||||
zIn += i;
|
zIn += i;
|
||||||
N -= i;
|
N -= i;
|
||||||
if( N==0 ) break;
|
if( N==0 ) break;
|
||||||
@@ -321,16 +352,16 @@ static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
|
|||||||
jsonAppendChar(p, '\'');
|
jsonAppendChar(p, '\'');
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
jsonAppendRaw(p, "\\u0009", 6);
|
jsonAppendRawNZ(p, "\\u0009", 6);
|
||||||
break;
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
jsonAppendRaw(p, "\\u00", 4);
|
jsonAppendRawNZ(p, "\\u00", 4);
|
||||||
jsonAppendRaw(p, &zIn[2], 2);
|
jsonAppendRawNZ(p, &zIn[2], 2);
|
||||||
zIn += 2;
|
zIn += 2;
|
||||||
N -= 2;
|
N -= 2;
|
||||||
break;
|
break;
|
||||||
case '0':
|
case '0':
|
||||||
jsonAppendRaw(p, "\\u0000", 6);
|
jsonAppendRawNZ(p, "\\u0000", 6);
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
if( zIn[2]=='\n' ){
|
if( zIn[2]=='\n' ){
|
||||||
@@ -348,7 +379,7 @@ static void jsonAppendNormalizedString(JsonString *p, const char *zIn, u32 N){
|
|||||||
N -= 2;
|
N -= 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
jsonAppendRaw(p, zIn, 2);
|
jsonAppendRawNZ(p, zIn, 2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
zIn += 2;
|
zIn += 2;
|
||||||
@@ -378,11 +409,12 @@ static void jsonAppendNormalizedInt(JsonString *p, const char *zIn, u32 N){
|
|||||||
jsonPrintf(100,p,"%lld",i);
|
jsonPrintf(100,p,"%lld",i);
|
||||||
}else{
|
}else{
|
||||||
assert( rc==2 );
|
assert( rc==2 );
|
||||||
jsonAppendRaw(p, "9.0e999", 7);
|
jsonAppendRawNZ(p, "9.0e999", 7);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
jsonAppendRaw(p, zIn, N);
|
assert( N>0 );
|
||||||
|
jsonAppendRawNZ(p, zIn, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -414,7 +446,7 @@ static void jsonAppendNormalizedReal(JsonString *p, const char *zIn, u32 N){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( N>0 ){
|
if( N>0 ){
|
||||||
jsonAppendRaw(p, zIn, N);
|
jsonAppendRawNZ(p, zIn, N);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,7 +462,7 @@ static void jsonAppendValue(
|
|||||||
){
|
){
|
||||||
switch( sqlite3_value_type(pValue) ){
|
switch( sqlite3_value_type(pValue) ){
|
||||||
case SQLITE_NULL: {
|
case SQLITE_NULL: {
|
||||||
jsonAppendRaw(p, "null", 4);
|
jsonAppendRawNZ(p, "null", 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SQLITE_FLOAT: {
|
case SQLITE_FLOAT: {
|
||||||
@@ -469,7 +501,8 @@ static void jsonAppendValue(
|
|||||||
*/
|
*/
|
||||||
static void jsonResult(JsonString *p){
|
static void jsonResult(JsonString *p){
|
||||||
if( p->bErr==0 ){
|
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,
|
p->bStatic ? SQLITE_TRANSIENT : sqlite3_free,
|
||||||
SQLITE_UTF8);
|
SQLITE_UTF8);
|
||||||
jsonZero(p);
|
jsonZero(p);
|
||||||
@@ -538,15 +571,15 @@ static void jsonRenderNode(
|
|||||||
switch( pNode->eType ){
|
switch( pNode->eType ){
|
||||||
default: {
|
default: {
|
||||||
assert( pNode->eType==JSON_NULL );
|
assert( pNode->eType==JSON_NULL );
|
||||||
jsonAppendRaw(pOut, "null", 4);
|
jsonAppendRawNZ(pOut, "null", 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JSON_TRUE: {
|
case JSON_TRUE: {
|
||||||
jsonAppendRaw(pOut, "true", 4);
|
jsonAppendRawNZ(pOut, "true", 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JSON_FALSE: {
|
case JSON_FALSE: {
|
||||||
jsonAppendRaw(pOut, "false", 5);
|
jsonAppendRawNZ(pOut, "false", 5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case JSON_STRING: {
|
case JSON_STRING: {
|
||||||
@@ -562,7 +595,8 @@ static void jsonRenderNode(
|
|||||||
}else if( pNode->jnFlags & JNODE_JSON5 ){
|
}else if( pNode->jnFlags & JNODE_JSON5 ){
|
||||||
jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
|
jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n);
|
||||||
}else{
|
}else{
|
||||||
jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
|
assert( pNode->n>0 );
|
||||||
|
jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -571,7 +605,8 @@ static void jsonRenderNode(
|
|||||||
if( pNode->jnFlags & JNODE_JSON5 ){
|
if( pNode->jnFlags & JNODE_JSON5 ){
|
||||||
jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
|
jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n);
|
||||||
}else{
|
}else{
|
||||||
jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
|
assert( pNode->n>0 );
|
||||||
|
jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -580,7 +615,8 @@ static void jsonRenderNode(
|
|||||||
if( pNode->jnFlags & JNODE_JSON5 ){
|
if( pNode->jnFlags & JNODE_JSON5 ){
|
||||||
jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
|
jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n);
|
||||||
}else{
|
}else{
|
||||||
jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
|
assert( pNode->n>0 );
|
||||||
|
jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -882,7 +918,8 @@ static int jsonParseAddNode(
|
|||||||
const char *zContent /* Content */
|
const char *zContent /* Content */
|
||||||
){
|
){
|
||||||
JsonNode *p;
|
JsonNode *p;
|
||||||
if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){
|
assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc );
|
||||||
|
if( pParse->nNode>=pParse->nAlloc ){
|
||||||
return jsonParseAddNodeExpand(pParse, eType, n, zContent);
|
return jsonParseAddNodeExpand(pParse, eType, n, zContent);
|
||||||
}
|
}
|
||||||
p = &pParse->aNode[pParse->nNode];
|
p = &pParse->aNode[pParse->nNode];
|
||||||
@@ -1235,15 +1272,31 @@ json_parse_restart:
|
|||||||
jnFlags = 0;
|
jnFlags = 0;
|
||||||
parse_string:
|
parse_string:
|
||||||
cDelim = z[i];
|
cDelim = z[i];
|
||||||
j = i+1;
|
for(j=i+1; 1; j++){
|
||||||
for(;;){
|
static const char aOk[256] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
|
||||||
|
};
|
||||||
|
if( aOk[(unsigned char)z[j]] ) continue;
|
||||||
c = z[j];
|
c = z[j];
|
||||||
if( (c & ~0x1f)==0 ){
|
if( c==cDelim ){
|
||||||
/* Control characters are not allowed in strings */
|
break;
|
||||||
pParse->iErr = j;
|
}else if( c=='\\' ){
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if( c=='\\' ){
|
|
||||||
c = z[++j];
|
c = z[++j];
|
||||||
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|
if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f'
|
||||||
|| c=='n' || c=='r' || c=='t'
|
|| c=='n' || c=='r' || c=='t'
|
||||||
@@ -1263,10 +1316,11 @@ json_parse_restart:
|
|||||||
pParse->iErr = j;
|
pParse->iErr = j;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}else if( c==cDelim ){
|
}else if( c<=0x1f ){
|
||||||
break;
|
/* Control characters are not allowed in strings */
|
||||||
|
pParse->iErr = j;
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
|
jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]);
|
||||||
return j+1;
|
return j+1;
|
||||||
@@ -2003,12 +2057,12 @@ static void jsonParseFunc(
|
|||||||
assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
|
assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
|
||||||
if( x.aNode[i].u.zJContent!=0 ){
|
if( x.aNode[i].u.zJContent!=0 ){
|
||||||
assert( x.aNode[i].eU==1 );
|
assert( x.aNode[i].eU==1 );
|
||||||
jsonAppendRaw(&s, " ", 1);
|
jsonAppendChar(&s, ' ');
|
||||||
jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
|
jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
|
||||||
}else{
|
}else{
|
||||||
assert( x.aNode[i].eU==0 );
|
assert( x.aNode[i].eU==0 );
|
||||||
}
|
}
|
||||||
jsonAppendRaw(&s, "\n", 1);
|
jsonAppendChar(&s, '\n');
|
||||||
}
|
}
|
||||||
jsonParseReset(&x);
|
jsonParseReset(&x);
|
||||||
jsonResult(&s);
|
jsonResult(&s);
|
||||||
@@ -2175,11 +2229,11 @@ static void jsonExtractFunc(
|
|||||||
*/
|
*/
|
||||||
jsonInit(&jx, ctx);
|
jsonInit(&jx, ctx);
|
||||||
if( sqlite3Isdigit(zPath[0]) ){
|
if( sqlite3Isdigit(zPath[0]) ){
|
||||||
jsonAppendRaw(&jx, "$[", 2);
|
jsonAppendRawNZ(&jx, "$[", 2);
|
||||||
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
|
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
|
||||||
jsonAppendRaw(&jx, "]", 2);
|
jsonAppendRawNZ(&jx, "]", 2);
|
||||||
}else{
|
}else{
|
||||||
jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='['));
|
jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='['));
|
||||||
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
|
jsonAppendRaw(&jx, zPath, (int)strlen(zPath));
|
||||||
jsonAppendChar(&jx, 0);
|
jsonAppendChar(&jx, 0);
|
||||||
}
|
}
|
||||||
@@ -2214,7 +2268,7 @@ static void jsonExtractFunc(
|
|||||||
if( pNode ){
|
if( pNode ){
|
||||||
jsonRenderNode(pNode, &jx, 0);
|
jsonRenderNode(pNode, &jx, 0);
|
||||||
}else{
|
}else{
|
||||||
jsonAppendRaw(&jx, "null", 4);
|
jsonAppendRawNZ(&jx, "null", 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( i==argc ){
|
if( i==argc ){
|
||||||
|
@@ -889,8 +889,31 @@ typedef INT16_TYPE LogEst;
|
|||||||
** the end of buffer S. This macro returns true if P points to something
|
** the end of buffer S. This macro returns true if P points to something
|
||||||
** contained within the buffer S.
|
** contained within the buffer S.
|
||||||
*/
|
*/
|
||||||
#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
|
#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E)))
|
||||||
|
|
||||||
|
/*
|
||||||
|
** P is one byte past the end of a large buffer. Return true if a span of bytes
|
||||||
|
** between S..E crosses the end of that buffer. In other words, return true
|
||||||
|
** if the sub-buffer S..E-1 overflows the buffer show last byte is P-1.
|
||||||
|
**
|
||||||
|
** S is the start of the span. E is one byte past the end of end of span.
|
||||||
|
**
|
||||||
|
** P
|
||||||
|
** |-----------------| FALSE
|
||||||
|
** |-------|
|
||||||
|
** S E
|
||||||
|
**
|
||||||
|
** P
|
||||||
|
** |-----------------|
|
||||||
|
** |-------| TRUE
|
||||||
|
** S E
|
||||||
|
**
|
||||||
|
** P
|
||||||
|
** |-----------------|
|
||||||
|
** |-------| FALSE
|
||||||
|
** S E
|
||||||
|
*/
|
||||||
|
#define SQLITE_OVERFLOW(P,S,E) (((uptr)(S)<(uptr)(P))&&((uptr)(E)>(uptr)(P)))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Macros to determine whether the machine is big or little endian,
|
** Macros to determine whether the machine is big or little endian,
|
||||||
|
@@ -863,7 +863,9 @@ int sqlite3DecOrHexToI64(const char *z, i64 *pOut){
|
|||||||
}else
|
}else
|
||||||
#endif /* SQLITE_OMIT_HEX_INTEGER */
|
#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_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.');
|
||||||
}
|
}
|
||||||
sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
|
sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]);
|
||||||
|
if( f & MEM_Term ){
|
||||||
|
sqlite3_str_appendf(pStr, "(0-term)");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3085,6 +3088,9 @@ op_column_restart:
|
|||||||
rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
|
rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest);
|
||||||
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
if( rc!=SQLITE_OK ) goto abort_due_to_error;
|
||||||
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
|
sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest);
|
||||||
|
if( (t&1)!=0 && encoding==SQLITE_UTF8 ){
|
||||||
|
pDest->flags |= MEM_Term;
|
||||||
|
}
|
||||||
pDest->flags &= ~MEM_Ephem;
|
pDest->flags &= ~MEM_Ephem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -611,6 +611,7 @@ int sqlite3VdbeMemSetZeroBlob(Mem*,int);
|
|||||||
int sqlite3VdbeMemIsRowSet(const Mem*);
|
int sqlite3VdbeMemIsRowSet(const Mem*);
|
||||||
#endif
|
#endif
|
||||||
int sqlite3VdbeMemSetRowSet(Mem*);
|
int sqlite3VdbeMemSetRowSet(Mem*);
|
||||||
|
void sqlite3VdbeMemZeroTerminateIfAble(Mem*);
|
||||||
int sqlite3VdbeMemMakeWriteable(Mem*);
|
int sqlite3VdbeMemMakeWriteable(Mem*);
|
||||||
int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
int sqlite3VdbeMemStringify(Mem*, u8, u8);
|
||||||
int sqlite3IntFloatCompare(i64,double);
|
int sqlite3IntFloatCompare(i64,double);
|
||||||
|
@@ -514,6 +514,7 @@ void sqlite3_result_text64(
|
|||||||
(void)invokeValueDestructor(z, xDel, pCtx);
|
(void)invokeValueDestructor(z, xDel, pCtx);
|
||||||
}else{
|
}else{
|
||||||
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
|
setResultStrOrError(pCtx, z, (int)n, enc, xDel);
|
||||||
|
sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef SQLITE_OMIT_UTF16
|
#ifndef SQLITE_OMIT_UTF16
|
||||||
|
@@ -314,6 +314,32 @@ int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){
|
|||||||
return SQLITE_OK;
|
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.
|
** It is already known that pMem contains an unterminated string.
|
||||||
** Add the zero terminator.
|
** Add the zero terminator.
|
||||||
@@ -803,6 +829,7 @@ int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
int rc;
|
||||||
assert( aff==SQLITE_AFF_TEXT );
|
assert( aff==SQLITE_AFF_TEXT );
|
||||||
assert( MEM_Str==(MEM_Blob>>3) );
|
assert( MEM_Str==(MEM_Blob>>3) );
|
||||||
pMem->flags |= (pMem->flags&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 );
|
assert( pMem->flags & MEM_Str || pMem->db->mallocFailed );
|
||||||
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
|
pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero);
|
||||||
if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1;
|
if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1;
|
||||||
return sqlite3VdbeChangeEncoding(pMem, encoding);
|
rc = sqlite3VdbeChangeEncoding(pMem, encoding);
|
||||||
|
if( rc ) return rc;
|
||||||
|
sqlite3VdbeMemZeroTerminateIfAble(pMem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return SQLITE_OK;
|
return SQLITE_OK;
|
||||||
|
@@ -1945,7 +1945,6 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
|
|||||||
p->nSegment = nSegment;
|
p->nSegment = nSegment;
|
||||||
aTmp = (ht_slot*)&(((u8*)p)[nByte]);
|
aTmp = (ht_slot*)&(((u8*)p)[nByte]);
|
||||||
SEH_FREE_ON_ERROR(0, p);
|
SEH_FREE_ON_ERROR(0, p);
|
||||||
|
|
||||||
for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
|
for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && i<nSegment; i++){
|
||||||
WalHashLoc sLoc;
|
WalHashLoc sLoc;
|
||||||
|
|
||||||
@@ -1973,7 +1972,6 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){
|
|||||||
p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
|
p->aSegment[i].aPgno = (u32 *)sLoc.aPgno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( rc!=SQLITE_OK ){
|
if( rc!=SQLITE_OK ){
|
||||||
SEH_FREE_ON_ERROR(p, 0);
|
SEH_FREE_ON_ERROR(p, 0);
|
||||||
walIteratorFree(p);
|
walIteratorFree(p);
|
||||||
|
@@ -5122,9 +5122,10 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){
|
|||||||
|
|
||||||
/* TUNING: A full-scan of a VIEW or subquery in the outer loop
|
/* TUNING: A full-scan of a VIEW or subquery in the outer loop
|
||||||
** is not so bad. */
|
** is not so bad. */
|
||||||
if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){
|
if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 && nLoop>1 ){
|
||||||
rCost += -10;
|
rCost += -10;
|
||||||
nOut += -30;
|
nOut += -30;
|
||||||
|
WHERETRACE(0x80,("VIEWSCAN cost reduction for %c\n",pWLoop->cId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if pWLoop should be added to the set of
|
/* Check to see if pWLoop should be added to the set of
|
||||||
|
@@ -25,3 +25,15 @@ of the SQLite JSON parser.
|
|||||||
|
|
||||||
2. Run "`sh json-speed-check-1.sh x1`". The profile output will appear
|
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".
|
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;
|
||||||
|
~~~~
|
||||||
|
Reference in New Issue
Block a user