Merge in JNI's significant divergence since it adopted sqlite3_client_data().

FossilOrigin-Name: e8e07dbbeaa7799eb0b90726e18e994aaf8c8d316ab4bdb06da732bc51cf0919
This commit is contained in:
stephan 2023-09-11 15:20:15 +00:00
commit 5c3a25b450
37 changed files with 2432 additions and 1324 deletions

View File

@ -27,10 +27,18 @@ dir.bld := $(dir.jni)/bld
dir.bld.c := $(dir.bld) dir.bld.c := $(dir.bld)
dir.src.jni := $(dir.src)/org/sqlite/jni dir.src.jni := $(dir.src)/org/sqlite/jni
dir.src.jni.tester := $(dir.src.jni)/tester dir.src.jni.tester := $(dir.src.jni)/tester
mkdir := mkdir -p dir.src.fts5 := $(dir.src.jni)/fts5
mkdir ?= mkdir -p
$(dir.bld.c): $(dir.bld.c):
$(mkdir) $@ $(mkdir) $@
javac.flags ?= -Xlint:unchecked -Xlint:deprecation
java.flags ?=
jnicheck ?= 1
ifeq (1,$(jnicheck))
java.flags += -Xcheck:jni
endif
classpath := $(dir.src) classpath := $(dir.src)
CLEAN_FILES := $(package.jar) CLEAN_FILES := $(package.jar)
DISTCLEAN_FILES := $(dir.jni)/*~ $(dir.src.c)/*~ $(dir.src.jni)/*~ DISTCLEAN_FILES := $(dir.jni)/*~ $(dir.src.c)/*~ $(dir.src.jni)/*~
@ -44,10 +52,17 @@ SQLTester.class := $(SQLTester.java:.java=.class)
######################################################################## ########################################################################
# The future of FTS5 customization in this API is as yet unclear. # The future of FTS5 customization in this API is as yet unclear.
# It would be a real doozy to bind to JNI. # The pieces are all in place, and are all thin proxies so not much
enable.fts5 ?= 1 # complexity, but some semantic changes were required in porting
# which are largely untested.
#
# Reminder: this flag influences the contents of $(sqlite3-jni.h),
# which is checked in. Please do not check in changes to that file in
# which the fts5 APIs have been stripped unless that feature is
# intended to be stripped for good.
enable.fts5 ?= 0
# If enable.tester is 0, the org/sqlite/jni/tester/* bits are elided. # If enable.tester is 0, the org/sqlite/jni/tester/* bits are elided.
enable.tester ?= 1 enable.tester ?= $(if $(wildcard $(dir.src.jni.tester)/SQLTester.java),1,0)
# bin.version-info = binary to output various sqlite3 version info # bin.version-info = binary to output various sqlite3 version info
# building the distribution zip file. # building the distribution zip file.
@ -62,7 +77,6 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
annotation/Canonical.java \ annotation/Canonical.java \
annotation/NotNull.java \ annotation/NotNull.java \
annotation/Nullable.java \ annotation/Nullable.java \
annotation/package-info.java \
AbstractCollationCallback.java \ AbstractCollationCallback.java \
AggregateFunction.java \ AggregateFunction.java \
AuthorizerCallback.java \ AuthorizerCallback.java \
@ -71,6 +85,7 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
CollationCallback.java \ CollationCallback.java \
CollationNeededCallback.java \ CollationNeededCallback.java \
CommitHookCallback.java \ CommitHookCallback.java \
ConfigLogCallback.java \
ConfigSqllogCallback.java \ ConfigSqllogCallback.java \
NativePointerHolder.java \ NativePointerHolder.java \
OutputPointer.java \ OutputPointer.java \
@ -80,60 +95,59 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
RollbackHookCallback.java \ RollbackHookCallback.java \
ScalarFunction.java \ ScalarFunction.java \
SQLFunction.java \ SQLFunction.java \
CallbackProxy.java \
SQLite3Jni.java \ SQLite3Jni.java \
Tester1.java \ TableColumnMetadata.java \
TraceV2Callback.java \ TraceV2Callback.java \
UpdateHookCallback.java \ UpdateHookCallback.java \
ValueHolder.java \
WindowFunction.java \ WindowFunction.java \
XDestroyCallback.java \ XDestroyCallback.java \
package-info.java \
sqlite3.java \ sqlite3.java \
sqlite3_context.java \ sqlite3_context.java \
sqlite3_stmt.java \ sqlite3_stmt.java \
sqlite3_value.java \ sqlite3_value.java \
) )
JAVA_FILES.unittest := $(patsubst %,$(dir.src.jni)/%,\
Tester1.java \
)
ifeq (1,$(enable.fts5)) ifeq (1,$(enable.fts5))
JAVA_FILES.main += $(patsubst %,$(dir.src.jni)/%,\ JAVA_FILES.main += $(patsubst %,$(dir.src.fts5)/%,\
fts5_api.java \ fts5_api.java \
fts5_extension_function.java \ fts5_extension_function.java \
fts5_tokenizer.java \ fts5_tokenizer.java \
Fts5.java \ Fts5.java \
Fts5Context.java \ Fts5Context.java \
Fts5ExtensionApi.java \ Fts5ExtensionApi.java \
Fts5Function.java \
Fts5PhraseIter.java \ Fts5PhraseIter.java \
Fts5Tokenizer.java \ Fts5Tokenizer.java \
TesterFts5.java \ TesterFts5.java \
) )
endif endif
JAVA_FILES.tester := $(dir.src.jni.tester)/SQLTester.java JAVA_FILES.tester := $(dir.src.jni.tester)/SQLTester.java
JAVA_FILES.package.info := \
$(dir.src.jni)/package-info.java \
$(dir.src.jni)/annotation/package-info.java
CLASS_FILES.main := $(JAVA_FILES.main:.java=.class) CLASS_FILES.main := $(JAVA_FILES.main:.java=.class)
CLASS_FILES.unittest := $(JAVA_FILES.unittest:.java=.class)
CLASS_FILES.tester := $(JAVA_FILES.tester:.java=.class) CLASS_FILES.tester := $(JAVA_FILES.tester:.java=.class)
JAVA_FILES += $(JAVA_FILES.main) JAVA_FILES += $(JAVA_FILES.main) $(JAVA_FILES.unittest)
ifeq (1,$(enable.tester)) ifeq (1,$(enable.tester))
JAVA_FILES += $(JAVA_FILES.tester) JAVA_FILES += $(JAVA_FILES.tester)
endif endif
CLASS_FILES := CLASS_FILES :=
define DOTCLASS_DEPS define CLASSFILE_DEPS
$(1).class: $(1).java $(MAKEFILE)
all: $(1).class all: $(1).class
CLASS_FILES += $(1).class CLASS_FILES += $(1).class
endef endef
$(foreach B,$(basename $(JAVA_FILES)),$(eval $(call DOTCLASS_DEPS,$(B)))) $(foreach B,$(basename \
$(CLASS_FILES.tester): $(CLASS_FILES.main) $(JAVA_FILES.main) $(JAVA_FILES.unittest) $(JAVA_FILES.tester)),\
javac.flags ?= -Xlint:unchecked -Xlint:deprecation $(eval $(call CLASSFILE_DEPS,$(B))))
java.flags ?= $(CLASS_FILES): $(JAVA_FILES) $(MAKEFILE)
jnicheck ?= 1
ifeq (1,$(jnicheck))
java.flags += -Xcheck:jni
endif
$(SQLite3Jni.class): $(JAVA_FILES)
$(bin.javac) $(javac.flags) -h $(dir.bld.c) -cp $(classpath) $(JAVA_FILES) $(bin.javac) $(javac.flags) -h $(dir.bld.c) -cp $(classpath) $(JAVA_FILES)
all: $(SQLite3Jni.class)
#.PHONY: classfiles #.PHONY: classfiles
######################################################################## ########################################################################
@ -168,7 +182,9 @@ $(sqlite3.h):
$(sqlite3.c): $(sqlite3.h) $(sqlite3.c): $(sqlite3.h)
opt.threadsafe ?= 1 opt.threadsafe ?= 1
opt.oom ?= 0 opt.fatal-oom ?= 1
opt.debug ?= 1
opt.metrics ?= 1
SQLITE_OPT = \ SQLITE_OPT = \
-DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_EXPLAIN_COMMENTS \ -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
@ -186,10 +202,14 @@ SQLITE_OPT = \
-DSQLITE_TEMP_STORE=2 \ -DSQLITE_TEMP_STORE=2 \
-DSQLITE_USE_URI=1 \ -DSQLITE_USE_URI=1 \
-DSQLITE_C=$(sqlite3.c) \ -DSQLITE_C=$(sqlite3.c) \
-DSQLITE_JNI_FATAL_OOM=$(opt.oom) \ -DSQLITE_JNI_FATAL_OOM=$(opt.fatal-oom) \
-DSQLITE_DEBUG -DSQLITE_JNI_ENABLE_METRICS=$(opt.metrics)
SQLITE_OPT += -g -DDEBUG -UNDEBUG ifeq (1,$(opt.debug))
SQLITE_OPT += -DSQLITE_DEBUG -g -DDEBUG -UNDEBUG
else
SQLITE_OPT += -O2
endif
ifeq (1,$(enable.fts5)) ifeq (1,$(enable.fts5))
SQLITE_OPT += -DSQLITE_ENABLE_FTS5 SQLITE_OPT += -DSQLITE_ENABLE_FTS5
@ -198,25 +218,31 @@ endif
sqlite3-jni.c := $(dir.src.c)/sqlite3-jni.c sqlite3-jni.c := $(dir.src.c)/sqlite3-jni.c
sqlite3-jni.o := $(dir.bld.c)/sqlite3-jni.o sqlite3-jni.o := $(dir.bld.c)/sqlite3-jni.o
sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h
sqlite3-jni.dll := $(dir.bld.c)/libsqlite3-jni.so package.dll := $(dir.bld.c)/libsqlite3-jni.so
# All javac-generated .h files must be listed in $(sqlite3-jni.h.in): # All javac-generated .h files must be listed in $(sqlite3-jni.h.in):
sqlite3-jni.h.in := sqlite3-jni.h.in :=
# $(java.with.jni) lists all Java files which contain JNI decls:
java.with.jni :=
define ADD_JNI_H define ADD_JNI_H
sqlite3-jni.h.in += $$(dir.bld.c)/org_sqlite_jni_$(1).h sqlite3-jni.h.in += $$(dir.bld.c)/org_sqlite_jni$(3)_$(2).h
$$(dir.bld.c)/org_sqlite_jni_$(1).h: $$(dir.src.jni)/$(1).java java.with.jni += $(1)/$(2).java
$$(dir.bld.c)/org_sqlite_jni$(3)_$(2).h: $(1)/$(2).java
endef endef
$(eval $(call ADD_JNI_H,SQLite3Jni)) # Invoke ADD_JNI_H once for each Java file which includes JNI
# declarations:
$(eval $(call ADD_JNI_H,$(dir.src.jni),SQLite3Jni,))
ifeq (1,$(enable.fts5)) ifeq (1,$(enable.fts5))
$(eval $(call ADD_JNI_H,Fts5ExtensionApi)) $(eval $(call ADD_JNI_H,$(dir.src.fts5),Fts5ExtensionApi,_fts5))
$(eval $(call ADD_JNI_H,fts5_api)) $(eval $(call ADD_JNI_H,$(dir.src.fts5),fts5_api,_fts5))
$(eval $(call ADD_JNI_H,fts5_tokenizer)) $(eval $(call ADD_JNI_H,$(dir.src.fts5),fts5_tokenizer,_fts5))
endif endif
ifeq (1,$(enable.tester)) ifeq (1,$(enable.tester))
sqlite3-jni.h.in += $(dir.bld.c)/org_sqlite_jni_tester_SQLTester.h $(eval $(call ADD_JNI_H,$(dir.src.jni.tester),SQLTester,_tester))
$(dir.bld.c)/org_sqlite_jni_tester_SQLTester.h: $(dir.src.jni.tester)/SQLTester.java
endif endif
#sqlite3-jni.dll.cfiles := $(dir.src.c) $(sqlite3-jni.h.in): $(dir.bld.c)
sqlite3-jni.dll.cflags = \
#package.dll.cfiles :=
package.dll.cflags = \
-fPIC \ -fPIC \
-I. \ -I. \
-I$(dir $(sqlite3.h)) \ -I$(dir $(sqlite3.h)) \
@ -233,22 +259,34 @@ sqlite3-jni.dll.cflags = \
# include path for client-level code. # include path for client-level code.
######################################################################## ########################################################################
ifeq (1,$(enable.tester)) ifeq (1,$(enable.tester))
sqlite3-jni.dll.cflags += -DSQLITE_JNI_ENABLE_SQLTester package.dll.cflags += -DSQLITE_JNI_ENABLE_SQLTester
endif endif
$(sqlite3-jni.h): $(sqlite3-jni.h.in) $(MAKEFILE) $(sqlite3-jni.h): $(sqlite3-jni.h.in) $(MAKEFILE)
cat $(sqlite3-jni.h.in) > $@ @cat $(sqlite3-jni.h.in) > $@.tmp
$(sqlite3-jni.dll): $(sqlite3-jni.h) $(sqlite3.c) $(sqlite3.h) @if cmp $@ $@.tmp >/dev/null; then \
$(sqlite3-jni.dll): $(dir.bld.c) $(sqlite3-jni.c) $(SQLite3Jni.java) $(MAKEFILE) rm -f $@.tmp; \
$(CC) $(sqlite3-jni.dll.cflags) $(SQLITE_OPT) \ echo "$@ not modified"; \
else \
mv $@.tmp $@; \
echo "Updated $@"; \
fi
@if [ x1 != x$(enable.fts5) ]; then \
echo "*** REMINDER:"; \
echo "*** enable.fts5=0, so please do not check in changes to $@."; \
fi
$(package.dll): $(sqlite3-jni.h) $(sqlite3.c) $(sqlite3.h)
$(package.dll): $(sqlite3-jni.c) $(MAKEFILE)
$(CC) $(package.dll.cflags) $(SQLITE_OPT) \
$(sqlite3-jni.c) -shared -o $@ $(sqlite3-jni.c) -shared -o $@
all: $(sqlite3-jni.dll) all: $(package.dll)
.PHONY: test test-one .PHONY: test test-one
test.flags ?= test.flags ?=
test.main.flags = -ea -Djava.library.path=$(dir.bld.c) \ test.main.flags = -ea -Djava.library.path=$(dir.bld.c) \
$(java.flags) -cp $(classpath) \ $(java.flags) -cp $(classpath) \
org.sqlite.jni.Tester1 org.sqlite.jni.Tester1
test.deps := $(SQLite3Jni.class) $(sqlite3-jni.dll) test.deps := $(CLASS_FILES) $(package.dll)
test-one: $(test.deps) test-one: $(test.deps)
$(bin.java) $(test.main.flags) $(test.flags) $(bin.java) $(test.main.flags) $(test.flags)
test-sqllog: $(test.deps) test-sqllog: $(test.deps)
@ -256,7 +294,7 @@ test-sqllog: $(test.deps)
$(bin.java) $(test.main.flags) -sqllog $(bin.java) $(test.main.flags) -sqllog
test-mt: $(test.deps) test-mt: $(test.deps)
@echo "Testing in multi-threaded mode:"; @echo "Testing in multi-threaded mode:";
$(bin.java) $(test.main.flags) -t 11 -r 50 -shuffle $(test.flags) $(bin.java) $(test.main.flags) -t 7 -r 50 -shuffle $(test.flags)
test: test-one test-mt test: test-one test-mt
tests: test test-sqllog tests: test test-sqllog
@ -265,7 +303,7 @@ tester.scripts := $(sort $(wildcard $(dir.src)/tests/*.test))
tester.flags ?= # --verbose tester.flags ?= # --verbose
.PHONY: tester tester-local tester-ext .PHONY: tester tester-local tester-ext
ifeq (1,$(enable.tester)) ifeq (1,$(enable.tester))
tester-local: $(CLASS_FILES.tester) $(sqlite3-jni.dll) tester-local: $(CLASS_FILES.tester) $(package.dll)
$(bin.java) -ea -Djava.library.path=$(dir.bld.c) \ $(bin.java) -ea -Djava.library.path=$(dir.bld.c) \
$(java.flags) -cp $(classpath) \ $(java.flags) -cp $(classpath) \
org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.scripts) org.sqlite.jni.tester.SQLTester $(tester.flags) $(tester.scripts)
@ -296,41 +334,59 @@ endif
tester-ext: tester-local tester-ext: tester-local
tester: tester-ext tester: tester-ext
tests: tester tests: tester
######################################################################## ########################################################################
# Build each SQLITE_THREADMODE variant and run all tests against them. # Build each SQLITE_THREADMODE variant and run all tests against them.
multitest: clean multitest: clean
$(MAKE) opt.threadsafe=0 opt.oom=1 tests clean define MULTIOPT
$(MAKE) opt.threadsafe=0 opt.oom=0 tests clean multitest: multitest-$(1)
$(MAKE) opt.threadsafe=1 opt.oom=1 tests clean multitest-$(1):
$(MAKE) opt.threadsafe=1 opt.oom=0 tests clean $$(MAKE) opt.debug=$$(opt.debug) $(patsubst %,opt.%,$(2)) \
$(MAKE) opt.threadsafe=2 opt.oom=1 tests clean tests clean enable.fts5=1
$(MAKE) opt.threadsafe=2 opt.oom=0 tests clean endef
$(eval $(call MULTIOPT,01,threadsafe=0 oom=1))
$(eval $(call MULTIOPT,00,threadsafe=0 oom=0))
$(eval $(call MULTIOPT,11,threadsafe=1 oom=1))
$(eval $(call MULTIOPT,10,threadsafe=1 oom=0))
$(eval $(call MULTIOPT,21,threadsafe=2 oom=1))
$(eval $(call MULTIOPT,20,threadsafe=2 oom=0))
######################################################################## ########################################################################
# jar bundle... # jar bundle...
package.jar.in := $(abspath $(dir.src)/jar.in) package.jar.in := $(abspath $(dir.src)/jar.in)
CLEAN_FILES += $(package.jar.in) CLEAN_FILES += $(package.jar.in)
$(package.jar.in): $(MAKEFILE) $(CLASS_FILES.main) JAVA_FILES.jar := $(JAVA_FILES.main) $(JAVA_FILES.unittest) $(JAVA_FILES.package.info)
cd $(dir.src); ls -1 org/sqlite/jni/*.java org/sqlite/jni/*.class > $@ CLASS_FILES.jar := $(filter-out %/package-info.class,$(JAVA_FILES.jar:.java=.class))
@echo "To use this jar you will need the -Djava.library.path=DIR/CONTAINING/libsqlite3-jni.so flag." $(package.jar.in): $(package.dll) $(MAKEFILE)
@echo "e.g. java -jar $@ -Djava.library.path=bld" ls -1 \
$(dir.src.jni)/*.java $(dir.src.jni)/*.class \
$(dir.src.jni)/annotation/*.java $(dir.src.jni)/annotation/*.class \
| sed -e 's,^$(dir.src)/,,' | sort > $@
$(package.jar): $(CLASS_FILES) $(MAKEFILE) $(package.jar.in) $(package.jar): $(CLASS_FILES.jar) $(MAKEFILE) $(package.jar.in)
rm -f $(dir.src)/c/*~ $(dir.src.jni)/*~ @rm -f $(dir.src)/c/*~ $(dir.src.jni)/*~
cd $(dir.src); $(bin.jar) -cfe ../$@ org.sqlite.jni.Tester1 @$(package.jar.in) cd $(dir.src); $(bin.jar) -cfe ../$@ org.sqlite.jni.Tester1 @$(package.jar.in)
@ls -la $@
@echo "To use this jar you will need the -Djava.library.path=DIR/CONTAINING/libsqlite3-jni.so flag."
@echo "e.g. java -Djava.library.path=bld -jar $@"
jar: $(package.jar) jar: $(package.jar)
run-jar: $(package.jar) $(package.dll)
$(bin.java) -Djava.library.path=$(dir.bld) -jar $(package.jar) $(run-jar.flags)
######################################################################## ########################################################################
# javadoc... # javadoc...
dir.doc := $(dir.jni)/javadoc dir.doc := $(dir.jni)/javadoc
doc.index := $(dir.doc)/index.html doc.index := $(dir.doc)/index.html
javadoc.exclude := -exclude org.sqlite.jni.tester
ifneq (1,$(enable.fts5))
javadoc.exclude += -exclude org.sqlite.jni.fts5
endif
$(doc.index): $(JAVA_FILES.main) $(MAKEFILE) $(doc.index): $(JAVA_FILES.main) $(MAKEFILE)
@if [ -d $(dir.doc) ]; then rm -fr $(dir.doc)/*; fi @if [ -d $(dir.doc) ]; then rm -fr $(dir.doc)/*; fi
$(bin.javadoc) -cp $(classpath) -d $(dir.doc) -quiet \ $(bin.javadoc) -cp $(classpath) -d $(dir.doc) -quiet \
-subpackages org.sqlite.jni -exclude org.sqlite.jni.tester -subpackages org.sqlite.jni $(javadoc.exclude)
@echo "javadoc output is in $@" @echo "javadoc output is in $@"
.PHONY: doc javadoc docserve .PHONY: doc javadoc docserve
@ -348,7 +404,7 @@ docserve: $(doc.index)
CLEAN_FILES += $(dir.bld.c)/* \ CLEAN_FILES += $(dir.bld.c)/* \
$(dir.src.jni)/*.class \ $(dir.src.jni)/*.class \
$(dir.src.jni.tester)/*.class \ $(dir.src.jni.tester)/*.class \
$(sqlite3-jni.dll) \ $(package.dll) \
hs_err_pid*.log hs_err_pid*.log
.PHONY: clean distclean .PHONY: clean distclean

File diff suppressed because it is too large Load Diff

View File

@ -379,6 +379,30 @@ extern "C" {
#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_IMMUTABLE 8192L #define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_IMMUTABLE 8192L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_BATCH_ATOMIC #undef org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_BATCH_ATOMIC
#define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_BATCH_ATOMIC 16384L #define org_sqlite_jni_SQLite3Jni_SQLITE_IOCAP_BATCH_ATOMIC 16384L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LENGTH
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LENGTH 0L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_SQL_LENGTH
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_SQL_LENGTH 1L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COLUMN
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COLUMN 2L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_EXPR_DEPTH
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_EXPR_DEPTH 3L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COMPOUND_SELECT
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_COMPOUND_SELECT 4L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VDBE_OP
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VDBE_OP 5L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_FUNCTION_ARG
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_FUNCTION_ARG 6L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_ATTACHED
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_ATTACHED 7L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LIKE_PATTERN_LENGTH
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VARIABLE_NUMBER
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_VARIABLE_NUMBER 9L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_TRIGGER_DEPTH
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_TRIGGER_DEPTH 10L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_WORKER_THREADS
#define org_sqlite_jni_SQLite3Jni_SQLITE_LIMIT_WORKER_THREADS 11L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READONLY #undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READONLY
#define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READONLY 1L #define org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READONLY 1L
#undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READWRITE #undef org_sqlite_jni_SQLite3Jni_SQLITE_OPEN_READWRITE
@ -787,6 +811,46 @@ JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1aggregate_1conte
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1auto_1extension JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1auto_1extension
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_backup_finish
* Signature: (Lorg/sqlite/jni/sqlite3_backup;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1finish
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_backup_init
* Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)Lorg/sqlite/jni/sqlite3_backup;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1init
(JNIEnv *, jclass, jobject, jstring, jobject, jstring);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_backup_pagecount
* Signature: (Lorg/sqlite/jni/sqlite3_backup;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1pagecount
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_backup_remaining
* Signature: (Lorg/sqlite/jni/sqlite3_backup;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1remaining
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_backup_step
* Signature: (Lorg/sqlite/jni/sqlite3_backup;I)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1backup_1step
(JNIEnv *, jclass, jobject, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_bind_blob * Method: sqlite3_bind_blob
@ -851,6 +915,14 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1parameter_1
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1parameter_1index JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1parameter_1index
(JNIEnv *, jclass, jobject, jbyteArray); (JNIEnv *, jclass, jobject, jbyteArray);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_bind_parameter_name
* Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1parameter_1name
(JNIEnv *, jclass, jobject, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_bind_text * Method: sqlite3_bind_text
@ -883,6 +955,54 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1zeroblob
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1zeroblob64 JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1bind_1zeroblob64
(JNIEnv *, jclass, jobject, jint, jlong); (JNIEnv *, jclass, jobject, jint, jlong);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_blob_bytes
* Signature: (Lorg/sqlite/jni/sqlite3_blob;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1bytes
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_blob_close
* Signature: (Lorg/sqlite/jni/sqlite3_blob;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1close
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_blob_open
* Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;JILorg/sqlite/jni/OutputPointer/sqlite3_blob;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1open
(JNIEnv *, jclass, jobject, jstring, jstring, jstring, jlong, jint, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_blob_read
* Signature: (Lorg/sqlite/jni/sqlite3_blob;[BI)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1read
(JNIEnv *, jclass, jobject, jbyteArray, jint);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_blob_reopen
* Signature: (Lorg/sqlite/jni/sqlite3_blob;J)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1reopen
(JNIEnv *, jclass, jobject, jlong);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_blob_write
* Signature: (Lorg/sqlite/jni/sqlite3_blob;[BI)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1blob_1write
(JNIEnv *, jclass, jobject, jbyteArray, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_busy_handler * Method: sqlite3_busy_handler
@ -1037,18 +1157,10 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1table_
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_column_text_utf8 * Method: sqlite3_column_text
* Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)[B * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)[B
*/ */
JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text_1utf8 JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text
(JNIEnv *, jclass, jobject, jint);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_column_text
* Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text
(JNIEnv *, jclass, jobject, jint); (JNIEnv *, jclass, jobject, jint);
/* /*
@ -1083,14 +1195,6 @@ JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1value
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1collation_1needed JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1collation_1needed
(JNIEnv *, jclass, jobject, jobject); (JNIEnv *, jclass, jobject, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_context_db_handle
* Signature: (Lorg/sqlite/jni/sqlite3_context;)Lorg/sqlite/jni/sqlite3;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1context_1db_1handle
(JNIEnv *, jclass, jobject);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_commit_hook * Method: sqlite3_commit_hook
@ -1115,6 +1219,14 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1compileoption_
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1compileoption_1used JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1compileoption_1used
(JNIEnv *, jclass, jstring); (JNIEnv *, jclass, jstring);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_complete
* Signature: ([B)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1complete
(JNIEnv *, jclass, jbyteArray);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_config * Method: sqlite3_config
@ -1131,6 +1243,22 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__I
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__Lorg_sqlite_jni_ConfigSqllogCallback_2 JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__Lorg_sqlite_jni_ConfigSqllogCallback_2
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_config
* Signature: (Lorg/sqlite/jni/ConfigLogCallback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__Lorg_sqlite_jni_ConfigLogCallback_2
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_context_db_handle
* Signature: (Lorg/sqlite/jni/sqlite3_context;)Lorg/sqlite/jni/sqlite3;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1context_1db_1handle
(JNIEnv *, jclass, jobject);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_create_collation * Method: sqlite3_create_collation
@ -1187,6 +1315,14 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1filename
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1handle JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1handle
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_db_release_memory
* Signature: (Lorg/sqlite/jni/sqlite3;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1release_1memory
(JNIEnv *, jclass, jobject);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_db_status * Method: sqlite3_db_status
@ -1203,6 +1339,22 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1db_1status
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errcode JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errcode
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_errmsg
* Signature: (Lorg/sqlite/jni/sqlite3;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errmsg
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_errstr
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errstr
(JNIEnv *, jclass, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_expanded_sql * Method: sqlite3_expanded_sql
@ -1229,19 +1381,19 @@ JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1extended_1res
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_errmsg * Method: sqlite3_get_autocommit
* Signature: (Lorg/sqlite/jni/sqlite3;)Ljava/lang/String; * Signature: (Lorg/sqlite/jni/sqlite3;)Z
*/ */
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errmsg JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1get_1autocommit
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_errstr * Method: sqlite3_get_auxdata
* Signature: (I)Ljava/lang/String; * Signature: (Lorg/sqlite/jni/sqlite3_context;I)Ljava/lang/Object;
*/ */
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1errstr JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1get_1auxdata
(JNIEnv *, jclass, jint); (JNIEnv *, jclass, jobject, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
@ -1283,6 +1435,30 @@ JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1interrupt
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1is_1interrupted JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1is_1interrupted
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_keyword_check
* Signature: (Ljava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1keyword_1check
(JNIEnv *, jclass, jstring);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_keyword_count
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1keyword_1count
(JNIEnv *, jclass);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_keyword_name
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1keyword_1name
(JNIEnv *, jclass, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_last_insert_rowid * Method: sqlite3_last_insert_rowid
@ -1307,6 +1483,14 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1libversion
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1libversion_1number JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1libversion_1number
(JNIEnv *, jclass); (JNIEnv *, jclass);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_limit
* Signature: (Lorg/sqlite/jni/sqlite3;II)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1limit
(JNIEnv *, jclass, jobject, jint, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_open * Method: sqlite3_open
@ -1403,6 +1587,22 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1preupdate_1old
JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1progress_1handler JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1progress_1handler
(JNIEnv *, jclass, jobject, jint, jobject); (JNIEnv *, jclass, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_randomness
* Signature: ([B)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1randomness
(JNIEnv *, jclass, jbyteArray);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_release_memory
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1release_1memory
(JNIEnv *, jclass, jint);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_reset * Method: sqlite3_reset
@ -1563,6 +1763,14 @@ JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1rollback_1hook
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1set_1authorizer JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1set_1authorizer
(JNIEnv *, jclass, jobject, jobject); (JNIEnv *, jclass, jobject, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_set_auxdata
* Signature: (Lorg/sqlite/jni/sqlite3_context;ILjava/lang/Object;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1set_1auxdata
(JNIEnv *, jclass, jobject, jint, jobject);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_set_last_insert_rowid * Method: sqlite3_set_last_insert_rowid
@ -1627,6 +1835,38 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1status64
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1step JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1step
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_stmt_explain
* Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1explain
(JNIEnv *, jclass, jobject, jint);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_stmt_isexplain
* Signature: (Lorg/sqlite/jni/sqlite3_stmt;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1isexplain
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_stmt_readonly
* Signature: (Lorg/sqlite/jni/sqlite3_stmt;)Z
*/
JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1readonly
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_stmt_status
* Signature: (Lorg/sqlite/jni/sqlite3_stmt;IZ)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1stmt_1status
(JNIEnv *, jclass, jobject, jint, jboolean);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_strglob * Method: sqlite3_strglob
@ -1643,6 +1883,22 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1strglob
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1strlike JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1strlike
(JNIEnv *, jclass, jbyteArray, jbyteArray, jint); (JNIEnv *, jclass, jbyteArray, jbyteArray, jint);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_system_errno
* Signature: (Lorg/sqlite/jni/sqlite3;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1system_1errno
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_table_column_metadata
* Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/sqlite/jni/OutputPointer/String;Lorg/sqlite/jni/OutputPointer/String;Lorg/sqlite/jni/OutputPointer/Bool;Lorg/sqlite/jni/OutputPointer/Bool;Lorg/sqlite/jni/OutputPointer/Bool;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1table_1column_1metadata
(JNIEnv *, jclass, jobject, jstring, jstring, jstring, jobject, jobject, jobject, jobject, jobject);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_threadsafe * Method: sqlite3_threadsafe
@ -1675,6 +1931,14 @@ JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1total_1changes64
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1trace_1v2 JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1trace_1v2
(JNIEnv *, jclass, jobject, jint, jobject); (JNIEnv *, jclass, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_txn_state
* Signature: (Lorg/sqlite/jni/sqlite3;Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1txn_1state
(JNIEnv *, jclass, jobject, jstring);
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_update_hook * Method: sqlite3_update_hook
@ -1765,18 +2029,10 @@ JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1java_1o
/* /*
* Class: org_sqlite_jni_SQLite3Jni * Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_value_text_utf8 * Method: sqlite3_value_text
* Signature: (Lorg/sqlite/jni/sqlite3_value;)[B * Signature: (Lorg/sqlite/jni/sqlite3_value;)[B
*/ */
JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text_1utf8 JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_SQLite3Jni
* Method: sqlite3_value_text
* Signature: (Lorg/sqlite/jni/sqlite3_value;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text
(JNIEnv *, jclass, jobject); (JNIEnv *, jclass, jobject);
/* /*
@ -1835,229 +2091,6 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1subtype
JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1jni_1internal_1details JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1jni_1internal_1details
(JNIEnv *, jclass); (JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_sqlite_jni_Fts5ExtensionApi */
#ifndef _Included_org_sqlite_jni_Fts5ExtensionApi
#define _Included_org_sqlite_jni_Fts5ExtensionApi
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: getInstance
* Signature: ()Lorg/sqlite/jni/Fts5ExtensionApi;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_getInstance
(JNIEnv *, jclass);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xColumnCount
* Signature: (Lorg/sqlite/jni/Fts5Context;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnCount
(JNIEnv *, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xColumnSize
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnSize
(JNIEnv *, jobject, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xColumnText
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/OutputPointer/String;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnText
(JNIEnv *, jobject, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xColumnTotalSize
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/OutputPointer/Int64;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xColumnTotalSize
(JNIEnv *, jobject, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xGetAuxdata
* Signature: (Lorg/sqlite/jni/Fts5Context;Z)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xGetAuxdata
(JNIEnv *, jobject, jobject, jboolean);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xInst
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xInst
(JNIEnv *, jobject, jobject, jint, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xInstCount
* Signature: (Lorg/sqlite/jni/Fts5Context;Lorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xInstCount
(JNIEnv *, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseCount
* Signature: (Lorg/sqlite/jni/Fts5Context;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseCount
(JNIEnv *, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseFirst
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseFirst
(JNIEnv *, jobject, jobject, jint, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseFirstColumn
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseFirstColumn
(JNIEnv *, jobject, jobject, jint, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseNext
* Signature: (Lorg/sqlite/jni/Fts5Context;Lorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;Lorg/sqlite/jni/OutputPointer/Int32;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseNext
(JNIEnv *, jobject, jobject, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseNextColumn
* Signature: (Lorg/sqlite/jni/Fts5Context;Lorg/sqlite/jni/Fts5PhraseIter;Lorg/sqlite/jni/OutputPointer/Int32;)V
*/
JNIEXPORT void JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseNextColumn
(JNIEnv *, jobject, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xPhraseSize
* Signature: (Lorg/sqlite/jni/Fts5Context;I)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xPhraseSize
(JNIEnv *, jobject, jobject, jint);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xQueryPhrase
* Signature: (Lorg/sqlite/jni/Fts5Context;ILorg/sqlite/jni/Fts5ExtensionApi/xQueryPhraseCallback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xQueryPhrase
(JNIEnv *, jobject, jobject, jint, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xRowCount
* Signature: (Lorg/sqlite/jni/Fts5Context;Lorg/sqlite/jni/OutputPointer/Int64;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xRowCount
(JNIEnv *, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xRowid
* Signature: (Lorg/sqlite/jni/Fts5Context;)J
*/
JNIEXPORT jlong JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xRowid
(JNIEnv *, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xSetAuxdata
* Signature: (Lorg/sqlite/jni/Fts5Context;Ljava/lang/Object;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xSetAuxdata
(JNIEnv *, jobject, jobject, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xTokenize
* Signature: (Lorg/sqlite/jni/Fts5Context;[BLorg/sqlite/jni/Fts5/xTokenize_callback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xTokenize
(JNIEnv *, jobject, jobject, jbyteArray, jobject);
/*
* Class: org_sqlite_jni_Fts5ExtensionApi
* Method: xUserData
* Signature: (Lorg/sqlite/jni/Fts5Context;)Ljava/lang/Object;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_Fts5ExtensionApi_xUserData
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_sqlite_jni_fts5_api */
#ifndef _Included_org_sqlite_jni_fts5_api
#define _Included_org_sqlite_jni_fts5_api
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_sqlite_jni_fts5_api
* Method: getInstanceForDb
* Signature: (Lorg/sqlite/jni/sqlite3;)Lorg/sqlite/jni/fts5_api;
*/
JNIEXPORT jobject JNICALL Java_org_sqlite_jni_fts5_1api_getInstanceForDb
(JNIEnv *, jclass, jobject);
/*
* Class: org_sqlite_jni_fts5_api
* Method: xCreateFunction
* Signature: (Ljava/lang/String;Ljava/lang/Object;Lorg/sqlite/jni/fts5_extension_function;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_1api_xCreateFunction
(JNIEnv *, jobject, jstring, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class org_sqlite_jni_fts5_tokenizer */
#ifndef _Included_org_sqlite_jni_fts5_tokenizer
#define _Included_org_sqlite_jni_fts5_tokenizer
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: org_sqlite_jni_fts5_tokenizer
* Method: xTokenize
* Signature: (Lorg/sqlite/jni/Fts5Tokenizer;I[BLorg/sqlite/jni/Fts5/xTokenize_callback;)I
*/
JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_1tokenizer_xTokenize
(JNIEnv *, jobject, jobject, jint, jbyteArray, jobject);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -17,7 +17,7 @@ import org.sqlite.jni.annotation.*;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_set_authorizer}. Callback for use with {@link SQLite3Jni#sqlite3_set_authorizer}.
*/ */
public interface AuthorizerCallback extends SQLite3CallbackProxy { public interface AuthorizerCallback extends CallbackProxy {
/** /**
Must function as described for the C-level Must function as described for the C-level
sqlite3_set_authorizer() callback. sqlite3_set_authorizer() callback.

View File

@ -17,7 +17,7 @@ package org.sqlite.jni;
Callback for use with the {@link SQLite3Jni#sqlite3_auto_extension} Callback for use with the {@link SQLite3Jni#sqlite3_auto_extension}
family of APIs. family of APIs.
*/ */
public interface AutoExtensionCallback extends SQLite3CallbackProxy { public interface AutoExtensionCallback extends CallbackProxy {
/** /**
Must function as described for a C-level Must function as described for a C-level
sqlite3_auto_extension() callback. sqlite3_auto_extension() callback.

View File

@ -16,7 +16,7 @@ package org.sqlite.jni;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_busy_handler}. Callback for use with {@link SQLite3Jni#sqlite3_busy_handler}.
*/ */
public interface BusyHandlerCallback extends SQLite3CallbackProxy { public interface BusyHandlerCallback extends CallbackProxy {
/** /**
Must function as documented for the C-level Must function as documented for the C-level
sqlite3_busy_handler() callback argument, minus the (void*) sqlite3_busy_handler() callback argument, minus the (void*)

View File

@ -41,4 +41,4 @@ package org.sqlite.jni;
<p>2) They all have a {@code call()} method but its signature is <p>2) They all have a {@code call()} method but its signature is
callback-specific. callback-specific.
*/ */
public interface SQLite3CallbackProxy {} public interface CallbackProxy {}

View File

@ -20,7 +20,7 @@ import org.sqlite.jni.annotation.NotNull;
@see AbstractCollationCallback @see AbstractCollationCallback
*/ */
public interface CollationCallback public interface CollationCallback
extends SQLite3CallbackProxy, XDestroyCallback { extends CallbackProxy, XDestroyCallback {
/** /**
Must compare the given byte arrays and return the result using Must compare the given byte arrays and return the result using
{@code memcmp()} semantics. {@code memcmp()} semantics.

View File

@ -16,7 +16,7 @@ package org.sqlite.jni;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_collation_needed}. Callback for use with {@link SQLite3Jni#sqlite3_collation_needed}.
*/ */
public interface CollationNeededCallback extends SQLite3CallbackProxy { public interface CollationNeededCallback extends CallbackProxy {
/** /**
Has the same semantics as the C-level sqlite3_create_collation() Has the same semantics as the C-level sqlite3_create_collation()
callback. callback.

View File

@ -16,7 +16,7 @@ package org.sqlite.jni;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_commit_hook}. Callback for use with {@link SQLite3Jni#sqlite3_commit_hook}.
*/ */
public interface CommitHookCallback extends SQLite3CallbackProxy { public interface CommitHookCallback extends CallbackProxy {
/** /**
Works as documented for the C-level sqlite3_commit_hook() Works as documented for the C-level sqlite3_commit_hook()
callback. Must not throw. callback. Must not throw.

View File

@ -1,5 +1,5 @@
/* /*
** 2023-07-21 ** 2023-08-23
** **
** The author disclaims copyright to this source code. In place of ** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing: ** a legal notice, here is a blessing:
@ -14,12 +14,12 @@
package org.sqlite.jni; package org.sqlite.jni;
/** /**
A helper class which simply holds a single value. Its current use A callback for use with sqlite3_config().
is for communicating values out of anonymous classes, as doing so
requires a "final" reference.
*/ */
public class ValueHolder<T> { public interface ConfigLogCallback {
public T value; /**
public ValueHolder(){} Must function as described for a C-level callback for
public ValueHolder(T v){value = v;} {@link SQLite3Jni#sqlite3_config(ConfigLogCallback)}, with the slight signature change.
*/
void call(int errCode, String msg);
} }

View File

@ -64,6 +64,27 @@ public final class OutputPointer {
} }
} }
/**
Output pointer for sqlite3_blob_open(). These
pointers can only be set by the JNI layer, not by client-level
code.
*/
public static final class sqlite3_blob {
private org.sqlite.jni.sqlite3_blob value;
/** Initializes with a null value. */
public sqlite3_blob(){value = null;}
/** Sets the current value to null. */
public void clear(){value = null;}
/** Returns the current value. */
public final org.sqlite.jni.sqlite3_blob get(){return value;}
/** Equivalent to calling get() then clear(). */
public final org.sqlite.jni.sqlite3_blob take(){
final org.sqlite.jni.sqlite3_blob v = value;
value = null;
return v;
}
}
/** /**
Output pointer for use with routines, such as sqlite3_prepare(), Output pointer for use with routines, such as sqlite3_prepare(),
which return a statement handle via an output pointer. These which return a statement handle via an output pointer. These
@ -108,6 +129,26 @@ public final class OutputPointer {
} }
} }
/**
Output pointer for use with native routines which return booleans
via integer output pointers.
*/
public static final class Bool {
/**
This is public for ease of use. Accessors are provided for
consistency with the higher-level types.
*/
public boolean value;
/** Initializes with the value 0. */
public Bool(){this(false);}
/** Initializes with the value v. */
public Bool(boolean v){value = v;}
/** Returns the current value. */
public final boolean get(){return value;}
/** Sets the current value to v. */
public final void set(boolean v){value = v;}
}
/** /**
Output pointer for use with native routines which return integers via Output pointer for use with native routines which return integers via
output pointers. output pointers.

View File

@ -16,7 +16,7 @@ package org.sqlite.jni;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_preupdate_hook}. Callback for use with {@link SQLite3Jni#sqlite3_preupdate_hook}.
*/ */
public interface PreupdateHookCallback extends SQLite3CallbackProxy { public interface PreupdateHookCallback extends CallbackProxy {
/** /**
Must function as described for the C-level sqlite3_preupdate_hook() Must function as described for the C-level sqlite3_preupdate_hook()
callback. callback.

View File

@ -16,7 +16,7 @@ package org.sqlite.jni;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_progress_handler}. Callback for use with {@link SQLite3Jni#sqlite3_progress_handler}.
*/ */
public interface ProgressHandlerCallback extends SQLite3CallbackProxy { public interface ProgressHandlerCallback extends CallbackProxy {
/** /**
Works as documented for the C-level sqlite3_progress_handler() callback. Works as documented for the C-level sqlite3_progress_handler() callback.

View File

@ -16,7 +16,7 @@ package org.sqlite.jni;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_rollback_hook}. Callback for use with {@link SQLite3Jni#sqlite3_rollback_hook}.
*/ */
public interface RollbackHookCallback extends SQLite3CallbackProxy { public interface RollbackHookCallback extends CallbackProxy {
/** /**
Works as documented for the C-level sqlite3_rollback_hook() Works as documented for the C-level sqlite3_rollback_hook()
callback. callback.

View File

@ -165,6 +165,26 @@ public final class SQLite3Jni {
@Canonical @Canonical
public static native int sqlite3_auto_extension(@NotNull AutoExtensionCallback callback); public static native int sqlite3_auto_extension(@NotNull AutoExtensionCallback callback);
@Canonical
public static native int sqlite3_backup_finish(@NotNull sqlite3_backup b);
@Canonical
public static native sqlite3_backup sqlite3_backup_init(
@NotNull sqlite3 dbDest, @NotNull String destTableName,
@NotNull sqlite3 dbSrc, @NotNull String srcTableName
);
@Canonical
public static native int sqlite3_backup_pagecount(@NotNull sqlite3_backup b);
@Canonical
public static native int sqlite3_backup_remaining(@NotNull sqlite3_backup b);
@Canonical
public static native int sqlite3_backup_step(
@NotNull sqlite3_backup b, int nPage
);
/** /**
Results are undefined if data is not null and n<0 || n>=data.length. Results are undefined if data is not null and n<0 || n>=data.length.
*/ */
@ -217,10 +237,17 @@ public final class SQLite3Jni {
/** /**
Requires that paramName be a NUL-terminated UTF-8 string. Requires that paramName be a NUL-terminated UTF-8 string.
This overload is private because: (A) to keep users from
inadvertently passing non-NUL-terminated byte arrays (an easy
thing to do). (B) it is cheaper to NUL-terminate the
String-to-byte-array conversion in the public-facing Java-side
overload than to do that in C, so that signature is the
public-facing one.
*/ */
@Canonical @Canonical
public static native int sqlite3_bind_parameter_index( private static native int sqlite3_bind_parameter_index(
@NotNull sqlite3_stmt stmt, byte[] paramName @NotNull sqlite3_stmt stmt, @NotNull byte[] paramName
); );
@Canonical @Canonical
@ -231,6 +258,11 @@ public final class SQLite3Jni {
return sqlite3_bind_parameter_index(stmt, utf8); return sqlite3_bind_parameter_index(stmt, utf8);
} }
@Canonical
public static native String sqlite3_bind_parameter_name(
@NotNull sqlite3_stmt stmt, int index
);
/** /**
Works like the C-level sqlite3_bind_text() but assumes Works like the C-level sqlite3_bind_text() but assumes
SQLITE_TRANSIENT for the final C API parameter. The byte array is SQLITE_TRANSIENT for the final C API parameter. The byte array is
@ -315,10 +347,50 @@ public final class SQLite3Jni {
@NotNull sqlite3_stmt stmt, int ndx, long n @NotNull sqlite3_stmt stmt, int ndx, long n
); );
@Canonical
public static native int sqlite3_blob_bytes(@NotNull sqlite3_blob blob);
@Canonical
public static native int sqlite3_blob_close(@Nullable sqlite3_blob blob);
@Canonical
public static native int sqlite3_blob_open(
@NotNull sqlite3 db, @NotNull String dbName,
@NotNull String tableName, @NotNull String columnName,
long iRow, int flags, @NotNull OutputPointer.sqlite3_blob out
);
/** /**
As for the C-level function of the same name, with a BusyHandlerCallback Convenience overload.
instance in place of a callback function. Pass it a null handler */
to clear the busy handler. public static sqlite3_blob sqlite3_blob_open(
@NotNull sqlite3 db, @NotNull String dbName,
@NotNull String tableName, @NotNull String columnName,
long iRow, int flags ){
final OutputPointer.sqlite3_blob out = new OutputPointer.sqlite3_blob();
sqlite3_blob_open(db, dbName, tableName, columnName, iRow, flags, out);
return out.take();
};
@Canonical
public static native int sqlite3_blob_read(
@NotNull sqlite3_blob b, @NotNull byte[] target, int iOffset
);
@Canonical
public static native int sqlite3_blob_reopen(
@NotNull sqlite3_blob out, long newRowId
);
@Canonical
public static native int sqlite3_blob_write(
@NotNull sqlite3_blob out, @NotNull byte[] bytes, int iOffset
);
/**
As for the C-level function of the same name, with a
BusyHandlerCallback instance in place of a callback
function. Pass it a null handler to clear the busy handler.
*/ */
@Canonical @Canonical
public static native int sqlite3_busy_handler( public static native int sqlite3_busy_handler(
@ -416,24 +488,15 @@ public final class SQLite3Jni {
); );
/** /**
Returns the given column's contents as UTF-8-encoded (not MUTF-8) Functions identially to the C API, and this note is just to
text. Returns null if the C-level sqlite3_column_text() returns stress that the returned bytes are encoded as UTF-8. It returns
NULL. null if the underlying C-level sqlite3_column_text() returns NULL
or on allocation error.
@see #sqlite3_column_text @see #sqlite3_column_text16(sqlite3_stmt,int)
*/ */
@Canonical(cname="sqlite3_column_text") @Canonical
public static native byte[] sqlite3_column_text_utf8( public static native byte[] sqlite3_column_text(
@NotNull sqlite3_stmt stmt, int ndx
);
/**
Provides the same feature as the same-named C API but returns the
text in Java-native encoding rather than the C API's UTF-8.
@see #sqlite3_column_text16
*/
public static native String sqlite3_column_text(
@NotNull sqlite3_stmt stmt, int ndx @NotNull sqlite3_stmt stmt, int ndx
); );
@ -471,7 +534,7 @@ public final class SQLite3Jni {
// } // }
// case SQLITE_FLOAT: rv = new Double(sqlite3_value_double(v)); break; // case SQLITE_FLOAT: rv = new Double(sqlite3_value_double(v)); break;
// case SQLITE_BLOB: rv = sqlite3_value_blob(v); break; // case SQLITE_BLOB: rv = sqlite3_value_blob(v); break;
// case SQLITE_TEXT: rv = sqlite3_value_text(v); break; // case SQLITE_TEXT: rv = sqlite3_value_text16(v); break;
// default: break; // default: break;
// } // }
// } // }
@ -491,18 +554,13 @@ public final class SQLite3Jni {
/** /**
This functions like C's sqlite3_collation_needed16() because This functions like C's sqlite3_collation_needed16() because
Java's string type is compatible with that interface. Java's string type is inherently compatible with that interface.
*/ */
@Canonical @Canonical
public static native int sqlite3_collation_needed( public static native int sqlite3_collation_needed(
@NotNull sqlite3 db, @Nullable CollationNeededCallback callback @NotNull sqlite3 db, @Nullable CollationNeededCallback callback
); );
@Canonical
public static native sqlite3 sqlite3_context_db_handle(
@NotNull sqlite3_context cx
);
@Canonical @Canonical
public static native CommitHookCallback sqlite3_commit_hook( public static native CommitHookCallback sqlite3_commit_hook(
@NotNull sqlite3 db, @Nullable CommitHookCallback hook @NotNull sqlite3 db, @Nullable CommitHookCallback hook
@ -518,6 +576,24 @@ public final class SQLite3Jni {
@NotNull String optName @NotNull String optName
); );
/**
This implementation is private because it's too easy to pass it
non-NUL-terminated arrays.
*/
@Canonical
private static native int sqlite3_complete(
@NotNull byte[] nulTerminatedUtf8Sql
);
@Canonical()
public static int sqlite3_complete(@NotNull String sql){
/* Design note: we don't implement this in native code because we
won't get a NUL-terminated string there unless we make our own
copy to add a terminator. That's much easier to do here. */
return sqlite3_complete( (sql+"\0").getBytes(StandardCharsets.UTF_8) );
}
/** /**
<p>Works like in the C API with the exception that it only supports <p>Works like in the C API with the exception that it only supports
the following subset of configution flags: the following subset of configution flags:
@ -532,7 +608,6 @@ public final class SQLite3Jni {
<p>Note that sqlite3_config() is not threadsafe with regards to <p>Note that sqlite3_config() is not threadsafe with regards to
the rest of the library. This must not be called when any other the rest of the library. This must not be called when any other
library APIs are being called. library APIs are being called.
*/ */
@Canonical(comment="Option subset: "+ @Canonical(comment="Option subset: "+
"SQLITE_CONFIG_SINGLETHREAD, SQLITE_CONFIG_MULTITHREAD, "+ "SQLITE_CONFIG_SINGLETHREAD, SQLITE_CONFIG_MULTITHREAD, "+
@ -552,11 +627,22 @@ public final class SQLite3Jni {
<p>Note that sqlite3_config() is not threadsafe with regards to <p>Note that sqlite3_config() is not threadsafe with regards to
the rest of the library. This must not be called when any other the rest of the library. This must not be called when any other
library APIs are being called. library APIs are being called.
*/ */
@Canonical(comment="Option subset: SQLITE_CONFIG_SQLLOG") @Canonical(comment="Option subset: SQLITE_CONFIG_SQLLOG")
public static native int sqlite3_config( @Nullable ConfigSqllogCallback logger ); public static native int sqlite3_config( @Nullable ConfigSqllogCallback logger );
/**
The sqlite3_config() overload for handling the SQLITE_CONFIG_LOG
option.
*/
@Canonical(comment="Option subset: SQLITE_CONFIG_LOG")
public static native int sqlite3_config( @Nullable ConfigLogCallback logger );
@Canonical
public static native sqlite3 sqlite3_context_db_handle(
@NotNull sqlite3_context cx
);
@Canonical @Canonical
public static native int sqlite3_create_collation( public static native int sqlite3_create_collation(
@NotNull sqlite3 db, @NotNull String name, int eTextRep, @NotNull sqlite3 db, @NotNull String name, int eTextRep,
@ -612,6 +698,9 @@ public final class SQLite3Jni {
@Canonical @Canonical
public static native sqlite3 sqlite3_db_handle( @NotNull sqlite3_stmt stmt ); public static native sqlite3 sqlite3_db_handle( @NotNull sqlite3_stmt stmt );
@Canonical
public static native int sqlite3_db_release_memory(sqlite3 db);
@Canonical @Canonical
public static native int sqlite3_db_status( public static native int sqlite3_db_status(
@NotNull sqlite3 db, int op, @NotNull OutputPointer.Int32 pCurrent, @NotNull sqlite3 db, int op, @NotNull OutputPointer.Int32 pCurrent,
@ -621,6 +710,12 @@ public final class SQLite3Jni {
@Canonical @Canonical
public static native int sqlite3_errcode(@NotNull sqlite3 db); public static native int sqlite3_errcode(@NotNull sqlite3 db);
@Canonical
public static native String sqlite3_errmsg(@NotNull sqlite3 db);
@Canonical
public static native String sqlite3_errstr(int resultCode);
@Canonical @Canonical
public static native String sqlite3_expanded_sql(@NotNull sqlite3_stmt stmt); public static native String sqlite3_expanded_sql(@NotNull sqlite3_stmt stmt);
@ -633,10 +728,12 @@ public final class SQLite3Jni {
); );
@Canonical @Canonical
public static native String sqlite3_errmsg(@NotNull sqlite3 db); public static native boolean sqlite3_get_autocommit(@NotNull sqlite3 db);
@Canonical @Canonical
public static native String sqlite3_errstr(int resultCode); public static native Object sqlite3_get_auxdata(
@NotNull sqlite3_context cx, int n
);
/** /**
Note that the returned byte offset values assume UTF-8-encoded Note that the returned byte offset values assume UTF-8-encoded
@ -657,6 +754,16 @@ public final class SQLite3Jni {
@Canonical @Canonical
public static native boolean sqlite3_is_interrupted(@NotNull sqlite3 db); public static native boolean sqlite3_is_interrupted(@NotNull sqlite3 db);
@Canonical
public static native boolean sqlite3_keyword_check(@NotNull String word);
@Canonical
public static native int sqlite3_keyword_count();
@Canonical
public static native String sqlite3_keyword_name(int index);
@Canonical @Canonical
public static native long sqlite3_last_insert_rowid(@NotNull sqlite3 db); public static native long sqlite3_last_insert_rowid(@NotNull sqlite3 db);
@ -666,6 +773,9 @@ public final class SQLite3Jni {
@Canonical @Canonical
public static native int sqlite3_libversion_number(); public static native int sqlite3_libversion_number();
@Canonical
public static native int sqlite3_limit(@NotNull sqlite3 db, int id, int newVal);
/** /**
Works like its C counterpart and makes the native pointer of the Works like its C counterpart and makes the native pointer of the
underling (sqlite3*) object available via underling (sqlite3*) object available via
@ -758,6 +868,7 @@ public final class SQLite3Jni {
<p>Several overloads provided simplified call signatures. <p>Several overloads provided simplified call signatures.
*/ */
@Canonical
public static int sqlite3_prepare( public static int sqlite3_prepare(
@NotNull sqlite3 db, @NotNull byte[] sqlUtf8, @NotNull sqlite3 db, @NotNull byte[] sqlUtf8,
@NotNull OutputPointer.sqlite3_stmt outStmt, @NotNull OutputPointer.sqlite3_stmt outStmt,
@ -812,6 +923,7 @@ public final class SQLite3Jni {
output paramter is returned as the index offset into the given output paramter is returned as the index offset into the given
byte array at which SQL parsing stopped. byte array at which SQL parsing stopped.
*/ */
@Canonical
public static int sqlite3_prepare_v2( public static int sqlite3_prepare_v2(
@NotNull sqlite3 db, @NotNull byte[] sqlUtf8, @NotNull sqlite3 db, @NotNull byte[] sqlUtf8,
@NotNull OutputPointer.sqlite3_stmt outStmt, @NotNull OutputPointer.sqlite3_stmt outStmt,
@ -862,6 +974,7 @@ public final class SQLite3Jni {
output paramter is returned as the index offset into the given output paramter is returned as the index offset into the given
byte array at which SQL parsing stopped. byte array at which SQL parsing stopped.
*/ */
@Canonical
public static int sqlite3_prepare_v3( public static int sqlite3_prepare_v3(
@NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int prepFlags, @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int prepFlags,
@NotNull OutputPointer.sqlite3_stmt outStmt, @NotNull OutputPointer.sqlite3_stmt outStmt,
@ -972,6 +1085,12 @@ public final class SQLite3Jni {
@NotNull sqlite3 db, int n, @Nullable ProgressHandlerCallback h @NotNull sqlite3 db, int n, @Nullable ProgressHandlerCallback h
); );
@Canonical
public static native void sqlite3_randomness(byte[] target);
@Canonical
public static native int sqlite3_release_memory(int n);
@Canonical @Canonical
public static native int sqlite3_reset(@NotNull sqlite3_stmt stmt); public static native int sqlite3_reset(@NotNull sqlite3_stmt stmt);
@ -992,20 +1111,22 @@ public final class SQLite3Jni {
The main sqlite3_result_error() impl of which all others are The main sqlite3_result_error() impl of which all others are
proxies. eTextRep must be one of SQLITE_UTF8 or SQLITE_UTF16 and proxies. eTextRep must be one of SQLITE_UTF8 or SQLITE_UTF16 and
msg must be encoded correspondingly. Any other eTextRep value msg must be encoded correspondingly. Any other eTextRep value
results in the C-level sqlite3_result_error() being called with results in the C-level sqlite3_result_error() being called with a
a complaint about the invalid argument. complaint about the invalid argument.
*/ */
@Canonical @Canonical
private static native void sqlite3_result_error( private static native void sqlite3_result_error(
@NotNull sqlite3_context cx, @NotNull byte[] msg, int eTextRep @NotNull sqlite3_context cx, @NotNull byte[] msg, int eTextRep
); );
@Canonical
public static void sqlite3_result_error( public static void sqlite3_result_error(
@NotNull sqlite3_context cx, @NotNull byte[] utf8 @NotNull sqlite3_context cx, @NotNull byte[] utf8
){ ){
sqlite3_result_error(cx, utf8, SQLITE_UTF8); sqlite3_result_error(cx, utf8, SQLITE_UTF8);
} }
@Canonical
public static void sqlite3_result_error( public static void sqlite3_result_error(
@NotNull sqlite3_context cx, @NotNull String msg @NotNull sqlite3_context cx, @NotNull String msg
){ ){
@ -1163,11 +1284,16 @@ public final class SQLite3Jni {
@NotNull sqlite3_context cx, long n @NotNull sqlite3_context cx, long n
); );
/**
This overload is private because its final parameter is arguably
unnecessary in Java.
*/
@Canonical @Canonical
private static native void sqlite3_result_blob( private static native void sqlite3_result_blob(
@NotNull sqlite3_context cx, @Nullable byte[] blob, int maxLen @NotNull sqlite3_context cx, @Nullable byte[] blob, int maxLen
); );
@Canonical
public static void sqlite3_result_blob( public static void sqlite3_result_blob(
@NotNull sqlite3_context cx, @Nullable byte[] blob @NotNull sqlite3_context cx, @Nullable byte[] blob
){ ){
@ -1186,31 +1312,41 @@ public final class SQLite3Jni {
</ul> </ul>
If @param maxLen is larger than blob.length, it is truncated to <p>If @param maxLen is larger than blob.length, it is truncated
that value. If it is negative, results are undefined. to that value. If it is negative, results are undefined.</p>
<p>This overload is private because its final parameter is
arguably unnecessary in Java.</p>
*/ */
@Canonical @Canonical
private static native void sqlite3_result_blob64( private static native void sqlite3_result_blob64(
@NotNull sqlite3_context cx, @Nullable byte[] blob, long maxLen @NotNull sqlite3_context cx, @Nullable byte[] blob, long maxLen
); );
@Canonical
public static void sqlite3_result_blob64( public static void sqlite3_result_blob64(
@NotNull sqlite3_context cx, @Nullable byte[] blob @NotNull sqlite3_context cx, @Nullable byte[] blob
){ ){
sqlite3_result_blob64(cx, blob, (long)(null==blob ? 0 : blob.length)); sqlite3_result_blob64(cx, blob, (long)(null==blob ? 0 : blob.length));
} }
/**
This overload is private because its final parameter is
arguably unnecessary in Java.
*/
@Canonical @Canonical
private static native void sqlite3_result_text( private static native void sqlite3_result_text(
@NotNull sqlite3_context cx, @Nullable byte[] utf8, int maxLen @NotNull sqlite3_context cx, @Nullable byte[] utf8, int maxLen
); );
@Canonical
public static void sqlite3_result_text( public static void sqlite3_result_text(
@NotNull sqlite3_context cx, @Nullable byte[] utf8 @NotNull sqlite3_context cx, @Nullable byte[] utf8
){ ){
sqlite3_result_text(cx, utf8, null==utf8 ? 0 : utf8.length); sqlite3_result_text(cx, utf8, null==utf8 ? 0 : utf8.length);
} }
@Canonical
public static void sqlite3_result_text( public static void sqlite3_result_text(
@NotNull sqlite3_context cx, @Nullable String text @NotNull sqlite3_context cx, @Nullable String text
){ ){
@ -1240,6 +1376,9 @@ public final class SQLite3Jni {
text.length, it is silently truncated to text.length. If it is text.length, it is silently truncated to text.length. If it is
negative, results are undefined. If text is null, the subsequent negative, results are undefined. If text is null, the subsequent
arguments are ignored. arguments are ignored.
This overload is private because its maxLength parameter is
arguably unnecessary in Java.
*/ */
@Canonical @Canonical
private static native void sqlite3_result_text64( private static native void sqlite3_result_text64(
@ -1251,12 +1390,14 @@ public final class SQLite3Jni {
Sets the current UDF result to the given bytes, which are assumed Sets the current UDF result to the given bytes, which are assumed
be encoded in UTF-16 using the platform's byte order. be encoded in UTF-16 using the platform's byte order.
*/ */
@Canonical
public static void sqlite3_result_text16( public static void sqlite3_result_text16(
@NotNull sqlite3_context cx, @Nullable byte[] utf16 @NotNull sqlite3_context cx, @Nullable byte[] utf16
){ ){
sqlite3_result_text64(cx, utf16, utf16.length, SQLITE_UTF16); sqlite3_result_text64(cx, utf16, utf16.length, SQLITE_UTF16);
} }
@Canonical
public static void sqlite3_result_text16( public static void sqlite3_result_text16(
@NotNull sqlite3_context cx, @Nullable String text @NotNull sqlite3_context cx, @Nullable String text
){ ){
@ -1277,6 +1418,11 @@ public final class SQLite3Jni {
@NotNull sqlite3 db, @Nullable AuthorizerCallback auth @NotNull sqlite3 db, @Nullable AuthorizerCallback auth
); );
@Canonical
public static native void sqlite3_set_auxdata(
@NotNull sqlite3_context cx, int n, @Nullable Object data
);
@Canonical @Canonical
public static native void sqlite3_set_last_insert_rowid( public static native void sqlite3_set_last_insert_rowid(
@NotNull sqlite3 db, long rowid @NotNull sqlite3 db, long rowid
@ -1304,7 +1450,6 @@ public final class SQLite3Jni {
@Canonical @Canonical
public static native String sqlite3_sql(@NotNull sqlite3_stmt stmt); public static native String sqlite3_sql(@NotNull sqlite3_stmt stmt);
@Canonical @Canonical
public static native int sqlite3_status( public static native int sqlite3_status(
int op, @NotNull OutputPointer.Int32 pCurrent, int op, @NotNull OutputPointer.Int32 pCurrent,
@ -1320,15 +1465,39 @@ public final class SQLite3Jni {
@Canonical @Canonical
public static native int sqlite3_step(@NotNull sqlite3_stmt stmt); public static native int sqlite3_step(@NotNull sqlite3_stmt stmt);
@Canonical
public static native int sqlite3_stmt_explain(
@NotNull sqlite3_stmt stmt, int op
);
@Canonical
public static native int sqlite3_stmt_isexplain(@NotNull sqlite3_stmt stmt);
@Canonical
public static native boolean sqlite3_stmt_readonly(@NotNull sqlite3_stmt stmt);
@Canonical
public static native int sqlite3_stmt_status(
@NotNull sqlite3_stmt stmt, int op, boolean reset
);
/** /**
Internal impl of the public sqlite3_strglob() method. Neither Internal impl of the public sqlite3_strglob() method. Neither
argument may be NULL and both MUST be NUL-terminated UTF-8. argument may be null and both must be NUL-terminated UTF-8.
This overload is private because: (A) to keep users from
inadvertently passing non-NUL-terminated byte arrays (an easy
thing to do). (B) it is cheaper to NUL-terminate the
String-to-byte-array conversion in the Java implementation
(sqlite3_strglob(String,String)) than to do that in C, so that
signature is the public-facing one.
*/ */
@Canonical @Canonical
private static native int sqlite3_strglob( private static native int sqlite3_strglob(
@NotNull byte[] glob, @NotNull byte[] txt @NotNull byte[] glob, @NotNull byte[] nullTerminatedUtf8
); );
@Canonical
public static int sqlite3_strglob( public static int sqlite3_strglob(
@NotNull String glob, @NotNull String txt @NotNull String glob, @NotNull String txt
){ ){
@ -1339,14 +1508,15 @@ public final class SQLite3Jni {
} }
/** /**
Internal impl of the public sqlite3_strlike() method. Neither The LIKE counterpart of the private sqlite3_strglob() method.
argument may be NULL and both MUST be NUL-terminated UTF-8.
*/ */
@Canonical @Canonical
private static native int sqlite3_strlike( private static native int sqlite3_strlike(
@NotNull byte[] glob, @NotNull byte[] txt, int escChar @NotNull byte[] glob, @NotNull byte[] nullTerminatedUtf8,
int escChar
); );
@Canonical
public static int sqlite3_strlike( public static int sqlite3_strlike(
@NotNull String glob, @NotNull String txt, char escChar @NotNull String glob, @NotNull String txt, char escChar
){ ){
@ -1357,6 +1527,48 @@ public final class SQLite3Jni {
); );
} }
@Canonical
public static native int sqlite3_system_errno(@NotNull sqlite3 db);
@Canonical
public static native int sqlite3_table_column_metadata(
@NotNull sqlite3 db, @NotNull String zDbName,
@NotNull String zTableName, @NotNull String zColumnName,
@Nullable OutputPointer.String pzDataType,
@Nullable OutputPointer.String pzCollSeq,
@Nullable OutputPointer.Bool pNotNull,
@Nullable OutputPointer.Bool pPrimaryKey,
@Nullable OutputPointer.Bool pAutoinc
);
/**
Convenience overload which returns its results via a single
output object. If this function returns non-0 (error), the the
contents of the output object are not modified.
*/
public static int sqlite3_table_column_metadata(
@NotNull sqlite3 db, @NotNull String zDbName,
@NotNull String zTableName, @NotNull String zColumnName,
@NotNull TableColumnMetadata out){
return sqlite3_table_column_metadata(
db, zDbName, zTableName, zColumnName,
out.pzDataType, out.pzCollSeq, out.pNotNull,
out.pPrimaryKey, out.pAutoinc);
}
/**
Convenience overload which returns the column metadata object on
success and null on error.
*/
public static TableColumnMetadata sqlite3_table_column_metadata(
@NotNull sqlite3 db, @NotNull String zDbName,
@NotNull String zTableName, @NotNull String zColumnName){
final TableColumnMetadata out = new TableColumnMetadata();
return 0==sqlite3_table_column_metadata(
db, zDbName, zTableName, zColumnName, out
) ? out : null;
}
@Canonical @Canonical
public static native int sqlite3_threadsafe(); public static native int sqlite3_threadsafe();
@ -1381,10 +1593,25 @@ public final class SQLite3Jni {
); );
@Canonical @Canonical
public static native UpdateHookCallback sqlite3_update_hook( public static native int sqlite3_txn_state(
sqlite3 db, UpdateHookCallback hook @NotNull sqlite3 db, @Nullable String zSchema
); );
@Canonical
public static native UpdateHookCallback sqlite3_update_hook(
@NotNull sqlite3 db, @Nullable UpdateHookCallback hook
);
/*
Note that:
void * sqlite3_user_data(sqlite3_context*)
Is not relevant in the JNI binding, as its feature is replaced by
the ability to pass an object, including any relevant state, to
sqlite3_create_function().
*/
@Canonical @Canonical
public static native byte[] sqlite3_value_blob(@NotNull sqlite3_value v); public static native byte[] sqlite3_value_blob(@NotNull sqlite3_value v);
@ -1439,30 +1666,14 @@ public final class SQLite3Jni {
} }
/** /**
Returns the given value as UTF-8-encoded bytes, or null if the Functions identially to the C API, and this note is just to
underlying C-level sqlite3_value_text() returns NULL. stress that the returned bytes are encoded as UTF-8. It returns
null if the underlying C-level sqlite3_value_text() returns NULL
or on allocation error.
*/ */
@Canonical(cname="sqlite3_value_text", @Canonical
comment="Renamed because its String-returning overload would "+ public static native byte[] sqlite3_value_text(@NotNull sqlite3_value v);
"otherwise be ambiguous.")
public static native byte[] sqlite3_value_text_utf8(@NotNull sqlite3_value v);
/**
Provides the same feature as the same-named C API but returns the
text in Java-native encoding rather than the C API's UTF-8.
@see #sqlite3_value_text16
*/
public static native String sqlite3_value_text(@NotNull sqlite3_value v);
/**
In the Java layer, sqlite3_value_text() and
sqlite3_value_text16() are functionally equivalent, the
difference being only where the encoding to UTF-16 (if necessary)
takes place. This function does it via SQLite and
sqlite3_value_text() fetches UTF-8 (SQLite's default encoding)
and converts it to UTF-16 in Java.
*/
@Canonical @Canonical
public static native String sqlite3_value_text16(@NotNull sqlite3_value v); public static native String sqlite3_value_text16(@NotNull sqlite3_value v);
@ -1497,10 +1708,6 @@ public final class SQLite3Jni {
public static final String SQLITE_VERSION = sqlite3_libversion(); public static final String SQLITE_VERSION = sqlite3_libversion();
public static final String SQLITE_SOURCE_ID = sqlite3_sourceid(); public static final String SQLITE_SOURCE_ID = sqlite3_sourceid();
// Initialized at static init time to the build-time value of
// SQLITE_THREADSAFE.
public static int SQLITE_THREADSAFE = -1;
// access // access
public static final int SQLITE_ACCESS_EXISTS = 0; public static final int SQLITE_ACCESS_EXISTS = 0;
public static final int SQLITE_ACCESS_READWRITE = 1; public static final int SQLITE_ACCESS_READWRITE = 1;
@ -1713,36 +1920,19 @@ public final class SQLite3Jni {
public static final int SQLITE_IOCAP_IMMUTABLE = 8192; public static final int SQLITE_IOCAP_IMMUTABLE = 8192;
public static final int SQLITE_IOCAP_BATCH_ATOMIC = 16384; public static final int SQLITE_IOCAP_BATCH_ATOMIC = 16384;
// limits. These get injected at init-time so that they stay in sync // limits
// with the compile-time options. This unfortunately means they are public static final int SQLITE_LIMIT_LENGTH = 0;
// not final, but keeping them in sync with their C values seems public static final int SQLITE_LIMIT_SQL_LENGTH = 1;
// more important than protecting users from assigning to these public static final int SQLITE_LIMIT_COLUMN = 2;
// (with unpredictable results). public static final int SQLITE_LIMIT_EXPR_DEPTH = 3;
public static int SQLITE_MAX_ALLOCATION_SIZE = -1; public static final int SQLITE_LIMIT_COMPOUND_SELECT = 4;
public static int SQLITE_LIMIT_LENGTH = -1; public static final int SQLITE_LIMIT_VDBE_OP = 5;
public static int SQLITE_MAX_LENGTH = -1; public static final int SQLITE_LIMIT_FUNCTION_ARG = 6;
public static int SQLITE_LIMIT_SQL_LENGTH = -1; public static final int SQLITE_LIMIT_ATTACHED = 7;
public static int SQLITE_MAX_SQL_LENGTH = -1; public static final int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8;
public static int SQLITE_LIMIT_COLUMN = -1; public static final int SQLITE_LIMIT_VARIABLE_NUMBER = 9;
public static int SQLITE_MAX_COLUMN = -1; public static final int SQLITE_LIMIT_TRIGGER_DEPTH = 10;
public static int SQLITE_LIMIT_EXPR_DEPTH = -1; public static final int SQLITE_LIMIT_WORKER_THREADS = 11;
public static int SQLITE_MAX_EXPR_DEPTH = -1;
public static int SQLITE_LIMIT_COMPOUND_SELECT = -1;
public static int SQLITE_MAX_COMPOUND_SELECT = -1;
public static int SQLITE_LIMIT_VDBE_OP = -1;
public static int SQLITE_MAX_VDBE_OP = -1;
public static int SQLITE_LIMIT_FUNCTION_ARG = -1;
public static int SQLITE_MAX_FUNCTION_ARG = -1;
public static int SQLITE_LIMIT_ATTACHED = -1;
public static int SQLITE_MAX_ATTACHED = -1;
public static int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = -1;
public static int SQLITE_MAX_LIKE_PATTERN_LENGTH = -1;
public static int SQLITE_LIMIT_VARIABLE_NUMBER = -1;
public static int SQLITE_MAX_VARIABLE_NUMBER = -1;
public static int SQLITE_LIMIT_TRIGGER_DEPTH = -1;
public static int SQLITE_MAX_TRIGGER_DEPTH = -1;
public static int SQLITE_LIMIT_WORKER_THREADS = -1;
public static int SQLITE_MAX_WORKER_THREADS = -1;
// open flags // open flags
public static final int SQLITE_OPEN_READONLY = 1; public static final int SQLITE_OPEN_READONLY = 1;

View File

@ -0,0 +1,35 @@
/*
** 2023-07-21
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API.
*/
package org.sqlite.jni;
/**
A wrapper object for use with sqlite3_table_column_metadata().
They are populated only via that interface.
*/
public final class TableColumnMetadata {
OutputPointer.Bool pNotNull = new OutputPointer.Bool();
OutputPointer.Bool pPrimaryKey = new OutputPointer.Bool();
OutputPointer.Bool pAutoinc = new OutputPointer.Bool();
OutputPointer.String pzCollSeq = new OutputPointer.String();
OutputPointer.String pzDataType = new OutputPointer.String();
public TableColumnMetadata(){
}
public String getDataType(){ return pzDataType.value; }
public String getCollation(){ return pzCollSeq.value; }
public boolean isNotNull(){ return pNotNull.value; }
public boolean isPrimaryKey(){ return pPrimaryKey.value; }
public boolean isAutoincrement(){ return pAutoinc.value; }
}

View File

@ -38,6 +38,17 @@ import java.util.concurrent.Future;
@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) @java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD})
@interface SingleThreadOnly{} @interface SingleThreadOnly{}
/**
A helper class which simply holds a single value. Its current use
is for communicating values out of anonymous classes, as doing so
requires a "final" reference.
*/
class ValueHolder<T> {
public T value;
public ValueHolder(){}
public ValueHolder(T v){value = v;}
}
public class Tester1 implements Runnable { public class Tester1 implements Runnable {
//! True when running in multi-threaded mode. //! True when running in multi-threaded mode.
private static boolean mtMode = false; private static boolean mtMode = false;
@ -68,62 +79,67 @@ public class Tester1 implements Runnable {
static final Metrics metrics = new Metrics(); static final Metrics metrics = new Metrics();
public synchronized static void outln(){ public static synchronized void outln(){
if( !quietMode ){ if( !quietMode ){
System.out.println(""); System.out.println("");
} }
} }
public synchronized static void outln(Object val){ public static synchronized void outPrefix(){
if( !quietMode ){ if( !quietMode ){
System.out.print(Thread.currentThread().getName()+": "); System.out.print(Thread.currentThread().getName()+": ");
}
}
public static synchronized void outln(Object val){
if( !quietMode ){
outPrefix();
System.out.println(val); System.out.println(val);
} }
} }
public synchronized static void out(Object val){ public static synchronized void out(Object val){
if( !quietMode ){ if( !quietMode ){
System.out.print(val); System.out.print(val);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public synchronized static void out(Object... vals){ public static synchronized void out(Object... vals){
if( !quietMode ){ if( !quietMode ){
System.out.print(Thread.currentThread().getName()+": "); outPrefix();
for(Object v : vals) out(v); for(Object v : vals) out(v);
} }
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public synchronized static void outln(Object... vals){ public static synchronized void outln(Object... vals){
if( !quietMode ){ if( !quietMode ){
out(vals); out("\n"); out(vals); out("\n");
} }
} }
static volatile int affirmCount = 0; static volatile int affirmCount = 0;
public synchronized static void affirm(Boolean v, String comment){ public static synchronized int affirm(Boolean v, String comment){
++affirmCount; ++affirmCount;
if( false ) assert( v /* prefer assert over exception if it's enabled because if( false ) assert( v /* prefer assert over exception if it's enabled because
the JNI layer sometimes has to suppress exceptions, the JNI layer sometimes has to suppress exceptions,
so they might be squelched on their way back to the so they might be squelched on their way back to the
top. */); top. */);
if( !v ) throw new RuntimeException(comment); if( !v ) throw new RuntimeException(comment);
return affirmCount;
} }
public static void affirm(Boolean v){ public static void affirm(Boolean v){
affirm(v, "Affirmation failed."); affirm(v, "Affirmation failed.");
} }
@ManualTest /* because testing this for threading is pointless */ @SingleThreadOnly /* because it's thread-agnostic */
private void test1(){ private void test1(){
affirm(sqlite3_libversion_number() == SQLITE_VERSION_NUMBER); affirm(sqlite3_libversion_number() == SQLITE_VERSION_NUMBER);
affirm(SQLITE_MAX_LENGTH > 0);
affirm(SQLITE_MAX_TRIGGER_DEPTH>0);
} }
static sqlite3 createNewDb(){ public static sqlite3 createNewDb(){
final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); final OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
int rc = sqlite3_open(":memory:", out); int rc = sqlite3_open(":memory:", out);
++metrics.dbOpen; ++metrics.dbOpen;
@ -141,11 +157,11 @@ public class Tester1 implements Runnable {
return db; return db;
} }
static void execSql(sqlite3 db, String[] sql){ public static void execSql(sqlite3 db, String[] sql){
execSql(db, String.join("", sql)); execSql(db, String.join("", sql));
} }
static int execSql(sqlite3 db, boolean throwOnError, String sql){ public static int execSql(sqlite3 db, boolean throwOnError, String sql){
OutputPointer.Int32 oTail = new OutputPointer.Int32(); OutputPointer.Int32 oTail = new OutputPointer.Int32();
final byte[] sqlUtf8 = sql.getBytes(StandardCharsets.UTF_8); final byte[] sqlUtf8 = sql.getBytes(StandardCharsets.UTF_8);
int pos = 0, n = 1; int pos = 0, n = 1;
@ -186,13 +202,13 @@ public class Tester1 implements Runnable {
return rc; return rc;
} }
static void execSql(sqlite3 db, String sql){ public static void execSql(sqlite3 db, String sql){
execSql(db, true, sql); execSql(db, true, sql);
} }
static sqlite3_stmt prepare(sqlite3 db, boolean throwOnError, String sql){ public static sqlite3_stmt prepare(sqlite3 db, boolean throwOnError, String sql){
final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt();
int rc = sqlite3_prepare(db, sql, outStmt); int rc = sqlite3_prepare_v2(db, sql, outStmt);
if( throwOnError ){ if( throwOnError ){
affirm( 0 == rc ); affirm( 0 == rc );
} }
@ -203,9 +219,11 @@ public class Tester1 implements Runnable {
} }
return rv; return rv;
} }
static sqlite3_stmt prepare(sqlite3 db, String sql){
public static sqlite3_stmt prepare(sqlite3 db, String sql){
return prepare(db, true, sql); return prepare(db, true, sql);
} }
private void showCompileOption(){ private void showCompileOption(){
int i = 0; int i = 0;
String optName; String optName;
@ -214,7 +232,15 @@ public class Tester1 implements Runnable {
outln("\t"+optName+"\t (used="+ outln("\t"+optName+"\t (used="+
sqlite3_compileoption_used(optName)+")"); sqlite3_compileoption_used(optName)+")");
} }
}
private void testCompileOption(){
int i = 0;
String optName;
for( ; null != (optName = sqlite3_compileoption_get(i)); ++i){
}
affirm( i > 10 );
affirm( null==sqlite3_compileoption_get(-1) );
} }
private void testOpenDb1(){ private void testOpenDb1(){
@ -260,6 +286,7 @@ public class Tester1 implements Runnable {
affirm(0 == rc); affirm(0 == rc);
sqlite3_stmt stmt = outStmt.take(); sqlite3_stmt stmt = outStmt.take();
affirm(0 != stmt.getNativePointer()); affirm(0 != stmt.getNativePointer());
affirm( !sqlite3_stmt_readonly(stmt) );
affirm( db == sqlite3_db_handle(stmt) ); affirm( db == sqlite3_db_handle(stmt) );
rc = sqlite3_step(stmt); rc = sqlite3_step(stmt);
if( SQLITE_DONE != rc ){ if( SQLITE_DONE != rc ){
@ -335,6 +362,7 @@ public class Tester1 implements Runnable {
affirm(1 == sqlite3_bind_parameter_count(stmt)); affirm(1 == sqlite3_bind_parameter_count(stmt));
final int paramNdx = sqlite3_bind_parameter_index(stmt, ":a"); final int paramNdx = sqlite3_bind_parameter_index(stmt, ":a");
affirm(1 == paramNdx); affirm(1 == paramNdx);
affirm( ":a".equals(sqlite3_bind_parameter_name(stmt, paramNdx)));
int total1 = 0; int total1 = 0;
long rowid = -1; long rowid = -1;
int changes = sqlite3_changes(db); int changes = sqlite3_changes(db);
@ -360,6 +388,7 @@ public class Tester1 implements Runnable {
affirm(sqlite3_changes64(db) > changes64); affirm(sqlite3_changes64(db) > changes64);
affirm(sqlite3_total_changes64(db) > changesT64); affirm(sqlite3_total_changes64(db) > changesT64);
stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;");
affirm( sqlite3_stmt_readonly(stmt) );
int total2 = 0; int total2 = 0;
while( SQLITE_ROW == sqlite3_step(stmt) ){ while( SQLITE_ROW == sqlite3_step(stmt) ){
total2 += sqlite3_column_int(stmt, 0); total2 += sqlite3_column_int(stmt, 0);
@ -425,7 +454,7 @@ public class Tester1 implements Runnable {
sqlite3 db = createNewDb(); sqlite3 db = createNewDb();
execSql(db, "CREATE TABLE t(a)"); execSql(db, "CREATE TABLE t(a)");
sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);");
String[] list1 = { "hell🤩", "w😃rld", "!" }; String[] list1 = { "hell🤩", "w😃rld", "!🤩" };
int rc; int rc;
int n = 0; int n = 0;
for( String e : list1 ){ for( String e : list1 ){
@ -445,15 +474,36 @@ public class Tester1 implements Runnable {
final sqlite3_value sv = sqlite3_value_dup(sqlite3_column_value(stmt,0)); final sqlite3_value sv = sqlite3_value_dup(sqlite3_column_value(stmt,0));
final String txt = sqlite3_column_text16(stmt, 0); final String txt = sqlite3_column_text16(stmt, 0);
sbuf.append( txt ); sbuf.append( txt );
affirm( txt.equals(sqlite3_column_text(stmt, 0)) ); affirm( txt.equals(new String(
affirm( txt.equals(sqlite3_value_text(sv)) ); sqlite3_column_text(stmt, 0),
StandardCharsets.UTF_8
)) );
affirm( txt.length() < sqlite3_value_bytes(sv) );
affirm( txt.equals(new String(
sqlite3_value_text(sv),
StandardCharsets.UTF_8)) );
affirm( txt.length() == sqlite3_value_bytes16(sv)/2 );
affirm( txt.equals(sqlite3_value_text16(sv)) ); affirm( txt.equals(sqlite3_value_text16(sv)) );
sqlite3_value_free(sv); sqlite3_value_free(sv);
++n; ++n;
} }
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
affirm(3 == n); affirm(3 == n);
affirm("w😃rldhell🤩!".equals(sbuf.toString())); affirm("w😃rldhell🤩!🤩".equals(sbuf.toString()));
stmt = prepare(db, "SELECT ?, ?");
rc = sqlite3_bind_text(stmt, 1, "");
affirm( 0==rc );
rc = sqlite3_bind_text(stmt, 2, (String)null);
affirm( 0==rc );
rc = sqlite3_step(stmt);
affirm( SQLITE_ROW==rc );
byte[] colBa = sqlite3_column_text(stmt, 0);
affirm( 0==colBa.length );
colBa = sqlite3_column_text(stmt, 1);
affirm( null==colBa );
sqlite3_finalize(stmt);
sqlite3_close_v2(db); sqlite3_close_v2(db);
} }
@ -573,7 +623,7 @@ public class Tester1 implements Runnable {
affirm( 1 == xDestroyCalled.value ); affirm( 1 == xDestroyCalled.value );
} }
@ManualTest /* because threading is meaningless here */ @SingleThreadOnly /* because it's thread-agnostic */
private void testToUtf8(){ private void testToUtf8(){
/** /**
https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html
@ -731,6 +781,7 @@ public class Tester1 implements Runnable {
} }
sqlite3_finalize(stmt); sqlite3_finalize(stmt);
affirm( 1 == n ); affirm( 1 == n );
affirm( 0==sqlite3_db_release_memory(db) );
sqlite3_close_v2(db); sqlite3_close_v2(db);
} }
@ -762,7 +813,7 @@ public class Tester1 implements Runnable {
int rc = sqlite3_create_function(db, "myfunc", 1, SQLITE_UTF8, func); int rc = sqlite3_create_function(db, "myfunc", 1, SQLITE_UTF8, func);
affirm(0 == rc); affirm(0 == rc);
sqlite3_stmt stmt = prepare(db, "select myfunc(a), myfunc(a+10) from t"); sqlite3_stmt stmt = prepare(db, "select myfunc(a), myfunc(a+10) from t");
affirm( null != stmt ); affirm( 0==sqlite3_stmt_status(stmt, SQLITE_STMTSTATUS_RUN, false) );
int n = 0; int n = 0;
if( SQLITE_ROW == sqlite3_step(stmt) ){ if( SQLITE_ROW == sqlite3_step(stmt) ){
int v = sqlite3_column_int(stmt, 0); int v = sqlite3_column_int(stmt, 0);
@ -774,6 +825,7 @@ public class Tester1 implements Runnable {
affirm( 1==n ); affirm( 1==n );
affirm(!xFinalNull.value); affirm(!xFinalNull.value);
sqlite3_reset(stmt); sqlite3_reset(stmt);
affirm( 1==sqlite3_stmt_status(stmt, SQLITE_STMTSTATUS_RUN, false) );
// Ensure that the accumulator is reset on subsequent calls... // Ensure that the accumulator is reset on subsequent calls...
n = 0; n = 0;
if( SQLITE_ROW == sqlite3_step(stmt) ){ if( SQLITE_ROW == sqlite3_step(stmt) ){
@ -940,8 +992,8 @@ public class Tester1 implements Runnable {
affirm( 7 == counter.value ); affirm( 7 == counter.value );
} }
@ManualTest /* because threads inherently break this test */ @SingleThreadOnly /* because threads inherently break this test */
private void testBusy(){ private static void testBusy(){
final String dbName = "_busy-handler.db"; final String dbName = "_busy-handler.db";
final OutputPointer.sqlite3 outDb = new OutputPointer.sqlite3(); final OutputPointer.sqlite3 outDb = new OutputPointer.sqlite3();
final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt();
@ -1224,10 +1276,13 @@ public class Tester1 implements Runnable {
} }
Exception err = null; Exception err = null;
try { try {
Class t = Class.forName("org.sqlite.jni.TesterFts5"); Class t = Class.forName("org.sqlite.jni.fts5.TesterFts5");
java.lang.reflect.Constructor ctor = t.getConstructor(); java.lang.reflect.Constructor ctor = t.getConstructor();
ctor.setAccessible(true); ctor.setAccessible(true);
final long timeStart = System.currentTimeMillis();
ctor.newInstance() /* will run all tests */; ctor.newInstance() /* will run all tests */;
final long timeEnd = System.currentTimeMillis();
outln("FTS5 Tests done in ",(timeEnd - timeStart),"ms");
}catch(ClassNotFoundException e){ }catch(ClassNotFoundException e){
outln("FTS5 classes not loaded."); outln("FTS5 classes not loaded.");
err = e; err = e;
@ -1273,7 +1328,7 @@ public class Tester1 implements Runnable {
final ValueHolder<Integer> val = new ValueHolder<>(0); final ValueHolder<Integer> val = new ValueHolder<>(0);
final ValueHolder<String> toss = new ValueHolder<>(null); final ValueHolder<String> toss = new ValueHolder<>(null);
final AutoExtensionCallback ax = new AutoExtensionCallback(){ final AutoExtensionCallback ax = new AutoExtensionCallback(){
@Override public synchronized int call(sqlite3 db){ @Override public int call(sqlite3 db){
++val.value; ++val.value;
if( null!=toss.value ){ if( null!=toss.value ){
throw new RuntimeException(toss.value); throw new RuntimeException(toss.value);
@ -1300,7 +1355,7 @@ public class Tester1 implements Runnable {
sqlite3 db = createNewDb(); sqlite3 db = createNewDb();
affirm( 4==val.value ); affirm( 4==val.value );
execSql(db, "ATTACH ':memory' as foo"); execSql(db, "ATTACH ':memory:' as foo");
affirm( 4==val.value, "ATTACH uses the same connection, not sub-connections." ); affirm( 4==val.value, "ATTACH uses the same connection, not sub-connections." );
sqlite3_close(db); sqlite3_close(db);
db = null; db = null;
@ -1359,7 +1414,197 @@ public class Tester1 implements Runnable {
affirm( 8 == val.value ); affirm( 8 == val.value );
} }
@ManualTest /* we really only want to run this test manually. */
private void testColumnMetadata(){
final sqlite3 db = createNewDb();
execSql(db, new String[] {
"CREATE TABLE t(a duck primary key not null collate noCase); ",
"INSERT INTO t(a) VALUES(1),(2),(3);"
});
OutputPointer.Bool bNotNull = new OutputPointer.Bool();
OutputPointer.Bool bPrimaryKey = new OutputPointer.Bool();
OutputPointer.Bool bAutoinc = new OutputPointer.Bool();
OutputPointer.String zCollSeq = new OutputPointer.String();
OutputPointer.String zDataType = new OutputPointer.String();
int rc = sqlite3_table_column_metadata(
db, "main", "t", "a", zDataType, zCollSeq,
bNotNull, bPrimaryKey, bAutoinc);
affirm( 0==rc );
affirm( bPrimaryKey.value );
affirm( !bAutoinc.value );
affirm( bNotNull.value );
affirm( "noCase".equals(zCollSeq.value) );
affirm( "duck".equals(zDataType.value) );
final TableColumnMetadata m =
sqlite3_table_column_metadata(db, "main", "t", "a");
affirm( null != m );
affirm( bPrimaryKey.value == m.isPrimaryKey() );
affirm( bAutoinc.value == m.isAutoincrement() );
affirm( bNotNull.value == m.isNotNull() );
affirm( zCollSeq.value.equals(m.getCollation()) );
affirm( zDataType.value.equals(m.getDataType()) );
affirm( null == sqlite3_table_column_metadata(db, "nope", "t", "a") );
sqlite3_close_v2(db);
}
private void testTxnState(){
final sqlite3 db = createNewDb();
affirm( SQLITE_TXN_NONE == sqlite3_txn_state(db, null) );
affirm( sqlite3_get_autocommit(db) );
execSql(db, "BEGIN;");
affirm( !sqlite3_get_autocommit(db) );
affirm( SQLITE_TXN_NONE == sqlite3_txn_state(db, null) );
execSql(db, "SELECT * FROM sqlite_schema;");
affirm( SQLITE_TXN_READ == sqlite3_txn_state(db, "main") );
execSql(db, "CREATE TABLE t(a);");
affirm( SQLITE_TXN_WRITE == sqlite3_txn_state(db, null) );
execSql(db, "ROLLBACK;");
affirm( SQLITE_TXN_NONE == sqlite3_txn_state(db, null) );
sqlite3_close_v2(db);
}
private void testExplain(){
final sqlite3 db = createNewDb();
sqlite3_stmt stmt = prepare(db,"SELECT 1");
affirm( 0 == sqlite3_stmt_isexplain(stmt) );
int rc = sqlite3_stmt_explain(stmt, 1);
affirm( 1 == sqlite3_stmt_isexplain(stmt) );
rc = sqlite3_stmt_explain(stmt, 2);
affirm( 2 == sqlite3_stmt_isexplain(stmt) );
sqlite3_finalize(stmt);
sqlite3_close_v2(db);
}
private void testLimit(){
final sqlite3 db = createNewDb();
int v;
v = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
affirm( v > 0 );
affirm( v == sqlite3_limit(db, SQLITE_LIMIT_LENGTH, v-1) );
affirm( v-1 == sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1) );
sqlite3_close_v2(db);
}
private void testComplete(){
affirm( 0==sqlite3_complete("select 1") );
affirm( 0!=sqlite3_complete("select 1;") );
affirm( 0!=sqlite3_complete("nope 'nope' 'nope' 1;"), "Yup" );
}
private void testKeyword(){
final int n = sqlite3_keyword_count();
affirm( n>0 );
affirm( !sqlite3_keyword_check("_nope_") );
affirm( sqlite3_keyword_check("seLect") );
affirm( null!=sqlite3_keyword_name(0) );
affirm( null!=sqlite3_keyword_name(n-1) );
affirm( null==sqlite3_keyword_name(n) );
}
private void testBackup(){
final sqlite3 db1 = createNewDb();
final sqlite3 db2 = createNewDb();
execSql(db1, new String[]{
"pragma page_size=512; VACUUM;",
"create table t(a);",
"insert into t(a) values(1),(2),(3);"
});
affirm( null==sqlite3_backup_init(db1,"main",db1,"main") );
final sqlite3_backup b = sqlite3_backup_init(db2,"main",db1,"main");
affirm( null!=b );
affirm( b.getNativePointer()!=0 );
int rc;
while( SQLITE_DONE!=(rc = sqlite3_backup_step(b, 1)) ){
affirm( 0==rc );
}
affirm( sqlite3_backup_pagecount(b) > 0 );
rc = sqlite3_backup_finish(b);
affirm( 0==rc );
affirm( b.getNativePointer()==0 );
sqlite3_close_v2(db1);
final sqlite3_stmt stmt = prepare(db2,"SELECT sum(a) from t");
sqlite3_step(stmt);
affirm( sqlite3_column_int(stmt,0) == 6 );
sqlite3_finalize(stmt);
sqlite3_close_v2(db2);
}
private void testRandomness(){
byte[] foo = new byte[20];
int i = 0;
for( byte b : foo ){
i += b;
}
affirm( i==0 );
sqlite3_randomness(foo);
for( byte b : foo ){
if(b!=0) ++i;
}
affirm( i!=0, "There's a very slight chance that 0 is actually correct." );
}
private void testBlobOpen(){
final sqlite3 db = createNewDb();
execSql(db, "CREATE TABLE T(a BLOB);"
+"INSERT INTO t(rowid,a) VALUES(1, 'def'),(2, 'XYZ');"
);
final OutputPointer.sqlite3_blob pOut = new OutputPointer.sqlite3_blob();
int rc = sqlite3_blob_open(db, "main", "t", "a",
sqlite3_last_insert_rowid(db), 1, pOut);
affirm( 0==rc );
sqlite3_blob b = pOut.take();
affirm( null!=b );
affirm( 0!=b.getNativePointer() );
affirm( 3==sqlite3_blob_bytes(b) );
rc = sqlite3_blob_write( b, new byte[] {100, 101, 102 /*"DEF"*/}, 0);
affirm( 0==rc );
rc = sqlite3_blob_close(b);
affirm( 0==rc );
rc = sqlite3_blob_close(b);
affirm( 0!=rc );
affirm( 0==b.getNativePointer() );
sqlite3_stmt stmt = prepare(db,"SELECT length(a), a FROM t ORDER BY a");
affirm( SQLITE_ROW == sqlite3_step(stmt) );
affirm( 3 == sqlite3_column_int(stmt,0) );
affirm( "def".equals(sqlite3_column_text16(stmt,1)) );
sqlite3_finalize(stmt);
b = sqlite3_blob_open(db, "main", "t", "a",
sqlite3_last_insert_rowid(db), 1);
affirm( null!=b );
rc = sqlite3_blob_reopen(b, 2);
affirm( 0==rc );
final byte[] tgt = new byte[3];
rc = sqlite3_blob_read(b, tgt, 0);
affirm( 0==rc );
affirm( 100==tgt[0] && 101==tgt[1] && 102==tgt[2], "DEF" );
rc = sqlite3_blob_close(b);
affirm( 0==rc );
sqlite3_close_v2(db);
}
/* Copy/paste/rename this to add new tests. */
private void _testTemplate(){
final sqlite3 db = createNewDb();
sqlite3_stmt stmt = prepare(db,"SELECT 1");
sqlite3_finalize(stmt);
sqlite3_close_v2(db);
}
@ManualTest /* we really only want to run this test manually */
private void testSleep(){ private void testSleep(){
out("Sleeping briefly... "); out("Sleeping briefly... ");
sqlite3_sleep(600); sqlite3_sleep(600);
@ -1402,8 +1647,6 @@ public class Tester1 implements Runnable {
outln(); outln();
} }
} }
testToUtf8();
test1();
for(java.lang.reflect.Method m : mlist){ for(java.lang.reflect.Method m : mlist){
nap(); nap();
try{ try{
@ -1413,9 +1656,6 @@ public class Tester1 implements Runnable {
throw e; throw e;
} }
} }
if( !fromThread ){
testBusy();
}
synchronized( this.getClass() ){ synchronized( this.getClass() ){
++nTestRuns; ++nTestRuns;
} }
@ -1466,6 +1706,7 @@ public class Tester1 implements Runnable {
Integer nRepeat = 1; Integer nRepeat = 1;
boolean forceFail = false; boolean forceFail = false;
boolean sqlLog = false; boolean sqlLog = false;
boolean configLog = false;
boolean squelchTestOutput = false; boolean squelchTestOutput = false;
for( int i = 0; i < args.length; ){ for( int i = 0; i < args.length; ){
String arg = args[i++]; String arg = args[i++];
@ -1486,6 +1727,8 @@ public class Tester1 implements Runnable {
forceFail = true; forceFail = true;
}else if(arg.equals("sqllog")){ }else if(arg.equals("sqllog")){
sqlLog = true; sqlLog = true;
}else if(arg.equals("configlog")){
configLog = true;
}else if(arg.equals("naps")){ }else if(arg.equals("naps")){
takeNaps = true; takeNaps = true;
}else if(arg.equals("q") || arg.equals("quiet")){ }else if(arg.equals("q") || arg.equals("quiet")){
@ -1509,7 +1752,7 @@ public class Tester1 implements Runnable {
}; };
int rc = sqlite3_config( log ); int rc = sqlite3_config( log );
affirm( 0==rc ); affirm( 0==rc );
rc = sqlite3_config( null ); rc = sqlite3_config( (ConfigSqllogCallback)null );
affirm( 0==rc ); affirm( 0==rc );
rc = sqlite3_config( log ); rc = sqlite3_config( log );
affirm( 0==rc ); affirm( 0==rc );
@ -1518,6 +1761,19 @@ public class Tester1 implements Runnable {
"without SQLITE_ENABLE_SQLLOG."); "without SQLITE_ENABLE_SQLLOG.");
} }
} }
if( configLog ){
final ConfigLogCallback log = new ConfigLogCallback() {
@Override public void call(int code, String msg){
outln("ConfigLogCallback: ",ResultCode.getEntryForInt(code),": ", msg);
};
};
int rc = sqlite3_config( log );
affirm( 0==rc );
rc = sqlite3_config( (ConfigLogCallback)null );
affirm( 0==rc );
rc = sqlite3_config( log );
affirm( 0==rc );
}
quietMode = squelchTestOutput; quietMode = squelchTestOutput;
outln("If you just saw warning messages regarding CallStaticObjectMethod, ", outln("If you just saw warning messages regarding CallStaticObjectMethod, ",
@ -1527,7 +1783,7 @@ public class Tester1 implements Runnable {
{ {
// Build list of tests to run from the methods named test*(). // Build list of tests to run from the methods named test*().
testMethods = new ArrayList<>(); testMethods = new ArrayList<>();
out("Skipping tests in multi-thread mode:"); int nSkipped = 0;
for(final java.lang.reflect.Method m : Tester1.class.getDeclaredMethods()){ for(final java.lang.reflect.Method m : Tester1.class.getDeclaredMethods()){
final String name = m.getName(); final String name = m.getName();
if( name.equals("testFail") ){ if( name.equals("testFail") ){
@ -1536,18 +1792,21 @@ public class Tester1 implements Runnable {
} }
}else if( !m.isAnnotationPresent( ManualTest.class ) ){ }else if( !m.isAnnotationPresent( ManualTest.class ) ){
if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){ if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){
if( 0==nSkipped++ ){
out("Skipping tests in multi-thread mode:");
}
out(" "+name+"()"); out(" "+name+"()");
}else if( name.startsWith("test") ){ }else if( name.startsWith("test") ){
testMethods.add(m); testMethods.add(m);
} }
} }
} }
out("\n"); if( nSkipped>0 ) out("\n");
} }
final long timeStart = System.currentTimeMillis(); final long timeStart = System.currentTimeMillis();
int nLoop = 0; int nLoop = 0;
switch( SQLITE_THREADSAFE ){ /* Sanity checking */ switch( sqlite3_threadsafe() ){ /* Sanity checking */
case 0: case 0:
affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ), affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ),
"Could not switch to single-thread mode." ); "Could not switch to single-thread mode." );
@ -1573,19 +1832,21 @@ public class Tester1 implements Runnable {
outln("libversion_number: ", outln("libversion_number: ",
sqlite3_libversion_number(),"\n", sqlite3_libversion_number(),"\n",
sqlite3_libversion(),"\n",SQLITE_SOURCE_ID,"\n", sqlite3_libversion(),"\n",SQLITE_SOURCE_ID,"\n",
"SQLITE_THREADSAFE=",SQLITE_THREADSAFE); "SQLITE_THREADSAFE=",sqlite3_threadsafe());
outln("Running ",nRepeat," loop(s) with ",nThread," thread(s) each."); final boolean showLoopCount = (nRepeat>1 && nThread>1);
if( showLoopCount ){
outln("Running ",nRepeat," loop(s) with ",nThread," thread(s) each.");
}
if( takeNaps ) outln("Napping between tests is enabled."); if( takeNaps ) outln("Napping between tests is enabled.");
for( int n = 0; n < nRepeat; ++n ){ for( int n = 0; n < nRepeat; ++n ){
++nLoop; ++nLoop;
out((1==nLoop ? "" : " ")+nLoop); if( showLoopCount ) out((1==nLoop ? "" : " ")+nLoop);
if( nThread<=1 ){ if( nThread<=1 ){
new Tester1(0).runTests(false); new Tester1(0).runTests(false);
continue; continue;
} }
Tester1.mtMode = true; Tester1.mtMode = true;
final ExecutorService ex = Executors.newFixedThreadPool( nThread ); final ExecutorService ex = Executors.newFixedThreadPool( nThread );
//final List<Future<?>> futures = new ArrayList<>();
for( int i = 0; i < nThread; ++i ){ for( int i = 0; i < nThread; ++i ){
ex.submit( new Tester1(i), i ); ex.submit( new Tester1(i), i );
} }
@ -1608,7 +1869,7 @@ public class Tester1 implements Runnable {
if( null!=err ) throw err; if( null!=err ) throw err;
} }
} }
outln(); if( showLoopCount ) outln();
quietMode = false; quietMode = false;
final long timeEnd = System.currentTimeMillis(); final long timeEnd = System.currentTimeMillis();
@ -1618,17 +1879,22 @@ public class Tester1 implements Runnable {
if( doSomethingForDev ){ if( doSomethingForDev ){
sqlite3_jni_internal_details(); sqlite3_jni_internal_details();
} }
affirm( 0==sqlite3_release_memory(1) );
sqlite3_shutdown(); sqlite3_shutdown();
int nMethods = 0; int nMethods = 0;
int nNatives = 0; int nNatives = 0;
int nCanonical = 0;
final java.lang.reflect.Method[] declaredMethods = final java.lang.reflect.Method[] declaredMethods =
SQLite3Jni.class.getDeclaredMethods(); SQLite3Jni.class.getDeclaredMethods();
for(java.lang.reflect.Method m : declaredMethods){ for(java.lang.reflect.Method m : declaredMethods){
int mod = m.getModifiers(); final int mod = m.getModifiers();
if( 0!=(mod & java.lang.reflect.Modifier.STATIC) ){ if( 0!=(mod & java.lang.reflect.Modifier.STATIC) ){
final String name = m.getName(); final String name = m.getName();
if(name.startsWith("sqlite3_")){ if(name.startsWith("sqlite3_")){
++nMethods; ++nMethods;
if( m.isAnnotationPresent( org.sqlite.jni.annotation.Canonical.class ) ){
++nCanonical;
}
if( 0!=(mod & java.lang.reflect.Modifier.NATIVE) ){ if( 0!=(mod & java.lang.reflect.Modifier.NATIVE) ){
++nNatives; ++nNatives;
} }
@ -1636,8 +1902,10 @@ public class Tester1 implements Runnable {
} }
} }
outln("\tSQLite3Jni.sqlite3_*() methods: "+ outln("\tSQLite3Jni.sqlite3_*() methods: "+
nNatives+" native methods and "+ nNatives+" native methods, "+
(nMethods - nNatives)+" Java impls"); (nMethods - nNatives)+" Java impls. ",
nCanonical," methods flagged as canonical"
);
outln("\tTotal test time = " outln("\tTotal test time = "
+(timeEnd - timeStart)+"ms"); +(timeEnd - timeStart)+"ms");
} }

View File

@ -17,7 +17,7 @@ import org.sqlite.jni.annotation.Nullable;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_trace_v2}. Callback for use with {@link SQLite3Jni#sqlite3_trace_v2}.
*/ */
public interface TraceV2Callback extends SQLite3CallbackProxy { public interface TraceV2Callback extends CallbackProxy {
/** /**
Called by sqlite3 for various tracing operations, as per Called by sqlite3 for various tracing operations, as per
sqlite3_trace_v2(). Note that this interface elides the 2nd sqlite3_trace_v2(). Note that this interface elides the 2nd

View File

@ -16,7 +16,7 @@ package org.sqlite.jni;
/** /**
Callback for use with {@link SQLite3Jni#sqlite3_update_hook}. Callback for use with {@link SQLite3Jni#sqlite3_update_hook}.
*/ */
public interface UpdateHookCallback extends SQLite3CallbackProxy { public interface UpdateHookCallback extends CallbackProxy {
/** /**
Must function as described for the C-level sqlite3_update_hook() Must function as described for the C-level sqlite3_update_hook()
callback. callback.

View File

@ -7,35 +7,26 @@ package org.sqlite.jni.annotation;
the Java API. the Java API.
<p>Canonical functions, unless specifically documented, have the <p>Canonical functions, unless specifically documented, have the
same semantics as their counterparts in same semantics as their counterparts in <a
<a href="https://sqlite.org/c3ref/intro.html">the C API documentation</a>, href="https://sqlite.org/c3ref/intro.html">the C API
despite their signatures perhaps differing. The Java API adds a documentation</a>, despite their signatures perhaps differing
number of overloads to simplify use, as well as a few Java-specific slightly. Canonical forms may be native or implemented in Java.
functions, and those are never flagged as @Canonical. Sometimes multiple overloads are labeled as Canonical because one
or more of them are just type- or encoding-related conversion
wrappers but provide identical semantics (e.g. from a String to a
byte[]). The Java API adds a number of convenience overloads to
simplify use, as well as a few Java-specific functions, and those
are never flagged as @Canonical.
<p>In some cases, the canonical version of a function is private <p>In some cases, the canonical version of a function is private
and exposed to Java via public overloads. and exposed to Java via public overloads.
<p>In rare cases, the Java interface for a canonical function has a
different name than its C counterpart. For such cases,
(cname=the-C-side-name) is passed to this annotation and a
Java-side implementation with a slightly different signature is
added to with the canonical name. As of this writing, that applies
only to {@link org.sqlite.jni.SQLite3Jni#sqlite3_value_text_utf8}
and {@link org.sqlite.jni.SQLite3Jni#sqlite3_column_text_utf8}.
<p>The comment property can be used to add a comment. <p>The comment property can be used to add a comment.
*/ */
@java.lang.annotation.Documented @java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD) @java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD)
public @interface Canonical{ public @interface Canonical{
/**
Java functions which directly map to a canonical function but
change its name for some reason should not the original name
in this property.
*/
String cname() default ""/*doesn't allow null*/;
/** /**
Brief comments about the binding, e.g. noting any major Brief comments about the binding, e.g. noting any major
semantic differences. semantic differences.

View File

@ -2,23 +2,37 @@ package org.sqlite.jni.annotation;
/** /**
This annotation is for flagging parameters which may not legally be This annotation is for flagging parameters which may not legally be
null. When used in the context of callback methods which are null or point to closed/finalized C-side resources.
called into from the C APIs, this annotation communicates that the
C API will never pass a null value to the callback. <p>In the case of Java types which map directly to C struct types
(e.g. {@link org.sqlite.jni.sqlite3}, {@link
org.sqlite.jni.sqlite3_stmt}, and {@link
org.sqlite.jni.sqlite3_context}), a closed/finalized resource is
also considered to be null for purposes this annotation because the
C-side effect of passing such a handle is the same as if null is
passed.</p>
<p>When used in the context of Java interfaces which are called
from the C APIs, this annotation communicates that the C API will
never pass a null value to the callback for that parameter.</p>
<p>Passing a null, for this annotation's definition of null, for
any parameter marked with this annoation specifically invokes
undefined behavior.</p>
<p>Note that the C-style API does not throw any exceptions on its <p>Note that the C-style API does not throw any exceptions on its
own because it has a no-throw policy in order to retain its C-style own because it has a no-throw policy in order to retain its C-style
semantics, but it may trigger NullPointerExceptions (or similar) if semantics, but it may trigger NullPointerExceptions (or similar) if
passed a null for a parameter flagged with this annotation. passed a null for a parameter flagged with this annotation.</p>
<p>This annotation is informational only. No policy is in place to <p>This annotation is informational only. No policy is in place to
programmatically ensure that NotNull is conformed to in client programmatically ensure that NotNull is conformed to in client
code. code.</p>
<p>This annotation is solely for the use by the classes in this <p>This annotation is solely for the use by the classes in this
package but is made public so that javadoc will link to it from the package but is made public so that javadoc will link to it from the
annotated functions. It is not part of the public API and annotated functions. It is not part of the public API and
client-level code must not rely on it. client-level code must not rely on it.</p>
*/ */
@java.lang.annotation.Documented @java.lang.annotation.Documented
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE)

View File

@ -11,15 +11,13 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
/** /**
INCOMPLETE AND COMPLETELY UNTESTED. INCOMPLETE AND COMPLETELY UNTESTED.
A wrapper for communicating C-level (fts5_api*) instances with A utility object for holding FTS5-specific types and constants
Java. These wrappers do not own their associated pointer, they which are used by multiple FTS5 classes.
simply provide a type-safe way to communicate it between Java and C
via JNI.
*/ */
public final class Fts5 { public final class Fts5 {
/* Not used */ /* Not used */
@ -28,7 +26,7 @@ public final class Fts5 {
/** /**
Callback type for use with xTokenize() variants Callback type for use with xTokenize() variants
*/ */
public static interface xTokenize_callback { public static interface XTokenizeCallback {
int call(int tFlags, byte[] txt, int iStart, int iEnd); int call(int tFlags, byte[] txt, int iStart, int iEnd);
} }

View File

@ -11,7 +11,8 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import org.sqlite.jni.*;
/** /**
A wrapper for communicating C-level (Fts5Context*) instances with A wrapper for communicating C-level (Fts5Context*) instances with

View File

@ -11,8 +11,9 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import org.sqlite.jni.*;
import org.sqlite.jni.annotation.*; import org.sqlite.jni.annotation.*;
/** /**
@ -27,8 +28,8 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
private final int iVersion = 2; private final int iVersion = 2;
/* Callback type for used by xQueryPhrase(). */ /* Callback type for used by xQueryPhrase(). */
public static interface xQueryPhraseCallback { public static interface XQueryPhraseCallback {
int xCallback(Fts5ExtensionApi fapi, Fts5Context cx); int call(Fts5ExtensionApi fapi, Fts5Context cx);
} }
/** /**
@ -36,40 +37,67 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
*/ */
public static native Fts5ExtensionApi getInstance(); public static native Fts5ExtensionApi getInstance();
@Canonical
public native int xColumnCount(@NotNull Fts5Context fcx); public native int xColumnCount(@NotNull Fts5Context fcx);
@Canonical
public native int xColumnSize(@NotNull Fts5Context cx, int iCol, public native int xColumnSize(@NotNull Fts5Context cx, int iCol,
@NotNull OutputPointer.Int32 pnToken); @NotNull OutputPointer.Int32 pnToken);
@Canonical
public native int xColumnText(@NotNull Fts5Context cx, int iCol, public native int xColumnText(@NotNull Fts5Context cx, int iCol,
@NotNull OutputPointer.String txt); @NotNull OutputPointer.String txt);
@Canonical
public native int xColumnTotalSize(@NotNull Fts5Context fcx, int iCol, public native int xColumnTotalSize(@NotNull Fts5Context fcx, int iCol,
@NotNull OutputPointer.Int64 pnToken); @NotNull OutputPointer.Int64 pnToken);
@Canonical
public native Object xGetAuxdata(@NotNull Fts5Context cx, boolean clearIt); public native Object xGetAuxdata(@NotNull Fts5Context cx, boolean clearIt);
@Canonical
public native int xInst(@NotNull Fts5Context cx, int iIdx, public native int xInst(@NotNull Fts5Context cx, int iIdx,
@NotNull OutputPointer.Int32 piPhrase, @NotNull OutputPointer.Int32 piPhrase,
@NotNull OutputPointer.Int32 piCol, @NotNull OutputPointer.Int32 piCol,
@NotNull OutputPointer.Int32 piOff); @NotNull OutputPointer.Int32 piOff);
@Canonical
public native int xInstCount(@NotNull Fts5Context fcx, public native int xInstCount(@NotNull Fts5Context fcx,
@NotNull OutputPointer.Int32 pnInst); @NotNull OutputPointer.Int32 pnInst);
@Canonical
public native int xPhraseCount(@NotNull Fts5Context fcx); public native int xPhraseCount(@NotNull Fts5Context fcx);
@Canonical
public native int xPhraseFirst(@NotNull Fts5Context cx, int iPhrase, public native int xPhraseFirst(@NotNull Fts5Context cx, int iPhrase,
@NotNull Fts5PhraseIter iter, @NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol, @NotNull OutputPointer.Int32 iCol,
@NotNull OutputPointer.Int32 iOff); @NotNull OutputPointer.Int32 iOff);
@Canonical
public native int xPhraseFirstColumn(@NotNull Fts5Context cx, int iPhrase, public native int xPhraseFirstColumn(@NotNull Fts5Context cx, int iPhrase,
@NotNull Fts5PhraseIter iter, @NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol); @NotNull OutputPointer.Int32 iCol);
@Canonical
public native void xPhraseNext(@NotNull Fts5Context cx, public native void xPhraseNext(@NotNull Fts5Context cx,
@NotNull Fts5PhraseIter iter, @NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol, @NotNull OutputPointer.Int32 iCol,
@NotNull OutputPointer.Int32 iOff); @NotNull OutputPointer.Int32 iOff);
@Canonical
public native void xPhraseNextColumn(@NotNull Fts5Context cx, public native void xPhraseNextColumn(@NotNull Fts5Context cx,
@NotNull Fts5PhraseIter iter, @NotNull Fts5PhraseIter iter,
@NotNull OutputPointer.Int32 iCol); @NotNull OutputPointer.Int32 iCol);
@Canonical
public native int xPhraseSize(@NotNull Fts5Context fcx, int iPhrase); public native int xPhraseSize(@NotNull Fts5Context fcx, int iPhrase);
@Canonical
public native int xQueryPhrase(@NotNull Fts5Context cx, int iPhrase, public native int xQueryPhrase(@NotNull Fts5Context cx, int iPhrase,
@NotNull xQueryPhraseCallback callback); @NotNull XQueryPhraseCallback callback);
@Canonical
public native int xRowCount(@NotNull Fts5Context fcx, public native int xRowCount(@NotNull Fts5Context fcx,
@NotNull OutputPointer.Int64 nRow); @NotNull OutputPointer.Int64 nRow);
@Canonical
public native long xRowid(@NotNull Fts5Context cx); public native long xRowid(@NotNull Fts5Context cx);
/* Note that the JNI binding lacks the C version's xDelete() /* Note that the JNI binding lacks the C version's xDelete()
callback argument. Instead, if pAux has an xDestroy() method, it callback argument. Instead, if pAux has an xDestroy() method, it
@ -77,10 +105,15 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
allocation of storage for the auxdata fails). Any reference to allocation of storage for the auxdata fails). Any reference to
pAux held by the JNI layer will be relinquished regardless of pAux held by the JNI layer will be relinquished regardless of
whether pAux has an xDestroy() method. */ whether pAux has an xDestroy() method. */
public native int xSetAuxdata(@NotNull Fts5Context cx, @Nullable Object pAux);
public native int xTokenize(@NotNull Fts5Context cx, @NotNull byte[] pText,
@NotNull Fts5.xTokenize_callback callback);
@Canonical
public native int xSetAuxdata(@NotNull Fts5Context cx, @Nullable Object pAux);
@Canonical
public native int xTokenize(@NotNull Fts5Context cx, @NotNull byte[] pText,
@NotNull Fts5.XTokenizeCallback callback);
@Canonical
public native Object xUserData(Fts5Context cx); public native Object xUserData(Fts5Context cx);
//^^^ returns the pointer passed as the 3rd arg to the C-level //^^^ returns the pointer passed as the 3rd arg to the C-level
// fts5_api::xCreateFunction(). // fts5_api::xCreateFunction().

View File

@ -11,7 +11,8 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import org.sqlite.jni.NativePointerHolder;
/** /**
A wrapper for C-level Fts5PhraseIter. They are only modified and A wrapper for C-level Fts5PhraseIter. They are only modified and

View File

@ -11,7 +11,8 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import org.sqlite.jni.NativePointerHolder;
/** /**
INCOMPLETE AND COMPLETELY UNTESTED. INCOMPLETE AND COMPLETELY UNTESTED.

View File

@ -11,14 +11,15 @@
************************************************************************* *************************************************************************
** This file contains a set of tests for the sqlite3 JNI bindings. ** This file contains a set of tests for the sqlite3 JNI bindings.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import static org.sqlite.jni.SQLite3Jni.*; import static org.sqlite.jni.SQLite3Jni.*;
import static org.sqlite.jni.Tester1.*; import static org.sqlite.jni.Tester1.*;
import org.sqlite.jni.*;
public class TesterFts5 { public class TesterFts5 {
private static void test1(){ private static void test1(){
Fts5ExtensionApi fea = Fts5ExtensionApi.getInstance(); final Fts5ExtensionApi fea = Fts5ExtensionApi.getInstance();
affirm( null != fea ); affirm( null != fea );
affirm( fea.getNativePointer() != 0 ); affirm( fea.getNativePointer() != 0 );
affirm( fea == Fts5ExtensionApi.getInstance() )/*singleton*/; affirm( fea == Fts5ExtensionApi.getInstance() )/*singleton*/;
@ -35,55 +36,51 @@ public class TesterFts5 {
}); });
final String pUserData = "This is pUserData"; final String pUserData = "This is pUserData";
ValueHolder<Boolean> xDestroyCalled = new ValueHolder<>(false); final int outputs[] = {0, 0};
ValueHolder<Integer> xFuncCount = new ValueHolder<>(0);
final fts5_extension_function func = new fts5_extension_function(){ final fts5_extension_function func = new fts5_extension_function(){
public void xFunction(Fts5ExtensionApi ext, Fts5Context fCx, @Override public void call(Fts5ExtensionApi ext, Fts5Context fCx,
sqlite3_context pCx, sqlite3_value argv[]){ sqlite3_context pCx, sqlite3_value argv[]){
int nCols = ext.xColumnCount(fCx); final int nCols = ext.xColumnCount(fCx);
affirm( 2 == nCols ); affirm( 2 == nCols );
affirm( nCols == argv.length ); affirm( nCols == argv.length );
affirm( ext.xUserData(fCx) == pUserData ); affirm( ext.xUserData(fCx) == pUserData );
if(true){ final OutputPointer.String op = new OutputPointer.String();
OutputPointer.String op = new OutputPointer.String(); final OutputPointer.Int32 colsz = new OutputPointer.Int32();
for(int i = 0; i < nCols; ++i ){ final OutputPointer.Int64 colTotalSz = new OutputPointer.Int64();
int rc = ext.xColumnText(fCx, i, op); for(int i = 0; i < nCols; ++i ){
affirm( 0 == rc ); int rc = ext.xColumnText(fCx, i, op);
final String val = op.value; affirm( 0 == rc );
affirm( val.equals(sqlite3_value_text(argv[i])) ); final String val = op.value;
//outln("xFunction col "+i+": "+val); affirm( val.equals(sqlite3_value_text16(argv[i])) );
} rc = ext.xColumnSize(fCx, i, colsz);
affirm( 0==rc );
affirm( 3==sqlite3_value_bytes(argv[i]) );
rc = ext.xColumnTotalSize(fCx, i, colTotalSz);
affirm( 0==rc );
} }
++xFuncCount.value; ++outputs[0];
} }
public void xDestroy(){ public void xDestroy(){
xDestroyCalled.value = true; outputs[1] = 1;
} }
}; };
int rc = fApi.xCreateFunction("myaux", pUserData, func); int rc = fApi.xCreateFunction("myaux", pUserData, func);
affirm( 0==rc ); affirm( 0==rc );
affirm( 0==xFuncCount.value ); affirm( 0==outputs[0] );
execSql(db, "select myaux(ft,a,b) from ft;"); execSql(db, "select myaux(ft,a,b) from ft;");
affirm( 2==xFuncCount.value ); affirm( 2==outputs[0] );
affirm( !xDestroyCalled.value ); affirm( 0==outputs[1] );
sqlite3_close_v2(db); sqlite3_close_v2(db);
affirm( xDestroyCalled.value ); affirm( 1==outputs[1] );
} }
public TesterFts5(boolean verbose){ private static synchronized void runTests(){
if(verbose){ test1();
final long timeStart = System.currentTimeMillis(); }
final int oldAffirmCount = Tester1.affirmCount;
test1(); public TesterFts5(){
final int affirmCount = Tester1.affirmCount - oldAffirmCount; runTests();
final long timeEnd = System.currentTimeMillis();
outln("FTS5 Tests done. Assertions checked = ",affirmCount,
", Total time = ",(timeEnd - timeStart),"ms");
}else{
test1();
}
} }
public TesterFts5(){ this(false); }
} }

View File

@ -11,8 +11,9 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import org.sqlite.jni.annotation.*; import org.sqlite.jni.annotation.*;
import org.sqlite.jni.*;
/** /**
INCOMPLETE AND COMPLETELY UNTESTED. INCOMPLETE AND COMPLETELY UNTESTED.
@ -25,7 +26,8 @@ import org.sqlite.jni.annotation.*;
public final class fts5_api extends NativePointerHolder<fts5_api> { public final class fts5_api extends NativePointerHolder<fts5_api> {
/* Only invoked from JNI */ /* Only invoked from JNI */
private fts5_api(){} private fts5_api(){}
public final int iVersion = 2;
public static final int iVersion = 2;
/** /**
Returns the fts5_api instance associated with the given db, or Returns the fts5_api instance associated with the given db, or
@ -33,6 +35,31 @@ public final class fts5_api extends NativePointerHolder<fts5_api> {
*/ */
public static synchronized native fts5_api getInstanceForDb(@NotNull sqlite3 db); public static synchronized native fts5_api getInstanceForDb(@NotNull sqlite3 db);
@Canonical
public synchronized native int xCreateFunction(@NotNull String name,
@Nullable Object userData,
@NotNull fts5_extension_function xFunction);
/**
Convenience overload which passes null as the 2nd argument to the
3-parameter form.
*/
public int xCreateFunction(@NotNull String name,
@NotNull fts5_extension_function xFunction){
return xCreateFunction(name, null, xFunction);
}
// /* Create a new auxiliary function */
// int (*xCreateFunction)(
// fts5_api *pApi,
// const char *zName,
// void *pContext,
// fts5_extension_function xFunction,
// void (*xDestroy)(void*)
// );
// Still potentially todo:
// int (*xCreateTokenizer)( // int (*xCreateTokenizer)(
// fts5_api *pApi, // fts5_api *pApi,
// const char *zName, // const char *zName,
@ -49,22 +76,4 @@ public final class fts5_api extends NativePointerHolder<fts5_api> {
// fts5_tokenizer *pTokenizer // fts5_tokenizer *pTokenizer
// ); // );
// /* Create a new auxiliary function */
// int (*xCreateFunction)(
// fts5_api *pApi,
// const char *zName,
// void *pContext,
// fts5_extension_function xFunction,
// void (*xDestroy)(void*)
// );
public synchronized native int xCreateFunction(@NotNull String name,
@Nullable Object userData,
@NotNull fts5_extension_function xFunction);
public int xCreateFunction(@NotNull String name,
@NotNull fts5_extension_function xFunction){
return xCreateFunction(name, null, xFunction);
}
} }

View File

@ -11,13 +11,14 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import org.sqlite.jni.sqlite3_context;
import org.sqlite.jni.sqlite3_value;
/** /**
JNI-level wrapper for C's fts5_extension_function type. JNI-level wrapper for C's fts5_extension_function type.
*/ */
public abstract class fts5_extension_function { public interface fts5_extension_function {
// typedef void (*fts5_extension_function)( // typedef void (*fts5_extension_function)(
// const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ // const Fts5ExtensionApi *pApi, /* API offered by current FTS version */
// Fts5Context *pFts, /* First arg to pass to pApi functions */ // Fts5Context *pFts, /* First arg to pass to pApi functions */
@ -30,8 +31,17 @@ public abstract class fts5_extension_function {
The callback implementation, corresponding to the xFunction The callback implementation, corresponding to the xFunction
argument of C's fts5_api::xCreateFunction(). argument of C's fts5_api::xCreateFunction().
*/ */
public abstract void xFunction(Fts5ExtensionApi ext, Fts5Context fCx, void call(Fts5ExtensionApi ext, Fts5Context fCx,
sqlite3_context pCx, sqlite3_value argv[]); sqlite3_context pCx, sqlite3_value argv[]);
//! Optionally override /**
public void xDestroy(){} Is called when this function is destroyed by sqlite3. Typically
this function will be empty.
*/
void xDestroy();
public static abstract class Abstract implements fts5_extension_function {
@Override public abstract void call(Fts5ExtensionApi ext, Fts5Context fCx,
sqlite3_context pCx, sqlite3_value argv[]);
@Override public void xDestroy(){}
}
} }

View File

@ -11,8 +11,9 @@
************************************************************************* *************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API. ** This file is part of the JNI bindings for the sqlite3 C API.
*/ */
package org.sqlite.jni; package org.sqlite.jni.fts5;
import org.sqlite.jni.annotation.*; import org.sqlite.jni.NativePointerHolder;
import org.sqlite.jni.annotation.NotNull;
/** /**
INCOMPLETE AND COMPLETELY UNTESTED. INCOMPLETE AND COMPLETELY UNTESTED.
@ -31,7 +32,7 @@ public final class fts5_tokenizer extends NativePointerHolder<fts5_tokenizer> {
public native int xTokenize(@NotNull Fts5Tokenizer t, int tokFlags, public native int xTokenize(@NotNull Fts5Tokenizer t, int tokFlags,
@NotNull byte pText[], @NotNull byte pText[],
@NotNull Fts5.xTokenize_callback callback); @NotNull Fts5.XTokenizeCallback callback);
// int (*xTokenize)(Fts5Tokenizer*, // int (*xTokenize)(Fts5Tokenizer*,

View File

@ -1,19 +1,59 @@
/** /**
This package houses a JNI binding to the SQLite3 C API. This package houses a JNI binding to the SQLite3 C API.
<p>The docs are in progress. <p>The primary interfaces are in {@link
org.sqlite.jni.SQLite3Jni}.</p>
<p>The primary interfaces are in {@link org.sqlite.jni.SQLite3Jni}. <h1>API Goals and Requirements</h1>
<ul>
<li>A 1-to-1(-ish) mapping of the C API to Java via JNI, insofar
as cross-language semantics allow for. A closely-related goal is
that <a href='https://sqlite.org/c3ref/intro.html'>the C
documentation</a> should be usable as-is, insofar as possible,
for most of the JNI binding. As a rule, undocumented symbols in
the Java interface behave as documented for their C API
counterpart. Only semantic differences and Java-specific features
are documented here.</li>
<li>Support Java as far back as version 8 (2014).</li>
<li>Environment-independent. Should work everywhere both Java and
SQLite3 do.</li>
<li>No 3rd-party dependencies beyond the JDK. That includes no
build-level dependencies for specific IDEs and toolchains. We
welcome the addition of build files for arbitrary environments
insofar as they neither interfere with each other nor become a
maintenance burden for the sqlite developers.</li>
</ul>
<h2>Non-Goals</h2>
<ul>
<li>Creation of high-level OO wrapper APIs. Clients are free to
create them off of the C-style API.</li>
<li>Support for mixed-mode operation, where client code accesses
SQLite both via the Java-side API and the C API via their own
native code. In such cases, proxy functionalities (primarily
callback handler wrappers of all sorts) may fail because the
C-side use of the SQLite APIs will bypass those proxies.</li>
</ul>
<h1>State of this API</h1> <h1>State of this API</h1>
<p>As of version 3.43, this software is in "tech preview" form. We <p>As of version 3.43, this software is in "tech preview" form. We
tentatively plan to stamp it as stable with the 3.44 release. tentatively plan to stamp it as stable with the 3.44 release.</p>
<h1>Threading Considerations</h1> <h1>Threading Considerations</h1>
<p>This API is, if built with SQLITE_THREADSAFE set to 1 or 2, <p>This API is, if built with SQLITE_THREADSAFE set to 1 or 2,
thread-safe, insofar as the C API guarantees, with some addenda: thread-safe, insofar as the C API guarantees, with some addenda:</p>
<ul> <ul>
@ -39,11 +79,11 @@
<p>Any number of threads may, of course, create and use any number <p>Any number of threads may, of course, create and use any number
of database handles they wish. Care only needs to be taken when of database handles they wish. Care only needs to be taken when
those handles or their associated resources cross threads, or... those handles or their associated resources cross threads, or...</p>
<p>When built with SQLITE_THREADSAFE=0 then no threading guarantees <p>When built with SQLITE_THREADSAFE=0 then no threading guarantees
are provided and multi-threaded use of the library will provoke are provided and multi-threaded use of the library will provoke
undefined behavior. undefined behavior.</p>
*/ */
package org.sqlite.jni; package org.sqlite.jni;

View File

@ -1,5 +1,5 @@
/* /*
** 2023-08-04 ** 2023-09-03
** **
** The author disclaims copyright to this source code. In place of ** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing: ** a legal notice, here is a blessing:
@ -14,14 +14,12 @@
package org.sqlite.jni; package org.sqlite.jni;
/** /**
Fts5Function is used in conjunction with the A wrapper for passing C-level (sqlite3_backup*) instances around in
sqlite3_create_fts_function() JNI-bound API to give that native code Java. These wrappers do not own their associated pointer, they
access to the callback functions needed in order to implement simply provide a type-safe way to communicate it between Java and C
FTS5 auxiliary functions in Java. via JNI.
*/ */
public abstract class Fts5Function { public final class sqlite3_backup extends NativePointerHolder<sqlite3_backup> {
// Only invoked from JNI.
public abstract void xFunction(Fts5ExtensionApi pApi, Fts5Context pFts, private sqlite3_backup(){}
sqlite3_context pCtx, sqlite3_value argv[]);
public void xDestroy() {}
} }

View File

@ -0,0 +1,25 @@
/*
** 2023-09-03
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** This file is part of the JNI bindings for the sqlite3 C API.
*/
package org.sqlite.jni;
/**
A wrapper for passing C-level (sqlite3_blob*) instances around in
Java. These wrappers do not own their associated pointer, they
simply provide a type-safe way to communicate it between Java and C
via JNI.
*/
public final class sqlite3_blob extends NativePointerHolder<sqlite3_blob> {
// Only invoked from JNI.
private sqlite3_blob(){}
}

View File

@ -96,6 +96,13 @@
logClass('','index.html:',...args); logClass('','index.html:',...args);
return f; return f;
}; };
const timerId = setTimeout( ()=>{
logClass('error',"The SQLTester module is taking an unusually ",
"long time to load. More information may be available",
"in the dev console.");
}, 3000 /* assuming localhost */ );
W.onmessage = function({data}){ W.onmessage = function({data}){
switch(data.type){ switch(data.type){
case 'stdout': log2(data.payload.message); break; case 'stdout': log2(data.payload.message); break;
@ -105,6 +112,7 @@
log("test results:",data.payload); log("test results:",data.payload);
break; break;
case 'is-ready': case 'is-ready':
clearTimeout(timerId);
runTests(); break; runTests(); break;
default: default:
log("unhandled onmessage",data); log("unhandled onmessage",data);

View File

@ -1,5 +1,5 @@
C Add\ssupport\sfor\sthe\ssqlite3_get_clientdata()\sand\ssqlite3_set_clientdata()\ninterfaces,\sto\sbetter\ssupport\sJNI. C Merge\sin\sJNI's\ssignificant\sdivergence\ssince\sit\sadopted\ssqlite3_client_data().
D 2023-09-11T14:55:05.474 D 2023-09-11T15:20:15.135
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
@ -235,52 +235,54 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282 F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
F ext/jni/GNUmakefile 374873bf6d2cd6ceafb458e28b59140dbb074f01f7adddf7e15a3ee3daf44551 F ext/jni/GNUmakefile 3c82b1333ab4c8224787a490e80ea000a8f97bcb53bf9c9d11e095da1ae862f0
F ext/jni/README.md 1332b1fa27918bd5d9ca2d0d4f3ac3a6ab86b9e3699dc5bfe32904a027f3d2a9 F ext/jni/README.md 1332b1fa27918bd5d9ca2d0d4f3ac3a6ab86b9e3699dc5bfe32904a027f3d2a9
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
F ext/jni/src/c/sqlite3-jni.c aaec2851258a7d9c9907d8e864a17e055676ec0adb64f335d979fa19674a0cab F ext/jni/src/c/sqlite3-jni.c 438a0141b7be7e8081f23254efe4cb313170aeb0f12fc5dd2c5a42612111bfad
F ext/jni/src/c/sqlite3-jni.h 12e1a5ef5ee1795dc22577c285b4518dfd8aa4af45757f6cb81a555d967bf201 F ext/jni/src/c/sqlite3-jni.h c1b34759d1a1f18ba7659ee1b5d518b5865f7f2f30685216910a149d038cdd05
F ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java 95e88ba04f4aac51ffec65693e878e234088b2f21b387f4e4285c8b72b33e436 F ext/jni/src/org/sqlite/jni/AbstractCollationCallback.java 95e88ba04f4aac51ffec65693e878e234088b2f21b387f4e4285c8b72b33e436
F ext/jni/src/org/sqlite/jni/AggregateFunction.java 7312486bc65fecdb91753c0a4515799194e031f45edbe16a6373cea18f404dc4 F ext/jni/src/org/sqlite/jni/AggregateFunction.java 7312486bc65fecdb91753c0a4515799194e031f45edbe16a6373cea18f404dc4
F ext/jni/src/org/sqlite/jni/AuthorizerCallback.java d00a2409ab76cae168927e2ca6a7ffbd0621a42547cce88768b4eeebc13827e0 F ext/jni/src/org/sqlite/jni/AuthorizerCallback.java e6135be32f12bf140bffa39be7fd1a45ad83b2661ed49c08dbde04c8485feb38
F ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java 1470e14d09f10729d35568506c6e61318edfb17aa322802e386764fa6d582f14 F ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java 5e4a75611c026730289d776469d6122cb2699d6970af5f53fe85e74d49930476
F ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java cd12c26dafd3e6c097fc73f80d328aebac0f58b985f66a96ee567ddf8d195f30 F ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java d316373b12b3bf1a421f1f7eed08128fa8dd52bb98617ba28c161aaabd71d1ee
F ext/jni/src/org/sqlite/jni/CollationCallback.java 7d5b246f1a7c9d6b8e974d970bbbb2d05c6264e65448d7be6a85edbf703c823d F ext/jni/src/org/sqlite/jni/CallbackProxy.java 064a8a00e4c63cc501c30504f93ca996d422c5f010067f969b2d0a10f0868153 w ext/jni/src/org/sqlite/jni/SQLite3CallbackProxy.java
F ext/jni/src/org/sqlite/jni/CollationNeededCallback.java 1707b50146c6b805b79e84f89a57c8dbb0134e431799f041f0bec403eca5f841 F ext/jni/src/org/sqlite/jni/CollationCallback.java df327348e1a34ee65210208d694d690e5ee0bfe901410122e07caf6c98b2b7c8
F ext/jni/src/org/sqlite/jni/CommitHookCallback.java e4de82c97560982e996e358958268e1e4e307b6115cd9aac0ff4f947d4380d90 F ext/jni/src/org/sqlite/jni/CollationNeededCallback.java 07df5fa161a0b81154295258037f662e7c372735c2899c76e81cb3abd9fd3b39
F ext/jni/src/org/sqlite/jni/CommitHookCallback.java 77cf8bb4f5548113e9792978f3f8a454614f420fa0ad73939421cbff4e7776f2
F ext/jni/src/org/sqlite/jni/ConfigLogCallback.java 636ed6b89ed03f15bc2a6f6f47bf7853b8328e5a8269e52e80630708efa703a6
F ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java e3656909eab7ed0f7e457c5b82df160ca22dd5e954c0a306ec1fca61b0d266b4 F ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java e3656909eab7ed0f7e457c5b82df160ca22dd5e954c0a306ec1fca61b0d266b4
F ext/jni/src/org/sqlite/jni/Fts5.java 3ebfbd5b95fdb9d7bc40306f2e682abd12e247d9224e92510b8dd103b4f96fe8
F ext/jni/src/org/sqlite/jni/Fts5Context.java 0a5a02047a6a1dd3e4a38b0e542a8dd2de365033ba30e6ae019a676305959890
F ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java 2fd11abb7c5403318181d69bb7b702a79cba7ab460105140f5161bea9bc505d1
F ext/jni/src/org/sqlite/jni/Fts5Function.java 65cde7151e441fee012250a5e03277de7babcd11a0c308a832b7940574259bcc
F ext/jni/src/org/sqlite/jni/Fts5PhraseIter.java 6642beda341c0b1b46af4e2d7f6f9ab03a7aede43277b2c92859176d6bce3be9
F ext/jni/src/org/sqlite/jni/Fts5Tokenizer.java 91489893596b6528c0df5cd7180bd5b55809c26e2b797fb321dfcdbc1298c060
F ext/jni/src/org/sqlite/jni/NativePointerHolder.java 564087036449a16df148dcf0a067408bd251170bf23286c655f46b5f973e8b2d F ext/jni/src/org/sqlite/jni/NativePointerHolder.java 564087036449a16df148dcf0a067408bd251170bf23286c655f46b5f973e8b2d
F ext/jni/src/org/sqlite/jni/OutputPointer.java 4ae06135decef35eb04498daa2868939d91a294e948747c580ef9ce31563a6b3 F ext/jni/src/org/sqlite/jni/OutputPointer.java 2f57c05672ddc9b38e3f8eed11759896cf0bf01107ffd24d5182b99f6e7254b6
F ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java 500c968b3893edbddf67e8eb773852c3a8ae58097a77bd22320ada6b1af06db1 F ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java eccaed8dc9c6289f07ef3fc109891c6be1e7cc6c88723d90174b68706fc21cda
F ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java 0da841810319f5a9dc372d0f2348930d54fac1a4b53e4298884f44c720d67830 F ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java 7b9ff2218129ece98ba60c57eeedcd8447e9e3b6e5d0f5e5d3eb0f0c5037d48d
F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86 F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86
F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java 16042be9d072a26dbb2f1b1b63e7639989b747bb80d2bd667ba4f7555f56a825 F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java d12352c0e22840de484ffa9b11ed5058bb0daca2e9f218055d3c54c947a273c4
F ext/jni/src/org/sqlite/jni/SQLFunction.java 544a875d33fd160467d82e2397ac33157b29971d715a821a4fad3c899113ee8c F ext/jni/src/org/sqlite/jni/SQLFunction.java 544a875d33fd160467d82e2397ac33157b29971d715a821a4fad3c899113ee8c
F ext/jni/src/org/sqlite/jni/SQLite3CallbackProxy.java c2748ab52856075b053a55b317988d95dc7fb4d3d42520f8c33573effe1cd185 F ext/jni/src/org/sqlite/jni/SQLite3Jni.java a1beb9f9953bfaf76824239d8f556c81a3d8ea81f89307817e17d2cb0cbf7c9c
F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 440d64e8c4cff53bd3c0cc676381212489198302d7f1aaa535712c2d7163cc69
F ext/jni/src/org/sqlite/jni/ScalarFunction.java 6d387bb499fbe3bc13c53315335233dbf6a0c711e8fa7c521683219b041c614c F ext/jni/src/org/sqlite/jni/ScalarFunction.java 6d387bb499fbe3bc13c53315335233dbf6a0c711e8fa7c521683219b041c614c
F ext/jni/src/org/sqlite/jni/Tester1.java 21d78aa59bfc5ce5ff242d4bb6f6d2255d162fba8be5859ab87c9201d61433f0 F ext/jni/src/org/sqlite/jni/TableColumnMetadata.java 54511b4297fa28dcb3f49b24035e34ced10e3fd44fd0e458e784f4d6b0096dab
F ext/jni/src/org/sqlite/jni/TesterFts5.java 6f135c60e24c89e8eecb9fe61dde0f3bb2906de668ca6c9186bcf34bdaf94629 F ext/jni/src/org/sqlite/jni/Tester1.java a14f34e0404179b2920c20bca79ae178c71130e7c53aabe9a9e5c717850d2dfd
F ext/jni/src/org/sqlite/jni/TraceV2Callback.java 641926b05a772c2c05c842a81aa839053ba4a13b78ef04b402f5705d060c6246 F ext/jni/src/org/sqlite/jni/TraceV2Callback.java beb0b064c1a5f8bfe585a324ed39a4e33edbe379a3fc60f1401661620d3ca7c0
F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java be2bc96ff4f56b3c1fd18ae7dba9b207b25b6c123b8a5fd2f7aaf3cc208d8b7d F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java 8376f4a931f2d5612b295c003c9515ba933ee76d8f95610e89c339727376e36c
F ext/jni/src/org/sqlite/jni/ValueHolder.java f022873abaabf64f3dd71ab0d6037c6e71cece3b8819fa10bf26a5461dc973ee
F ext/jni/src/org/sqlite/jni/WindowFunction.java 488980f4dbb6bdd7067d6cb9c43e4075475e51c54d9b74a5834422654b126246 F ext/jni/src/org/sqlite/jni/WindowFunction.java 488980f4dbb6bdd7067d6cb9c43e4075475e51c54d9b74a5834422654b126246
F ext/jni/src/org/sqlite/jni/XDestroyCallback.java 50c5ca124ef6c6b735a7e136e7a23a557be367e61b56d4aab5777a614ab46cc2 F ext/jni/src/org/sqlite/jni/XDestroyCallback.java 50c5ca124ef6c6b735a7e136e7a23a557be367e61b56d4aab5777a614ab46cc2
F ext/jni/src/org/sqlite/jni/annotation/Canonical.java e55b82c8259b617ff754ac493fd8b79602631d659b87a858b987540e4c4fdf56 F ext/jni/src/org/sqlite/jni/annotation/Canonical.java 2767daa5b3893b96729db80a0f8234d379d266d1b2c21400a057864b538a0ea5
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java d48ebd7ae6bbb78bd47d54431c85e1521c89b1d3864a2b6eafd9c0e1b2341457 F ext/jni/src/org/sqlite/jni/annotation/NotNull.java d9b32956cb9fb11d1f8a562e5df70d0599820265285120c63858294dbe2b7711
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 6f962a98c9a5c6e9d21c50ae8716b16bdfdc934a191608cbb7e12ea588ddb6af F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 6f962a98c9a5c6e9d21c50ae8716b16bdfdc934a191608cbb7e12ea588ddb6af
F ext/jni/src/org/sqlite/jni/annotation/package-info.java f66bfb621c6494e67c03ed38a9e26a3bd6af99b9f9f6ef79556bcec30a025a22 F ext/jni/src/org/sqlite/jni/annotation/package-info.java f66bfb621c6494e67c03ed38a9e26a3bd6af99b9f9f6ef79556bcec30a025a22
F ext/jni/src/org/sqlite/jni/fts5_api.java ee47f1837d32968f7bb62278c7504c0fb572a68ec107371b714578312e9f734b F ext/jni/src/org/sqlite/jni/fts5/Fts5.java 3268fc61a15da5682e4e2130adbb1ae5385393c2f8a2ed408af806894b4a0625 w ext/jni/src/org/sqlite/jni/Fts5.java
F ext/jni/src/org/sqlite/jni/fts5_extension_function.java ac825035d7d83fc7fd960347abfa6803e1614334a21533302041823ad5fc894c F ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 7058da97059b8e156c17561a47ecd7faa0fc3e2d8c2588b9a28dbff8d06202dd w ext/jni/src/org/sqlite/jni/Fts5Context.java
F ext/jni/src/org/sqlite/jni/fts5_tokenizer.java a92c2e55bda492e4c76d48ddc73369bcc0d5e8727940840f9339e3292ea58fa7 F ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java 3c337e5690c4de7f0d5478f53ca7ba326e776330eb511e607bd252a35b84d8f7 w ext/jni/src/org/sqlite/jni/Fts5ExtensionApi.java
F ext/jni/src/org/sqlite/jni/package-info.java 73f7821c240e4d116f164e87b613c5836b8a33ce2666967a29d9acb1ced7ca92 F ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 2a7f3d76a1206e6a43d4c4ed9609b294d5431cc7d8fb875d8419f76efa6e56dc w ext/jni/src/org/sqlite/jni/Fts5PhraseIter.java
F ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java cc9a53846a168a215238af224c31cef0e8379780e36e8a5e743b00c08145cf19 w ext/jni/src/org/sqlite/jni/Fts5Tokenizer.java
F ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java b5a805c2ecff5c89179133fd2a6ede90b8598796e3940afae4590c7b503d3917 w ext/jni/src/org/sqlite/jni/TesterFts5.java
F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java 6071bf76c2c6a0f035b99adc76715b0324f540a441452b4ff6b94d9360a6a83d w ext/jni/src/org/sqlite/jni/fts5_api.java
F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 1fe0f5692c1d67475d12b067f0469949073446f18c56eba5ee5da6ddd06db9b9 w ext/jni/src/org/sqlite/jni/fts5_extension_function.java
F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 4b56f407977f08e456ea0c956fb657b4cd96ec4635cc4f7a1b7ef10cb2a21d7d w ext/jni/src/org/sqlite/jni/fts5_tokenizer.java
F ext/jni/src/org/sqlite/jni/package-info.java a3946db2504de747a1993c4f6e8ce604bec5a8e5a134b292c3b07527bc321a99
F ext/jni/src/org/sqlite/jni/sqlite3.java 62b1b81935ccf3393472d17cb883dc5ff39c388ec3bc1de547f098a0217158fc F ext/jni/src/org/sqlite/jni/sqlite3.java 62b1b81935ccf3393472d17cb883dc5ff39c388ec3bc1de547f098a0217158fc
F ext/jni/src/org/sqlite/jni/sqlite3_backup.java d0bb06dd6225e76999ff6b7ab20f2643b1c4d4167431b3a93ea41943e41f094b
F ext/jni/src/org/sqlite/jni/sqlite3_blob.java f28a30134f2e524eb7d5ab87f57f86c90140341a6e8369ee54509ac8bb96fa82
F ext/jni/src/org/sqlite/jni/sqlite3_context.java 66ca95ce904044263a4aff684abe262d56f73e6b06bca6cf650761d79d7779ad F ext/jni/src/org/sqlite/jni/sqlite3_context.java 66ca95ce904044263a4aff684abe262d56f73e6b06bca6cf650761d79d7779ad
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
@ -552,7 +554,7 @@ F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e
F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff
F ext/wasm/SQLTester/SQLTester.mjs ec2f6ba63a0f2f0562941a0fb8e46b7dc55589711513f1952349785966edfe50 F ext/wasm/SQLTester/SQLTester.mjs ec2f6ba63a0f2f0562941a0fb8e46b7dc55589711513f1952349785966edfe50
F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638 F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638
F ext/wasm/SQLTester/index.html 3a12895015c165281307eb47786ce3c46b3c3f06383ad6a9fe3a8526105632f1 F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d
F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536 F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536
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
@ -2117,9 +2119,9 @@ 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 71548f72ad578db3d6ee409956386ace23ab2258d37cdc29ef2fb126e48f1ee3 7b884832b71c23e62ba3c0d53f7c89199734c351f909d84ac19ac18c7ddccbd8 P 9806c0dd2802d68b67c25c4f3347ed532f9a98b051e775d34e9182dd2f099891 caceb52fb58f924e7cbbebac05e7fd7822b7f6f56a3f834392d2be801bf04633
R ed133595420eb79056e6b2e7f8f7826c R c483b1d540b87b26a025edef658546dc
T +closed 7b884832b71c23e62ba3c0d53f7c89199734c351f909d84ac19ac18c7ddccbd8 T +closed caceb52fb58f924e7cbbebac05e7fd7822b7f6f56a3f834392d2be801bf04633 Closed\sby\sintegrate-merge.
U drh U stephan
Z 4388a2fb0fa820775dbaf90786b95f10 Z d9fe1d695ebe43d0eee6d17283d420b9
# Remove this line to create a well-formed Fossil manifest. # Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
9806c0dd2802d68b67c25c4f3347ed532f9a98b051e775d34e9182dd2f099891 e8e07dbbeaa7799eb0b90726e18e994aaf8c8d316ab4bdb06da732bc51cf0919