mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-05 15:55:57 +03:00
Merge the latest trunk fixes and enhancements into the jsonb branch, and
especially the JSON cache spill UAF fix. FossilOrigin-Name: 9422c24f4a8b290dcae61e50ec81be5b314b22c61a2bca1e194e47da1316b6e6
This commit is contained in:
@@ -45,9 +45,9 @@ DISTCLEAN_FILES := $(dir.jni)/*~ $(dir.src.c)/*~ $(dir.src.jni)/*~
|
|||||||
|
|
||||||
sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h
|
sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h
|
||||||
.NOTPARALLEL: $(sqlite3-jni.h)
|
.NOTPARALLEL: $(sqlite3-jni.h)
|
||||||
SQLite3Jni.java := src/org/sqlite/jni/SQLite3Jni.java
|
CApi.java := src/org/sqlite/jni/CApi.java
|
||||||
SQLTester.java := src/org/sqlite/jni/SQLTester.java
|
SQLTester.java := src/org/sqlite/jni/SQLTester.java
|
||||||
SQLite3Jni.class := $(SQLite3Jni.java:.java=.class)
|
CApi.class := $(CApi.java:.java=.class)
|
||||||
SQLTester.class := $(SQLTester.java:.java=.class)
|
SQLTester.class := $(SQLTester.java:.java=.class)
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
@@ -78,7 +78,6 @@ $(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile
|
|||||||
# Be explicit about which Java files to compile so that we can work on
|
# Be explicit about which Java files to compile so that we can work on
|
||||||
# in-progress files without requiring them to be in a compilable statae.
|
# in-progress files without requiring them to be in a compilable statae.
|
||||||
JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
|
JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
|
||||||
annotation/Canonical.java \
|
|
||||||
annotation/NotNull.java \
|
annotation/NotNull.java \
|
||||||
annotation/Nullable.java \
|
annotation/Nullable.java \
|
||||||
AbstractCollationCallback.java \
|
AbstractCollationCallback.java \
|
||||||
@@ -99,9 +98,11 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
|
|||||||
ResultCode.java \
|
ResultCode.java \
|
||||||
RollbackHookCallback.java \
|
RollbackHookCallback.java \
|
||||||
ScalarFunction.java \
|
ScalarFunction.java \
|
||||||
|
Sqlite.java \
|
||||||
|
SqliteException.java \
|
||||||
SQLFunction.java \
|
SQLFunction.java \
|
||||||
CallbackProxy.java \
|
CallbackProxy.java \
|
||||||
SQLite3Jni.java \
|
CApi.java \
|
||||||
TableColumnMetadata.java \
|
TableColumnMetadata.java \
|
||||||
TraceV2Callback.java \
|
TraceV2Callback.java \
|
||||||
UpdateHookCallback.java \
|
UpdateHookCallback.java \
|
||||||
@@ -114,6 +115,7 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
|
|||||||
)
|
)
|
||||||
JAVA_FILES.unittest := $(patsubst %,$(dir.src.jni)/%,\
|
JAVA_FILES.unittest := $(patsubst %,$(dir.src.jni)/%,\
|
||||||
Tester1.java \
|
Tester1.java \
|
||||||
|
Tester2.java \
|
||||||
)
|
)
|
||||||
ifeq (1,$(enable.fts5))
|
ifeq (1,$(enable.fts5))
|
||||||
JAVA_FILES.unittest += $(patsubst %,$(dir.src.jni)/%,\
|
JAVA_FILES.unittest += $(patsubst %,$(dir.src.jni)/%,\
|
||||||
@@ -243,7 +245,7 @@ $$(dir.bld.c)/org_sqlite_jni$(3)_$(2).h: $(1)/$(2).java
|
|||||||
endef
|
endef
|
||||||
# Invoke ADD_JNI_H once for each Java file which includes JNI
|
# Invoke ADD_JNI_H once for each Java file which includes JNI
|
||||||
# declarations:
|
# declarations:
|
||||||
$(eval $(call ADD_JNI_H,$(dir.src.jni),SQLite3Jni,))
|
$(eval $(call ADD_JNI_H,$(dir.src.jni),CApi,))
|
||||||
$(eval $(call ADD_JNI_H,$(dir.src.jni),SQLTester,))
|
$(eval $(call ADD_JNI_H,$(dir.src.jni),SQLTester,))
|
||||||
ifeq (1,$(enable.fts5))
|
ifeq (1,$(enable.fts5))
|
||||||
$(eval $(call ADD_JNI_H,$(dir.src.fts5),Fts5ExtensionApi,_fts5))
|
$(eval $(call ADD_JNI_H,$(dir.src.fts5),Fts5ExtensionApi,_fts5))
|
||||||
@@ -295,19 +297,23 @@ $(package.dll): $(sqlite3-jni.c) $(MAKEFILE)
|
|||||||
all: $(package.dll)
|
all: $(package.dll)
|
||||||
|
|
||||||
.PHONY: test test-one
|
.PHONY: test test-one
|
||||||
test.flags ?=
|
Tester1.flags ?=
|
||||||
test.main.flags = -ea -Djava.library.path=$(dir.bld.c) \
|
Tester2.flags ?=
|
||||||
$(java.flags) -cp $(classpath) \
|
test.flags.jvm = -ea -Djava.library.path=$(dir.bld.c) \
|
||||||
org.sqlite.jni.Tester1
|
$(java.flags) -cp $(classpath)
|
||||||
test.deps := $(CLASS_FILES) $(package.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.flags.jvm) org.sqlite.jni.Tester1 $(Tester1.flags)
|
||||||
|
# $(bin.java) $(test.flags.jvm) org.sqlite.jni.Tester2 $(Tester2.flags)
|
||||||
test-sqllog: $(test.deps)
|
test-sqllog: $(test.deps)
|
||||||
@echo "Testing with -sqllog..."
|
@echo "Testing with -sqllog..."
|
||||||
$(bin.java) $(test.main.flags) -sqllog
|
$(bin.java) $(test.flags.jvm) -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 7 -r 50 -shuffle $(test.flags)
|
$(bin.java) $(test.flags.jvm) org.sqlite.jni.Tester1 \
|
||||||
|
-t 7 -r 50 -shuffle $(Tester1.flags)
|
||||||
|
$(bin.java) $(test.flags.jvm) org.sqlite.jni.Tester2 \
|
||||||
|
-t 7 -r 50 -shuffle $(Tester2.flags)
|
||||||
|
|
||||||
test: test-one test-mt
|
test: test-one test-mt
|
||||||
tests: test test-sqllog
|
tests: test test-sqllog
|
||||||
|
@@ -55,7 +55,7 @@ Hello World
|
|||||||
|
|
||||||
```java
|
```java
|
||||||
import org.sqlite.jni.*;
|
import org.sqlite.jni.*;
|
||||||
import static org.sqlite.jni.SQLite3Jni.*;
|
import static org.sqlite.jni.CApi.*;
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
**
|
**
|
||||||
*************************************************************************
|
*************************************************************************
|
||||||
** This file implements the JNI bindings declared in
|
** This file implements the JNI bindings declared in
|
||||||
** org.sqlite.jni.SQLiteJni (from which sqlite3-jni.h is generated).
|
** org.sqlite.jni.CApi (from which sqlite3-jni.h is generated).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
** prefix seen in this macro.
|
** prefix seen in this macro.
|
||||||
*/
|
*/
|
||||||
#define JniFuncName(Suffix) \
|
#define JniFuncName(Suffix) \
|
||||||
Java_org_sqlite_jni_SQLite3Jni_sqlite3_ ## Suffix
|
Java_org_sqlite_jni_CApi_sqlite3_ ## Suffix
|
||||||
|
|
||||||
/* Prologue for JNI function declarations and definitions. */
|
/* Prologue for JNI function declarations and definitions. */
|
||||||
#define JniDecl(ReturnType,Suffix) \
|
#define JniDecl(ReturnType,Suffix) \
|
||||||
@@ -5661,11 +5661,11 @@ Java_org_sqlite_jni_SQLTester_installCustomExtensions(JniArgsEnvClass){
|
|||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Called during static init of the SQLite3Jni class to set up global
|
** Called during static init of the CApi class to set up global
|
||||||
** state.
|
** state.
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_org_sqlite_jni_SQLite3Jni_init(JniArgsEnvClass){
|
Java_org_sqlite_jni_CApi_init(JniArgsEnvClass){
|
||||||
jclass klazz;
|
jclass klazz;
|
||||||
|
|
||||||
memset(&S3JniGlobal, 0, sizeof(S3JniGlobal));
|
memset(&S3JniGlobal, 0, sizeof(S3JniGlobal));
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ package org.sqlite.jni;
|
|||||||
import org.sqlite.jni.annotation.*;
|
import org.sqlite.jni.annotation.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_set_authorizer}.
|
Callback for use with {@link CApi#sqlite3_set_authorizer}.
|
||||||
*/
|
*/
|
||||||
public interface AuthorizerCallback extends CallbackProxy {
|
public interface AuthorizerCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with the {@link SQLite3Jni#sqlite3_auto_extension}
|
Callback for use with the {@link CApi#sqlite3_auto_extension}
|
||||||
family of APIs.
|
family of APIs.
|
||||||
*/
|
*/
|
||||||
public interface AutoExtensionCallback extends CallbackProxy {
|
public interface AutoExtensionCallback extends CallbackProxy {
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_busy_handler}.
|
Callback for use with {@link CApi#sqlite3_busy_handler}.
|
||||||
*/
|
*/
|
||||||
public interface BusyHandlerCallback extends CallbackProxy {
|
public interface BusyHandlerCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ package org.sqlite.jni;
|
|||||||
import org.sqlite.jni.annotation.NotNull;
|
import org.sqlite.jni.annotation.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_create_collation}.
|
Callback for use with {@link CApi#sqlite3_create_collation}.
|
||||||
|
|
||||||
@see AbstractCollationCallback
|
@see AbstractCollationCallback
|
||||||
*/
|
*/
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_collation_needed}.
|
Callback for use with {@link CApi#sqlite3_collation_needed}.
|
||||||
*/
|
*/
|
||||||
public interface CollationNeededCallback extends CallbackProxy {
|
public interface CollationNeededCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_commit_hook}.
|
Callback for use with {@link CApi#sqlite3_commit_hook}.
|
||||||
*/
|
*/
|
||||||
public interface CommitHookCallback extends CallbackProxy {
|
public interface CommitHookCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -19,7 +19,7 @@ package org.sqlite.jni;
|
|||||||
public interface ConfigLogCallback {
|
public interface ConfigLogCallback {
|
||||||
/**
|
/**
|
||||||
Must function as described for a C-level callback for
|
Must function as described for a C-level callback for
|
||||||
{@link SQLite3Jni#sqlite3_config(ConfigLogCallback)}, with the slight signature change.
|
{@link CApi#sqlite3_config(ConfigLogCallback)}, with the slight signature change.
|
||||||
*/
|
*/
|
||||||
void call(int errCode, String msg);
|
void call(int errCode, String msg);
|
||||||
}
|
}
|
||||||
|
@@ -19,7 +19,7 @@ package org.sqlite.jni;
|
|||||||
public interface ConfigSqllogCallback {
|
public interface ConfigSqllogCallback {
|
||||||
/**
|
/**
|
||||||
Must function as described for a C-level callback for
|
Must function as described for a C-level callback for
|
||||||
{@link SQLite3Jni#sqlite3_config(ConfigSqllogCallback)}, with the slight signature change.
|
{@link CApi#sqlite3_config(ConfigSqllogCallback)}, with the slight signature change.
|
||||||
*/
|
*/
|
||||||
void call(sqlite3 db, String msg, int msgType );
|
void call(sqlite3 db, String msg, int msgType );
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_prepare_multi}.
|
Callback for use with {@link CApi#sqlite3_prepare_multi}.
|
||||||
*/
|
*/
|
||||||
public interface PrepareMultiCallback extends CallbackProxy {
|
public interface PrepareMultiCallback extends CallbackProxy {
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ public interface PrepareMultiCallback extends CallbackProxy {
|
|||||||
try {
|
try {
|
||||||
return this.p.call(st);
|
return this.p.call(st);
|
||||||
}finally{
|
}finally{
|
||||||
SQLite3Jni.sqlite3_finalize(st);
|
CApi.sqlite3_finalize(st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,9 +70,9 @@ public interface PrepareMultiCallback extends CallbackProxy {
|
|||||||
else the result of the final step is returned.
|
else the result of the final step is returned.
|
||||||
*/
|
*/
|
||||||
@Override public int call(sqlite3_stmt st){
|
@Override public int call(sqlite3_stmt st){
|
||||||
int rc = SQLite3Jni.SQLITE_DONE;
|
int rc = CApi.SQLITE_DONE;
|
||||||
while( SQLite3Jni.SQLITE_ROW == (rc = SQLite3Jni.sqlite3_step(st)) ){}
|
while( CApi.SQLITE_ROW == (rc = CApi.sqlite3_step(st)) ){}
|
||||||
return SQLite3Jni.SQLITE_DONE==rc ? 0 : rc;
|
return CApi.SQLITE_DONE==rc ? 0 : rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_preupdate_hook}.
|
Callback for use with {@link CApi#sqlite3_preupdate_hook}.
|
||||||
*/
|
*/
|
||||||
public interface PreupdateHookCallback extends CallbackProxy {
|
public interface PreupdateHookCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_progress_handler}.
|
Callback for use with {@link CApi#sqlite3_progress_handler}.
|
||||||
*/
|
*/
|
||||||
public interface ProgressHandlerCallback extends CallbackProxy {
|
public interface ProgressHandlerCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -20,110 +20,110 @@ package org.sqlite.jni;
|
|||||||
find it useful to map SQLite result codes to human-readable names.
|
find it useful to map SQLite result codes to human-readable names.
|
||||||
*/
|
*/
|
||||||
public enum ResultCode {
|
public enum ResultCode {
|
||||||
SQLITE_OK(SQLite3Jni.SQLITE_OK),
|
SQLITE_OK(CApi.SQLITE_OK),
|
||||||
SQLITE_ERROR(SQLite3Jni.SQLITE_ERROR),
|
SQLITE_ERROR(CApi.SQLITE_ERROR),
|
||||||
SQLITE_INTERNAL(SQLite3Jni.SQLITE_INTERNAL),
|
SQLITE_INTERNAL(CApi.SQLITE_INTERNAL),
|
||||||
SQLITE_PERM(SQLite3Jni.SQLITE_PERM),
|
SQLITE_PERM(CApi.SQLITE_PERM),
|
||||||
SQLITE_ABORT(SQLite3Jni.SQLITE_ABORT),
|
SQLITE_ABORT(CApi.SQLITE_ABORT),
|
||||||
SQLITE_BUSY(SQLite3Jni.SQLITE_BUSY),
|
SQLITE_BUSY(CApi.SQLITE_BUSY),
|
||||||
SQLITE_LOCKED(SQLite3Jni.SQLITE_LOCKED),
|
SQLITE_LOCKED(CApi.SQLITE_LOCKED),
|
||||||
SQLITE_NOMEM(SQLite3Jni.SQLITE_NOMEM),
|
SQLITE_NOMEM(CApi.SQLITE_NOMEM),
|
||||||
SQLITE_READONLY(SQLite3Jni.SQLITE_READONLY),
|
SQLITE_READONLY(CApi.SQLITE_READONLY),
|
||||||
SQLITE_INTERRUPT(SQLite3Jni.SQLITE_INTERRUPT),
|
SQLITE_INTERRUPT(CApi.SQLITE_INTERRUPT),
|
||||||
SQLITE_IOERR(SQLite3Jni.SQLITE_IOERR),
|
SQLITE_IOERR(CApi.SQLITE_IOERR),
|
||||||
SQLITE_CORRUPT(SQLite3Jni.SQLITE_CORRUPT),
|
SQLITE_CORRUPT(CApi.SQLITE_CORRUPT),
|
||||||
SQLITE_NOTFOUND(SQLite3Jni.SQLITE_NOTFOUND),
|
SQLITE_NOTFOUND(CApi.SQLITE_NOTFOUND),
|
||||||
SQLITE_FULL(SQLite3Jni.SQLITE_FULL),
|
SQLITE_FULL(CApi.SQLITE_FULL),
|
||||||
SQLITE_CANTOPEN(SQLite3Jni.SQLITE_CANTOPEN),
|
SQLITE_CANTOPEN(CApi.SQLITE_CANTOPEN),
|
||||||
SQLITE_PROTOCOL(SQLite3Jni.SQLITE_PROTOCOL),
|
SQLITE_PROTOCOL(CApi.SQLITE_PROTOCOL),
|
||||||
SQLITE_EMPTY(SQLite3Jni.SQLITE_EMPTY),
|
SQLITE_EMPTY(CApi.SQLITE_EMPTY),
|
||||||
SQLITE_SCHEMA(SQLite3Jni.SQLITE_SCHEMA),
|
SQLITE_SCHEMA(CApi.SQLITE_SCHEMA),
|
||||||
SQLITE_TOOBIG(SQLite3Jni.SQLITE_TOOBIG),
|
SQLITE_TOOBIG(CApi.SQLITE_TOOBIG),
|
||||||
SQLITE_CONSTRAINT(SQLite3Jni.SQLITE_CONSTRAINT),
|
SQLITE_CONSTRAINT(CApi.SQLITE_CONSTRAINT),
|
||||||
SQLITE_MISMATCH(SQLite3Jni.SQLITE_MISMATCH),
|
SQLITE_MISMATCH(CApi.SQLITE_MISMATCH),
|
||||||
SQLITE_MISUSE(SQLite3Jni.SQLITE_MISUSE),
|
SQLITE_MISUSE(CApi.SQLITE_MISUSE),
|
||||||
SQLITE_NOLFS(SQLite3Jni.SQLITE_NOLFS),
|
SQLITE_NOLFS(CApi.SQLITE_NOLFS),
|
||||||
SQLITE_AUTH(SQLite3Jni.SQLITE_AUTH),
|
SQLITE_AUTH(CApi.SQLITE_AUTH),
|
||||||
SQLITE_FORMAT(SQLite3Jni.SQLITE_FORMAT),
|
SQLITE_FORMAT(CApi.SQLITE_FORMAT),
|
||||||
SQLITE_RANGE(SQLite3Jni.SQLITE_RANGE),
|
SQLITE_RANGE(CApi.SQLITE_RANGE),
|
||||||
SQLITE_NOTADB(SQLite3Jni.SQLITE_NOTADB),
|
SQLITE_NOTADB(CApi.SQLITE_NOTADB),
|
||||||
SQLITE_NOTICE(SQLite3Jni.SQLITE_NOTICE),
|
SQLITE_NOTICE(CApi.SQLITE_NOTICE),
|
||||||
SQLITE_WARNING(SQLite3Jni.SQLITE_WARNING),
|
SQLITE_WARNING(CApi.SQLITE_WARNING),
|
||||||
SQLITE_ROW(SQLite3Jni.SQLITE_ROW),
|
SQLITE_ROW(CApi.SQLITE_ROW),
|
||||||
SQLITE_DONE(SQLite3Jni.SQLITE_DONE),
|
SQLITE_DONE(CApi.SQLITE_DONE),
|
||||||
SQLITE_ERROR_MISSING_COLLSEQ(SQLite3Jni.SQLITE_ERROR_MISSING_COLLSEQ),
|
SQLITE_ERROR_MISSING_COLLSEQ(CApi.SQLITE_ERROR_MISSING_COLLSEQ),
|
||||||
SQLITE_ERROR_RETRY(SQLite3Jni.SQLITE_ERROR_RETRY),
|
SQLITE_ERROR_RETRY(CApi.SQLITE_ERROR_RETRY),
|
||||||
SQLITE_ERROR_SNAPSHOT(SQLite3Jni.SQLITE_ERROR_SNAPSHOT),
|
SQLITE_ERROR_SNAPSHOT(CApi.SQLITE_ERROR_SNAPSHOT),
|
||||||
SQLITE_IOERR_READ(SQLite3Jni.SQLITE_IOERR_READ),
|
SQLITE_IOERR_READ(CApi.SQLITE_IOERR_READ),
|
||||||
SQLITE_IOERR_SHORT_READ(SQLite3Jni.SQLITE_IOERR_SHORT_READ),
|
SQLITE_IOERR_SHORT_READ(CApi.SQLITE_IOERR_SHORT_READ),
|
||||||
SQLITE_IOERR_WRITE(SQLite3Jni.SQLITE_IOERR_WRITE),
|
SQLITE_IOERR_WRITE(CApi.SQLITE_IOERR_WRITE),
|
||||||
SQLITE_IOERR_FSYNC(SQLite3Jni.SQLITE_IOERR_FSYNC),
|
SQLITE_IOERR_FSYNC(CApi.SQLITE_IOERR_FSYNC),
|
||||||
SQLITE_IOERR_DIR_FSYNC(SQLite3Jni.SQLITE_IOERR_DIR_FSYNC),
|
SQLITE_IOERR_DIR_FSYNC(CApi.SQLITE_IOERR_DIR_FSYNC),
|
||||||
SQLITE_IOERR_TRUNCATE(SQLite3Jni.SQLITE_IOERR_TRUNCATE),
|
SQLITE_IOERR_TRUNCATE(CApi.SQLITE_IOERR_TRUNCATE),
|
||||||
SQLITE_IOERR_FSTAT(SQLite3Jni.SQLITE_IOERR_FSTAT),
|
SQLITE_IOERR_FSTAT(CApi.SQLITE_IOERR_FSTAT),
|
||||||
SQLITE_IOERR_UNLOCK(SQLite3Jni.SQLITE_IOERR_UNLOCK),
|
SQLITE_IOERR_UNLOCK(CApi.SQLITE_IOERR_UNLOCK),
|
||||||
SQLITE_IOERR_RDLOCK(SQLite3Jni.SQLITE_IOERR_RDLOCK),
|
SQLITE_IOERR_RDLOCK(CApi.SQLITE_IOERR_RDLOCK),
|
||||||
SQLITE_IOERR_DELETE(SQLite3Jni.SQLITE_IOERR_DELETE),
|
SQLITE_IOERR_DELETE(CApi.SQLITE_IOERR_DELETE),
|
||||||
SQLITE_IOERR_BLOCKED(SQLite3Jni.SQLITE_IOERR_BLOCKED),
|
SQLITE_IOERR_BLOCKED(CApi.SQLITE_IOERR_BLOCKED),
|
||||||
SQLITE_IOERR_NOMEM(SQLite3Jni.SQLITE_IOERR_NOMEM),
|
SQLITE_IOERR_NOMEM(CApi.SQLITE_IOERR_NOMEM),
|
||||||
SQLITE_IOERR_ACCESS(SQLite3Jni.SQLITE_IOERR_ACCESS),
|
SQLITE_IOERR_ACCESS(CApi.SQLITE_IOERR_ACCESS),
|
||||||
SQLITE_IOERR_CHECKRESERVEDLOCK(SQLite3Jni.SQLITE_IOERR_CHECKRESERVEDLOCK),
|
SQLITE_IOERR_CHECKRESERVEDLOCK(CApi.SQLITE_IOERR_CHECKRESERVEDLOCK),
|
||||||
SQLITE_IOERR_LOCK(SQLite3Jni.SQLITE_IOERR_LOCK),
|
SQLITE_IOERR_LOCK(CApi.SQLITE_IOERR_LOCK),
|
||||||
SQLITE_IOERR_CLOSE(SQLite3Jni.SQLITE_IOERR_CLOSE),
|
SQLITE_IOERR_CLOSE(CApi.SQLITE_IOERR_CLOSE),
|
||||||
SQLITE_IOERR_DIR_CLOSE(SQLite3Jni.SQLITE_IOERR_DIR_CLOSE),
|
SQLITE_IOERR_DIR_CLOSE(CApi.SQLITE_IOERR_DIR_CLOSE),
|
||||||
SQLITE_IOERR_SHMOPEN(SQLite3Jni.SQLITE_IOERR_SHMOPEN),
|
SQLITE_IOERR_SHMOPEN(CApi.SQLITE_IOERR_SHMOPEN),
|
||||||
SQLITE_IOERR_SHMSIZE(SQLite3Jni.SQLITE_IOERR_SHMSIZE),
|
SQLITE_IOERR_SHMSIZE(CApi.SQLITE_IOERR_SHMSIZE),
|
||||||
SQLITE_IOERR_SHMLOCK(SQLite3Jni.SQLITE_IOERR_SHMLOCK),
|
SQLITE_IOERR_SHMLOCK(CApi.SQLITE_IOERR_SHMLOCK),
|
||||||
SQLITE_IOERR_SHMMAP(SQLite3Jni.SQLITE_IOERR_SHMMAP),
|
SQLITE_IOERR_SHMMAP(CApi.SQLITE_IOERR_SHMMAP),
|
||||||
SQLITE_IOERR_SEEK(SQLite3Jni.SQLITE_IOERR_SEEK),
|
SQLITE_IOERR_SEEK(CApi.SQLITE_IOERR_SEEK),
|
||||||
SQLITE_IOERR_DELETE_NOENT(SQLite3Jni.SQLITE_IOERR_DELETE_NOENT),
|
SQLITE_IOERR_DELETE_NOENT(CApi.SQLITE_IOERR_DELETE_NOENT),
|
||||||
SQLITE_IOERR_MMAP(SQLite3Jni.SQLITE_IOERR_MMAP),
|
SQLITE_IOERR_MMAP(CApi.SQLITE_IOERR_MMAP),
|
||||||
SQLITE_IOERR_GETTEMPPATH(SQLite3Jni.SQLITE_IOERR_GETTEMPPATH),
|
SQLITE_IOERR_GETTEMPPATH(CApi.SQLITE_IOERR_GETTEMPPATH),
|
||||||
SQLITE_IOERR_CONVPATH(SQLite3Jni.SQLITE_IOERR_CONVPATH),
|
SQLITE_IOERR_CONVPATH(CApi.SQLITE_IOERR_CONVPATH),
|
||||||
SQLITE_IOERR_VNODE(SQLite3Jni.SQLITE_IOERR_VNODE),
|
SQLITE_IOERR_VNODE(CApi.SQLITE_IOERR_VNODE),
|
||||||
SQLITE_IOERR_AUTH(SQLite3Jni.SQLITE_IOERR_AUTH),
|
SQLITE_IOERR_AUTH(CApi.SQLITE_IOERR_AUTH),
|
||||||
SQLITE_IOERR_BEGIN_ATOMIC(SQLite3Jni.SQLITE_IOERR_BEGIN_ATOMIC),
|
SQLITE_IOERR_BEGIN_ATOMIC(CApi.SQLITE_IOERR_BEGIN_ATOMIC),
|
||||||
SQLITE_IOERR_COMMIT_ATOMIC(SQLite3Jni.SQLITE_IOERR_COMMIT_ATOMIC),
|
SQLITE_IOERR_COMMIT_ATOMIC(CApi.SQLITE_IOERR_COMMIT_ATOMIC),
|
||||||
SQLITE_IOERR_ROLLBACK_ATOMIC(SQLite3Jni.SQLITE_IOERR_ROLLBACK_ATOMIC),
|
SQLITE_IOERR_ROLLBACK_ATOMIC(CApi.SQLITE_IOERR_ROLLBACK_ATOMIC),
|
||||||
SQLITE_IOERR_DATA(SQLite3Jni.SQLITE_IOERR_DATA),
|
SQLITE_IOERR_DATA(CApi.SQLITE_IOERR_DATA),
|
||||||
SQLITE_IOERR_CORRUPTFS(SQLite3Jni.SQLITE_IOERR_CORRUPTFS),
|
SQLITE_IOERR_CORRUPTFS(CApi.SQLITE_IOERR_CORRUPTFS),
|
||||||
SQLITE_LOCKED_SHAREDCACHE(SQLite3Jni.SQLITE_LOCKED_SHAREDCACHE),
|
SQLITE_LOCKED_SHAREDCACHE(CApi.SQLITE_LOCKED_SHAREDCACHE),
|
||||||
SQLITE_LOCKED_VTAB(SQLite3Jni.SQLITE_LOCKED_VTAB),
|
SQLITE_LOCKED_VTAB(CApi.SQLITE_LOCKED_VTAB),
|
||||||
SQLITE_BUSY_RECOVERY(SQLite3Jni.SQLITE_BUSY_RECOVERY),
|
SQLITE_BUSY_RECOVERY(CApi.SQLITE_BUSY_RECOVERY),
|
||||||
SQLITE_BUSY_SNAPSHOT(SQLite3Jni.SQLITE_BUSY_SNAPSHOT),
|
SQLITE_BUSY_SNAPSHOT(CApi.SQLITE_BUSY_SNAPSHOT),
|
||||||
SQLITE_BUSY_TIMEOUT(SQLite3Jni.SQLITE_BUSY_TIMEOUT),
|
SQLITE_BUSY_TIMEOUT(CApi.SQLITE_BUSY_TIMEOUT),
|
||||||
SQLITE_CANTOPEN_NOTEMPDIR(SQLite3Jni.SQLITE_CANTOPEN_NOTEMPDIR),
|
SQLITE_CANTOPEN_NOTEMPDIR(CApi.SQLITE_CANTOPEN_NOTEMPDIR),
|
||||||
SQLITE_CANTOPEN_ISDIR(SQLite3Jni.SQLITE_CANTOPEN_ISDIR),
|
SQLITE_CANTOPEN_ISDIR(CApi.SQLITE_CANTOPEN_ISDIR),
|
||||||
SQLITE_CANTOPEN_FULLPATH(SQLite3Jni.SQLITE_CANTOPEN_FULLPATH),
|
SQLITE_CANTOPEN_FULLPATH(CApi.SQLITE_CANTOPEN_FULLPATH),
|
||||||
SQLITE_CANTOPEN_CONVPATH(SQLite3Jni.SQLITE_CANTOPEN_CONVPATH),
|
SQLITE_CANTOPEN_CONVPATH(CApi.SQLITE_CANTOPEN_CONVPATH),
|
||||||
SQLITE_CANTOPEN_SYMLINK(SQLite3Jni.SQLITE_CANTOPEN_SYMLINK),
|
SQLITE_CANTOPEN_SYMLINK(CApi.SQLITE_CANTOPEN_SYMLINK),
|
||||||
SQLITE_CORRUPT_VTAB(SQLite3Jni.SQLITE_CORRUPT_VTAB),
|
SQLITE_CORRUPT_VTAB(CApi.SQLITE_CORRUPT_VTAB),
|
||||||
SQLITE_CORRUPT_SEQUENCE(SQLite3Jni.SQLITE_CORRUPT_SEQUENCE),
|
SQLITE_CORRUPT_SEQUENCE(CApi.SQLITE_CORRUPT_SEQUENCE),
|
||||||
SQLITE_CORRUPT_INDEX(SQLite3Jni.SQLITE_CORRUPT_INDEX),
|
SQLITE_CORRUPT_INDEX(CApi.SQLITE_CORRUPT_INDEX),
|
||||||
SQLITE_READONLY_RECOVERY(SQLite3Jni.SQLITE_READONLY_RECOVERY),
|
SQLITE_READONLY_RECOVERY(CApi.SQLITE_READONLY_RECOVERY),
|
||||||
SQLITE_READONLY_CANTLOCK(SQLite3Jni.SQLITE_READONLY_CANTLOCK),
|
SQLITE_READONLY_CANTLOCK(CApi.SQLITE_READONLY_CANTLOCK),
|
||||||
SQLITE_READONLY_ROLLBACK(SQLite3Jni.SQLITE_READONLY_ROLLBACK),
|
SQLITE_READONLY_ROLLBACK(CApi.SQLITE_READONLY_ROLLBACK),
|
||||||
SQLITE_READONLY_DBMOVED(SQLite3Jni.SQLITE_READONLY_DBMOVED),
|
SQLITE_READONLY_DBMOVED(CApi.SQLITE_READONLY_DBMOVED),
|
||||||
SQLITE_READONLY_CANTINIT(SQLite3Jni.SQLITE_READONLY_CANTINIT),
|
SQLITE_READONLY_CANTINIT(CApi.SQLITE_READONLY_CANTINIT),
|
||||||
SQLITE_READONLY_DIRECTORY(SQLite3Jni.SQLITE_READONLY_DIRECTORY),
|
SQLITE_READONLY_DIRECTORY(CApi.SQLITE_READONLY_DIRECTORY),
|
||||||
SQLITE_ABORT_ROLLBACK(SQLite3Jni.SQLITE_ABORT_ROLLBACK),
|
SQLITE_ABORT_ROLLBACK(CApi.SQLITE_ABORT_ROLLBACK),
|
||||||
SQLITE_CONSTRAINT_CHECK(SQLite3Jni.SQLITE_CONSTRAINT_CHECK),
|
SQLITE_CONSTRAINT_CHECK(CApi.SQLITE_CONSTRAINT_CHECK),
|
||||||
SQLITE_CONSTRAINT_COMMITHOOK(SQLite3Jni.SQLITE_CONSTRAINT_COMMITHOOK),
|
SQLITE_CONSTRAINT_COMMITHOOK(CApi.SQLITE_CONSTRAINT_COMMITHOOK),
|
||||||
SQLITE_CONSTRAINT_FOREIGNKEY(SQLite3Jni.SQLITE_CONSTRAINT_FOREIGNKEY),
|
SQLITE_CONSTRAINT_FOREIGNKEY(CApi.SQLITE_CONSTRAINT_FOREIGNKEY),
|
||||||
SQLITE_CONSTRAINT_FUNCTION(SQLite3Jni.SQLITE_CONSTRAINT_FUNCTION),
|
SQLITE_CONSTRAINT_FUNCTION(CApi.SQLITE_CONSTRAINT_FUNCTION),
|
||||||
SQLITE_CONSTRAINT_NOTNULL(SQLite3Jni.SQLITE_CONSTRAINT_NOTNULL),
|
SQLITE_CONSTRAINT_NOTNULL(CApi.SQLITE_CONSTRAINT_NOTNULL),
|
||||||
SQLITE_CONSTRAINT_PRIMARYKEY(SQLite3Jni.SQLITE_CONSTRAINT_PRIMARYKEY),
|
SQLITE_CONSTRAINT_PRIMARYKEY(CApi.SQLITE_CONSTRAINT_PRIMARYKEY),
|
||||||
SQLITE_CONSTRAINT_TRIGGER(SQLite3Jni.SQLITE_CONSTRAINT_TRIGGER),
|
SQLITE_CONSTRAINT_TRIGGER(CApi.SQLITE_CONSTRAINT_TRIGGER),
|
||||||
SQLITE_CONSTRAINT_UNIQUE(SQLite3Jni.SQLITE_CONSTRAINT_UNIQUE),
|
SQLITE_CONSTRAINT_UNIQUE(CApi.SQLITE_CONSTRAINT_UNIQUE),
|
||||||
SQLITE_CONSTRAINT_VTAB(SQLite3Jni.SQLITE_CONSTRAINT_VTAB),
|
SQLITE_CONSTRAINT_VTAB(CApi.SQLITE_CONSTRAINT_VTAB),
|
||||||
SQLITE_CONSTRAINT_ROWID(SQLite3Jni.SQLITE_CONSTRAINT_ROWID),
|
SQLITE_CONSTRAINT_ROWID(CApi.SQLITE_CONSTRAINT_ROWID),
|
||||||
SQLITE_CONSTRAINT_PINNED(SQLite3Jni.SQLITE_CONSTRAINT_PINNED),
|
SQLITE_CONSTRAINT_PINNED(CApi.SQLITE_CONSTRAINT_PINNED),
|
||||||
SQLITE_CONSTRAINT_DATATYPE(SQLite3Jni.SQLITE_CONSTRAINT_DATATYPE),
|
SQLITE_CONSTRAINT_DATATYPE(CApi.SQLITE_CONSTRAINT_DATATYPE),
|
||||||
SQLITE_NOTICE_RECOVER_WAL(SQLite3Jni.SQLITE_NOTICE_RECOVER_WAL),
|
SQLITE_NOTICE_RECOVER_WAL(CApi.SQLITE_NOTICE_RECOVER_WAL),
|
||||||
SQLITE_NOTICE_RECOVER_ROLLBACK(SQLite3Jni.SQLITE_NOTICE_RECOVER_ROLLBACK),
|
SQLITE_NOTICE_RECOVER_ROLLBACK(CApi.SQLITE_NOTICE_RECOVER_ROLLBACK),
|
||||||
SQLITE_WARNING_AUTOINDEX(SQLite3Jni.SQLITE_WARNING_AUTOINDEX),
|
SQLITE_WARNING_AUTOINDEX(CApi.SQLITE_WARNING_AUTOINDEX),
|
||||||
SQLITE_AUTH_USER(SQLite3Jni.SQLITE_AUTH_USER),
|
SQLITE_AUTH_USER(CApi.SQLITE_AUTH_USER),
|
||||||
SQLITE_OK_LOAD_PERMANENTLY(SQLite3Jni.SQLITE_OK_LOAD_PERMANENTLY);
|
SQLITE_OK_LOAD_PERMANENTLY(CApi.SQLITE_OK_LOAD_PERMANENTLY);
|
||||||
|
|
||||||
public final int value;
|
public final int value;
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_rollback_hook}.
|
Callback for use with {@link CApi#sqlite3_rollback_hook}.
|
||||||
*/
|
*/
|
||||||
public interface RollbackHookCallback extends CallbackProxy {
|
public interface RollbackHookCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -18,7 +18,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.regex.*;
|
import java.util.regex.*;
|
||||||
import static org.sqlite.jni.SQLite3Jni.*;
|
import static org.sqlite.jni.CApi.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Modes for how to escape (or not) column values and names from
|
Modes for how to escape (or not) column values and names from
|
||||||
@@ -668,7 +668,7 @@ public class SQLTester {
|
|||||||
static {
|
static {
|
||||||
System.loadLibrary("sqlite3-jni")
|
System.loadLibrary("sqlite3-jni")
|
||||||
/* Interestingly, when SQLTester is the main app, we have to
|
/* Interestingly, when SQLTester is the main app, we have to
|
||||||
load that lib from here. The same load from SQLite3Jni does
|
load that lib from here. The same load from CApi does
|
||||||
not happen early enough. Without this,
|
not happen early enough. Without this,
|
||||||
installCustomExtensions() is an unresolved symbol. */;
|
installCustomExtensions() is an unresolved symbol. */;
|
||||||
}
|
}
|
||||||
|
69
ext/jni/src/org/sqlite/jni/Sqlite.java
Normal file
69
ext/jni/src/org/sqlite/jni/Sqlite.java
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
** 2023-10-09
|
||||||
|
**
|
||||||
|
** 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;
|
||||||
|
import static org.sqlite.jni.CApi.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
This class represents a database connection, analog to the C-side
|
||||||
|
sqlite3 class but with added argument validation, exceptions, and
|
||||||
|
similar "smoothing of sharp edges" to make the API safe to use from
|
||||||
|
Java. It also acts as a namespace for other types for which
|
||||||
|
individual instances are tied to a specific database connection.
|
||||||
|
*/
|
||||||
|
public final class Sqlite implements AutoCloseable {
|
||||||
|
private sqlite3 db = null;
|
||||||
|
|
||||||
|
//! Used only by the open() factory functions.
|
||||||
|
private Sqlite(sqlite3 db){
|
||||||
|
this.db = db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns a newly-opened db connection or throws SqliteException if
|
||||||
|
opening fails. All arguments are as documented for
|
||||||
|
sqlite3_open_v2().
|
||||||
|
*/
|
||||||
|
public static Sqlite open(String filename, int flags, String vfsName){
|
||||||
|
final OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
|
||||||
|
final int rc = sqlite3_open_v2(filename, out, flags, vfsName);
|
||||||
|
final sqlite3 n = out.take();
|
||||||
|
if( 0!=rc ){
|
||||||
|
if( null==n ) throw new SqliteException(rc);
|
||||||
|
else throw new SqliteException(n);
|
||||||
|
}
|
||||||
|
return new Sqlite(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Sqlite open(String filename, int flags){
|
||||||
|
return open(filename, flags, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Sqlite open(String filename){
|
||||||
|
return open(filename, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void close(){
|
||||||
|
if(null!=this.db){
|
||||||
|
this.db.close();
|
||||||
|
this.db = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns this object's underlying native db handle, or null if
|
||||||
|
this instance has been closed.
|
||||||
|
*/
|
||||||
|
sqlite3 dbHandle(){ return this.db; }
|
||||||
|
|
||||||
|
}
|
73
ext/jni/src/org/sqlite/jni/SqliteException.java
Normal file
73
ext/jni/src/org/sqlite/jni/SqliteException.java
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
** 2023-10-09
|
||||||
|
**
|
||||||
|
** 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;
|
||||||
|
import static org.sqlite.jni.CApi.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
A wrapper for communicating C-level (sqlite3*) instances with
|
||||||
|
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 SqliteException extends java.lang.RuntimeException {
|
||||||
|
int errCode = SQLITE_ERROR;
|
||||||
|
int xerrCode = SQLITE_ERROR;
|
||||||
|
int errOffset = -1;
|
||||||
|
int sysErrno = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Records the given error string and uses SQLITE_ERROR for both the
|
||||||
|
error code and extended error code.
|
||||||
|
*/
|
||||||
|
public SqliteException(String msg){
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Uses sqlite3_errstr(sqlite3ResultCode) for the error string and
|
||||||
|
sets both the error code and extended error code to the given
|
||||||
|
value.
|
||||||
|
*/
|
||||||
|
public SqliteException(int sqlite3ResultCode){
|
||||||
|
super(sqlite3_errstr(sqlite3ResultCode));
|
||||||
|
errCode = xerrCode = sqlite3ResultCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Records the current error state of db (which must not be null and
|
||||||
|
must refer to an opened db object) then closes it.
|
||||||
|
*/
|
||||||
|
public SqliteException(sqlite3 db){
|
||||||
|
super(sqlite3_errmsg(db));
|
||||||
|
errCode = sqlite3_errcode(db);
|
||||||
|
xerrCode = sqlite3_extended_errcode(db);
|
||||||
|
errOffset = sqlite3_error_offset(db);
|
||||||
|
sysErrno = sqlite3_system_errno(db);
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Records the current error state of db (which must not be null and must
|
||||||
|
refer to an open database) then closes it.
|
||||||
|
*/
|
||||||
|
public SqliteException(Sqlite db){
|
||||||
|
this(db.dbHandle());
|
||||||
|
}
|
||||||
|
|
||||||
|
public int errcode(){ return errCode; }
|
||||||
|
public int extendedErrcode(){ return xerrCode; }
|
||||||
|
public int errorOffset(){ return errOffset; }
|
||||||
|
public int systemErrno(){ return sysErrno; }
|
||||||
|
|
||||||
|
}
|
@@ -12,7 +12,7 @@
|
|||||||
** 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;
|
||||||
import static org.sqlite.jni.SQLite3Jni.*;
|
import static org.sqlite.jni.CApi.*;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -934,7 +934,7 @@ public class Tester1 implements Runnable {
|
|||||||
private void listBoundMethods(){
|
private void listBoundMethods(){
|
||||||
if(false){
|
if(false){
|
||||||
final java.lang.reflect.Field[] declaredFields =
|
final java.lang.reflect.Field[] declaredFields =
|
||||||
SQLite3Jni.class.getDeclaredFields();
|
CApi.class.getDeclaredFields();
|
||||||
outln("Bound constants:\n");
|
outln("Bound constants:\n");
|
||||||
for(java.lang.reflect.Field field : declaredFields) {
|
for(java.lang.reflect.Field field : declaredFields) {
|
||||||
if(java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
if(java.lang.reflect.Modifier.isStatic(field.getModifiers())) {
|
||||||
@@ -943,7 +943,7 @@ public class Tester1 implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
final java.lang.reflect.Method[] declaredMethods =
|
final java.lang.reflect.Method[] declaredMethods =
|
||||||
SQLite3Jni.class.getDeclaredMethods();
|
CApi.class.getDeclaredMethods();
|
||||||
final java.util.List<String> funcList = new java.util.ArrayList<>();
|
final java.util.List<String> funcList = new java.util.ArrayList<>();
|
||||||
for(java.lang.reflect.Method m : declaredMethods){
|
for(java.lang.reflect.Method m : declaredMethods){
|
||||||
if((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0){
|
if((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0){
|
||||||
@@ -1925,29 +1925,24 @@ public class Tester1 implements Runnable {
|
|||||||
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();
|
CApi.class.getDeclaredMethods();
|
||||||
for(java.lang.reflect.Method m : declaredMethods){
|
for(java.lang.reflect.Method m : declaredMethods){
|
||||||
final 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outln("\tSQLite3Jni.sqlite3_*() methods: "+
|
outln("\tCApi.sqlite3_*() methods: "+
|
||||||
nMethods+" total, with "+
|
nMethods+" total, with "+
|
||||||
nNatives+" native, "+
|
nNatives+" native, "+
|
||||||
(nMethods - nNatives)+" Java, ",
|
(nMethods - nNatives)+" Java"
|
||||||
nCanonical," @Canonical"
|
|
||||||
);
|
);
|
||||||
outln("\tTotal test time = "
|
outln("\tTotal test time = "
|
||||||
+(timeEnd - timeStart)+"ms");
|
+(timeEnd - timeStart)+"ms");
|
||||||
|
417
ext/jni/src/org/sqlite/jni/Tester2.java
Normal file
417
ext/jni/src/org/sqlite/jni/Tester2.java
Normal file
@@ -0,0 +1,417 @@
|
|||||||
|
/*
|
||||||
|
** 2023-10-09
|
||||||
|
**
|
||||||
|
** The author disclaims copyright to this source code. In place of
|
||||||
|
** a legal notice, here is a blessing:
|
||||||
|
**
|
||||||
|
** May you do good and not evil.
|
||||||
|
** May you find forgiveness for yourself and forgive others.
|
||||||
|
** May you share freely, never taking more than you give.
|
||||||
|
**
|
||||||
|
*************************************************************************
|
||||||
|
** This file contains a set of tests for the sqlite3 JNI bindings.
|
||||||
|
*/
|
||||||
|
package org.sqlite.jni;
|
||||||
|
import static org.sqlite.jni.CApi.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
public class Tester2 implements Runnable {
|
||||||
|
//! True when running in multi-threaded mode.
|
||||||
|
private static boolean mtMode = false;
|
||||||
|
//! True to sleep briefly between tests.
|
||||||
|
private static boolean takeNaps = false;
|
||||||
|
//! True to shuffle the order of the tests.
|
||||||
|
private static boolean shuffle = false;
|
||||||
|
//! True to dump the list of to-run tests to stdout.
|
||||||
|
private static boolean listRunTests = false;
|
||||||
|
//! True to squelch all out() and outln() output.
|
||||||
|
private static boolean quietMode = false;
|
||||||
|
//! Total number of runTests() calls.
|
||||||
|
private static int nTestRuns = 0;
|
||||||
|
//! List of test*() methods to run.
|
||||||
|
private static List<java.lang.reflect.Method> testMethods = null;
|
||||||
|
//! List of exceptions collected by run()
|
||||||
|
private static List<Exception> listErrors = new ArrayList<>();
|
||||||
|
private static final class Metrics {
|
||||||
|
//! Number of times createNewDb() (or equivalent) is invoked.
|
||||||
|
volatile int dbOpen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Instance ID.
|
||||||
|
private Integer tId;
|
||||||
|
|
||||||
|
Tester2(Integer id){
|
||||||
|
tId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static final Metrics metrics = new Metrics();
|
||||||
|
|
||||||
|
public static synchronized void outln(){
|
||||||
|
if( !quietMode ){
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void outPrefix(){
|
||||||
|
if( !quietMode ){
|
||||||
|
System.out.print(Thread.currentThread().getName()+": ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void outln(Object val){
|
||||||
|
if( !quietMode ){
|
||||||
|
outPrefix();
|
||||||
|
System.out.println(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void out(Object val){
|
||||||
|
if( !quietMode ){
|
||||||
|
System.out.print(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static synchronized void out(Object... vals){
|
||||||
|
if( !quietMode ){
|
||||||
|
outPrefix();
|
||||||
|
for(Object v : vals) out(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static synchronized void outln(Object... vals){
|
||||||
|
if( !quietMode ){
|
||||||
|
out(vals); out("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static volatile int affirmCount = 0;
|
||||||
|
public static synchronized int affirm(Boolean v, String comment){
|
||||||
|
++affirmCount;
|
||||||
|
if( false ) assert( v /* prefer assert over exception if it's enabled because
|
||||||
|
the JNI layer sometimes has to suppress exceptions,
|
||||||
|
so they might be squelched on their way back to the
|
||||||
|
top. */);
|
||||||
|
if( !v ) throw new RuntimeException(comment);
|
||||||
|
return affirmCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void affirm(Boolean v){
|
||||||
|
affirm(v, "Affirmation failed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@SingleThreadOnly /* because it's thread-agnostic */
|
||||||
|
private void test1(){
|
||||||
|
affirm(sqlite3_libversion_number() == SQLITE_VERSION_NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nap() throws InterruptedException {
|
||||||
|
if( takeNaps ){
|
||||||
|
Thread.sleep(java.util.concurrent.ThreadLocalRandom.current().nextInt(3, 17), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ManualTest /* because we only want to run this test on demand */
|
||||||
|
private void testFail(){
|
||||||
|
affirm( false, "Intentional failure." );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTests(boolean fromThread) throws Exception {
|
||||||
|
List<java.lang.reflect.Method> mlist = testMethods;
|
||||||
|
affirm( null!=mlist );
|
||||||
|
if( shuffle ){
|
||||||
|
mlist = new ArrayList<>( testMethods.subList(0, testMethods.size()) );
|
||||||
|
java.util.Collections.shuffle(mlist);
|
||||||
|
}
|
||||||
|
if( listRunTests ){
|
||||||
|
synchronized(this.getClass()){
|
||||||
|
if( !fromThread ){
|
||||||
|
out("Initial test"," list: ");
|
||||||
|
for(java.lang.reflect.Method m : testMethods){
|
||||||
|
out(m.getName()+" ");
|
||||||
|
}
|
||||||
|
outln();
|
||||||
|
outln("(That list excludes some which are hard-coded to run.)");
|
||||||
|
}
|
||||||
|
out("Running"," tests: ");
|
||||||
|
for(java.lang.reflect.Method m : mlist){
|
||||||
|
out(m.getName()+" ");
|
||||||
|
}
|
||||||
|
outln();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(java.lang.reflect.Method m : mlist){
|
||||||
|
nap();
|
||||||
|
try{
|
||||||
|
m.invoke(this);
|
||||||
|
}catch(java.lang.reflect.InvocationTargetException e){
|
||||||
|
outln("FAILURE: ",m.getName(),"(): ", e.getCause());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized( this.getClass() ){
|
||||||
|
++nTestRuns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
runTests(0!=this.tId);
|
||||||
|
}catch(Exception e){
|
||||||
|
synchronized( listErrors ){
|
||||||
|
listErrors.add(e);
|
||||||
|
}
|
||||||
|
}finally{
|
||||||
|
affirm( sqlite3_java_uncache_thread() );
|
||||||
|
affirm( !sqlite3_java_uncache_thread() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Runs the basic sqlite3 JNI binding sanity-check suite.
|
||||||
|
|
||||||
|
CLI flags:
|
||||||
|
|
||||||
|
-q|-quiet: disables most test output.
|
||||||
|
|
||||||
|
-t|-thread N: runs the tests in N threads
|
||||||
|
concurrently. Default=1.
|
||||||
|
|
||||||
|
-r|-repeat N: repeats the tests in a loop N times, each one
|
||||||
|
consisting of the -thread value's threads.
|
||||||
|
|
||||||
|
-shuffle: randomizes the order of most of the test functions.
|
||||||
|
|
||||||
|
-naps: sleep small random intervals between tests in order to add
|
||||||
|
some chaos for cross-thread contention.
|
||||||
|
|
||||||
|
-list-tests: outputs the list of tests being run, minus some
|
||||||
|
which are hard-coded. This is noisy in multi-threaded mode.
|
||||||
|
|
||||||
|
-fail: forces an exception to be thrown during the test run. Use
|
||||||
|
with -shuffle to make its appearance unpredictable.
|
||||||
|
|
||||||
|
-v: emit some developer-mode info at the end.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
Integer nThread = 1;
|
||||||
|
boolean doSomethingForDev = false;
|
||||||
|
Integer nRepeat = 1;
|
||||||
|
boolean forceFail = false;
|
||||||
|
boolean sqlLog = false;
|
||||||
|
boolean configLog = false;
|
||||||
|
boolean squelchTestOutput = false;
|
||||||
|
for( int i = 0; i < args.length; ){
|
||||||
|
String arg = args[i++];
|
||||||
|
if(arg.startsWith("-")){
|
||||||
|
arg = arg.replaceFirst("-+","");
|
||||||
|
if(arg.equals("v")){
|
||||||
|
doSomethingForDev = true;
|
||||||
|
//listBoundMethods();
|
||||||
|
}else if(arg.equals("t") || arg.equals("thread")){
|
||||||
|
nThread = Integer.parseInt(args[i++]);
|
||||||
|
}else if(arg.equals("r") || arg.equals("repeat")){
|
||||||
|
nRepeat = Integer.parseInt(args[i++]);
|
||||||
|
}else if(arg.equals("shuffle")){
|
||||||
|
shuffle = true;
|
||||||
|
}else if(arg.equals("list-tests")){
|
||||||
|
listRunTests = true;
|
||||||
|
}else if(arg.equals("fail")){
|
||||||
|
forceFail = true;
|
||||||
|
}else if(arg.equals("sqllog")){
|
||||||
|
sqlLog = true;
|
||||||
|
}else if(arg.equals("configlog")){
|
||||||
|
configLog = true;
|
||||||
|
}else if(arg.equals("naps")){
|
||||||
|
takeNaps = true;
|
||||||
|
}else if(arg.equals("q") || arg.equals("quiet")){
|
||||||
|
squelchTestOutput = true;
|
||||||
|
}else{
|
||||||
|
throw new IllegalArgumentException("Unhandled flag:"+arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( sqlLog ){
|
||||||
|
if( sqlite3_compileoption_used("ENABLE_SQLLOG") ){
|
||||||
|
final ConfigSqllogCallback log = new ConfigSqllogCallback() {
|
||||||
|
@Override public void call(sqlite3 db, String msg, int op){
|
||||||
|
switch(op){
|
||||||
|
case 0: outln("Opening db: ",db); break;
|
||||||
|
case 1: outln("SQL ",db,": ",msg); break;
|
||||||
|
case 2: outln("Closing db: ",db); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
int rc = sqlite3_config( log );
|
||||||
|
affirm( 0==rc );
|
||||||
|
rc = sqlite3_config( (ConfigSqllogCallback)null );
|
||||||
|
affirm( 0==rc );
|
||||||
|
rc = sqlite3_config( log );
|
||||||
|
affirm( 0==rc );
|
||||||
|
}else{
|
||||||
|
outln("WARNING: -sqllog is not active because library was built ",
|
||||||
|
"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;
|
||||||
|
outln("If you just saw warning messages regarding CallStaticObjectMethod, ",
|
||||||
|
"you are very likely seeing the side effects of a known openjdk8 ",
|
||||||
|
"bug. It is unsightly but does not affect the library.");
|
||||||
|
|
||||||
|
{
|
||||||
|
// Build list of tests to run from the methods named test*().
|
||||||
|
testMethods = new ArrayList<>();
|
||||||
|
int nSkipped = 0;
|
||||||
|
for(final java.lang.reflect.Method m : Tester2.class.getDeclaredMethods()){
|
||||||
|
final String name = m.getName();
|
||||||
|
if( name.equals("testFail") ){
|
||||||
|
if( forceFail ){
|
||||||
|
testMethods.add(m);
|
||||||
|
}
|
||||||
|
}else if( !m.isAnnotationPresent( ManualTest.class ) ){
|
||||||
|
if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){
|
||||||
|
if( 0==nSkipped++ ){
|
||||||
|
out("Skipping tests in multi-thread mode:");
|
||||||
|
}
|
||||||
|
out(" "+name+"()");
|
||||||
|
}else if( name.startsWith("test") ){
|
||||||
|
testMethods.add(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( nSkipped>0 ) out("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
final long timeStart = System.currentTimeMillis();
|
||||||
|
int nLoop = 0;
|
||||||
|
switch( sqlite3_threadsafe() ){ /* Sanity checking */
|
||||||
|
case 0:
|
||||||
|
affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ),
|
||||||
|
"Could not switch to single-thread mode." );
|
||||||
|
affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_MULTITHREAD ),
|
||||||
|
"Could switch to multithread mode." );
|
||||||
|
affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_SERIALIZED ),
|
||||||
|
"Could not switch to serialized threading mode." );
|
||||||
|
outln("This is a single-threaded build. Not using threads.");
|
||||||
|
nThread = 1;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
affirm( 0==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ),
|
||||||
|
"Could not switch to single-thread mode." );
|
||||||
|
affirm( 0==sqlite3_config( SQLITE_CONFIG_MULTITHREAD ),
|
||||||
|
"Could not switch to multithread mode." );
|
||||||
|
affirm( 0==sqlite3_config( SQLITE_CONFIG_SERIALIZED ),
|
||||||
|
"Could not switch to serialized threading mode." );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
affirm( false, "Unhandled SQLITE_THREADSAFE value." );
|
||||||
|
}
|
||||||
|
outln("libversion_number: ",
|
||||||
|
sqlite3_libversion_number(),"\n",
|
||||||
|
sqlite3_libversion(),"\n",SQLITE_SOURCE_ID,"\n",
|
||||||
|
"SQLITE_THREADSAFE=",sqlite3_threadsafe());
|
||||||
|
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.");
|
||||||
|
for( int n = 0; n < nRepeat; ++n ){
|
||||||
|
++nLoop;
|
||||||
|
if( showLoopCount ) out((1==nLoop ? "" : " ")+nLoop);
|
||||||
|
if( nThread<=1 ){
|
||||||
|
new Tester2(0).runTests(false);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Tester2.mtMode = true;
|
||||||
|
final ExecutorService ex = Executors.newFixedThreadPool( nThread );
|
||||||
|
for( int i = 0; i < nThread; ++i ){
|
||||||
|
ex.submit( new Tester2(i), i );
|
||||||
|
}
|
||||||
|
ex.shutdown();
|
||||||
|
try{
|
||||||
|
ex.awaitTermination(nThread*200, java.util.concurrent.TimeUnit.MILLISECONDS);
|
||||||
|
ex.shutdownNow();
|
||||||
|
}catch (InterruptedException ie){
|
||||||
|
ex.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
if( !listErrors.isEmpty() ){
|
||||||
|
quietMode = false;
|
||||||
|
outln("TEST ERRORS:");
|
||||||
|
Exception err = null;
|
||||||
|
for( Exception e : listErrors ){
|
||||||
|
e.printStackTrace();
|
||||||
|
if( null==err ) err = e;
|
||||||
|
}
|
||||||
|
if( null!=err ) throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( showLoopCount ) outln();
|
||||||
|
quietMode = false;
|
||||||
|
|
||||||
|
final long timeEnd = System.currentTimeMillis();
|
||||||
|
outln("Tests done. Metrics across ",nTestRuns," total iteration(s):");
|
||||||
|
outln("\tAssertions checked: ",affirmCount);
|
||||||
|
outln("\tDatabases opened: ",metrics.dbOpen);
|
||||||
|
if( doSomethingForDev ){
|
||||||
|
sqlite3_jni_internal_details();
|
||||||
|
}
|
||||||
|
affirm( 0==sqlite3_release_memory(1) );
|
||||||
|
sqlite3_shutdown();
|
||||||
|
int nMethods = 0;
|
||||||
|
int nNatives = 0;
|
||||||
|
int nCanonical = 0;
|
||||||
|
final java.lang.reflect.Method[] declaredMethods =
|
||||||
|
CApi.class.getDeclaredMethods();
|
||||||
|
for(java.lang.reflect.Method m : declaredMethods){
|
||||||
|
final int mod = m.getModifiers();
|
||||||
|
if( 0!=(mod & java.lang.reflect.Modifier.STATIC) ){
|
||||||
|
final String name = m.getName();
|
||||||
|
if(name.startsWith("sqlite3_")){
|
||||||
|
++nMethods;
|
||||||
|
if( 0!=(mod & java.lang.reflect.Modifier.NATIVE) ){
|
||||||
|
++nNatives;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outln("\tCApi.sqlite3_*() methods: "+
|
||||||
|
nMethods+" total, with "+
|
||||||
|
nNatives+" native, "+
|
||||||
|
(nMethods - nNatives)+" Java"
|
||||||
|
);
|
||||||
|
outln("\tTotal test time = "
|
||||||
|
+(timeEnd - timeStart)+"ms");
|
||||||
|
}
|
||||||
|
}
|
@@ -12,7 +12,7 @@
|
|||||||
** 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;
|
||||||
import static org.sqlite.jni.SQLite3Jni.*;
|
import static org.sqlite.jni.CApi.*;
|
||||||
import static org.sqlite.jni.Tester1.*;
|
import static org.sqlite.jni.Tester1.*;
|
||||||
import org.sqlite.jni.*;
|
import org.sqlite.jni.*;
|
||||||
import org.sqlite.jni.fts5.*;
|
import org.sqlite.jni.fts5.*;
|
||||||
|
@@ -15,7 +15,7 @@ package org.sqlite.jni;
|
|||||||
import org.sqlite.jni.annotation.Nullable;
|
import org.sqlite.jni.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_trace_v2}.
|
Callback for use with {@link CApi#sqlite3_trace_v2}.
|
||||||
*/
|
*/
|
||||||
public interface TraceV2Callback extends CallbackProxy {
|
public interface TraceV2Callback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
package org.sqlite.jni;
|
package org.sqlite.jni;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Callback for use with {@link SQLite3Jni#sqlite3_update_hook}.
|
Callback for use with {@link CApi#sqlite3_update_hook}.
|
||||||
*/
|
*/
|
||||||
public interface UpdateHookCallback extends CallbackProxy {
|
public interface UpdateHookCallback extends CallbackProxy {
|
||||||
/**
|
/**
|
||||||
|
@@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
** 2023-09-27
|
|
||||||
**
|
|
||||||
** 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 houses the Canonical annotaion for the sqlite3 C API.
|
|
||||||
*/
|
|
||||||
package org.sqlite.jni.annotation;
|
|
||||||
|
|
||||||
/**
|
|
||||||
This annotation is for marking functions as "canonical", meaning
|
|
||||||
that they map directly to a function in the core sqlite3 C API. The
|
|
||||||
intent is to distinguish them from functions added specifically to
|
|
||||||
the Java API.
|
|
||||||
|
|
||||||
<p>Canonical functions, unless specifically documented, have the
|
|
||||||
same semantics as their counterparts in <a
|
|
||||||
href="https://sqlite.org/c3ref/intro.html">the C API
|
|
||||||
documentation</a>, despite their signatures perhaps differing
|
|
||||||
slightly. Canonical forms may be native or implemented in Java.
|
|
||||||
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
|
|
||||||
and exposed to Java via public overloads.
|
|
||||||
|
|
||||||
<p>The comment property can be used to add a comment.
|
|
||||||
*/
|
|
||||||
@java.lang.annotation.Documented
|
|
||||||
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
|
|
||||||
@java.lang.annotation.Target(java.lang.annotation.ElementType.METHOD)
|
|
||||||
public @interface Canonical{
|
|
||||||
/**
|
|
||||||
Brief comments about the binding, e.g. noting any major
|
|
||||||
semantic differences.
|
|
||||||
*/
|
|
||||||
String comment() default "";
|
|
||||||
}
|
|
@@ -33,67 +33,51 @@ 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
|
||||||
@@ -102,14 +86,11 @@ public final class Fts5ExtensionApi extends NativePointerHolder<Fts5ExtensionApi
|
|||||||
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. */
|
||||||
|
|
||||||
@Canonical
|
|
||||||
public native int xSetAuxdata(@NotNull Fts5Context cx, @Nullable Object pAux);
|
public native int xSetAuxdata(@NotNull Fts5Context cx, @Nullable Object pAux);
|
||||||
|
|
||||||
@Canonical
|
|
||||||
public native int xTokenize(@NotNull Fts5Context cx, @NotNull byte[] pText,
|
public native int xTokenize(@NotNull Fts5Context cx, @NotNull byte[] pText,
|
||||||
@NotNull XTokenizeCallback callback);
|
@NotNull 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().
|
||||||
|
@@ -33,7 +33,6 @@ 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,
|
public synchronized native int xCreateFunction(@NotNull String name,
|
||||||
@Nullable Object userData,
|
@Nullable Object userData,
|
||||||
@NotNull fts5_extension_function xFunction);
|
@NotNull fts5_extension_function xFunction);
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
This package houses a JNI binding to the SQLite3 C API.
|
This package houses a JNI binding to the SQLite3 C API.
|
||||||
|
|
||||||
<p>The primary interfaces are in {@link
|
<p>The primary interfaces are in {@link
|
||||||
org.sqlite.jni.SQLite3Jni}.</p>
|
org.sqlite.jni.CApi}.</p>
|
||||||
|
|
||||||
<h1>API Goals and Requirements</h1>
|
<h1>API Goals and Requirements</h1>
|
||||||
|
|
||||||
|
@@ -30,19 +30,14 @@ public final class sqlite3 extends NativePointerHolder<sqlite3>
|
|||||||
if( 0==ptr ){
|
if( 0==ptr ){
|
||||||
return sqlite3.class.getSimpleName()+"@null";
|
return sqlite3.class.getSimpleName()+"@null";
|
||||||
}
|
}
|
||||||
final String fn = SQLite3Jni.sqlite3_db_filename(this, "main");
|
final String fn = CApi.sqlite3_db_filename(this, "main");
|
||||||
return sqlite3.class.getSimpleName()
|
return sqlite3.class.getSimpleName()
|
||||||
+"@"+String.format("0x%08x",ptr)
|
+"@"+String.format("0x%08x",ptr)
|
||||||
+"["+((null == fn) ? "<unnamed>" : fn)+"]"
|
+"["+((null == fn) ? "<unnamed>" : fn)+"]"
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override protected void finalize(){
|
|
||||||
//System.out.println(this+".finalize()");
|
|
||||||
SQLite3Jni.sqlite3_close_v2(this.clearNativePointer());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void close(){
|
@Override public void close(){
|
||||||
SQLite3Jni.sqlite3_close_v2(this.clearNativePointer());
|
CApi.sqlite3_close_v2(this.clearNativePointer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ public final class sqlite3_backup extends NativePointerHolder<sqlite3_backup>
|
|||||||
private sqlite3_backup(){}
|
private sqlite3_backup(){}
|
||||||
|
|
||||||
@Override public void close(){
|
@Override public void close(){
|
||||||
SQLite3Jni.sqlite3_backup_finish(this);
|
CApi.sqlite3_backup_finish(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -25,7 +25,7 @@ public final class sqlite3_blob extends NativePointerHolder<sqlite3_blob>
|
|||||||
private sqlite3_blob(){}
|
private sqlite3_blob(){}
|
||||||
|
|
||||||
@Override public void close(){
|
@Override public void close(){
|
||||||
SQLite3Jni.sqlite3_blob_close(this.clearNativePointer());
|
CApi.sqlite3_blob_close(this.clearNativePointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -71,7 +71,7 @@ public final class sqlite3_context extends NativePointerHolder<sqlite3_context>
|
|||||||
*/
|
*/
|
||||||
public synchronized Long getAggregateContext(boolean initIfNeeded){
|
public synchronized Long getAggregateContext(boolean initIfNeeded){
|
||||||
if( aggregateContext==null ){
|
if( aggregateContext==null ){
|
||||||
aggregateContext = SQLite3Jni.sqlite3_aggregate_context(this, initIfNeeded);
|
aggregateContext = CApi.sqlite3_aggregate_context(this, initIfNeeded);
|
||||||
if( !initIfNeeded && null==aggregateContext ) aggregateContext = 0L;
|
if( !initIfNeeded && null==aggregateContext ) aggregateContext = 0L;
|
||||||
}
|
}
|
||||||
return (null==aggregateContext || 0!=aggregateContext) ? aggregateContext : null;
|
return (null==aggregateContext || 0!=aggregateContext) ? aggregateContext : null;
|
||||||
|
@@ -24,12 +24,7 @@ public final class sqlite3_stmt extends NativePointerHolder<sqlite3_stmt>
|
|||||||
// Only invoked from JNI.
|
// Only invoked from JNI.
|
||||||
private sqlite3_stmt(){}
|
private sqlite3_stmt(){}
|
||||||
|
|
||||||
//For as-yet-unknown reasons, this triggers a JVM crash.
|
|
||||||
//@Override protected void finalize(){
|
|
||||||
// SQLite3Jni.sqlite3_finalize(this.clearNativePointer());
|
|
||||||
//}
|
|
||||||
|
|
||||||
@Override public void close(){
|
@Override public void close(){
|
||||||
SQLite3Jni.sqlite3_finalize(this.clearNativePointer());
|
CApi.sqlite3_finalize(this.clearNativePointer());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -135,8 +135,8 @@ do_test 2.2.2 {
|
|||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
CREATE TABLE t2(a, b PRIMARY KEY, c, d);
|
CREATE TABLE t2(a, b PRIMARY KEY, c, d);
|
||||||
}
|
}
|
||||||
list [catch { S changeset } msg] $msg
|
catch { S changeset }
|
||||||
} {1 SQLITE_SCHEMA}
|
} {0}
|
||||||
do_test 2.2.3 {
|
do_test 2.2.3 {
|
||||||
S delete
|
S delete
|
||||||
sqlite3session S db main
|
sqlite3session S db main
|
||||||
@@ -167,8 +167,8 @@ do_test 2.2.4 {
|
|||||||
CREATE TABLE t2(a, b PRIMARY KEY, c, d);
|
CREATE TABLE t2(a, b PRIMARY KEY, c, d);
|
||||||
INSERT INTO t2 VALUES(4, 5, 6, 7);
|
INSERT INTO t2 VALUES(4, 5, 6, 7);
|
||||||
}
|
}
|
||||||
list [catch { S changeset } msg] $msg
|
catch { S changeset }
|
||||||
} {1 SQLITE_SCHEMA}
|
} {0}
|
||||||
|
|
||||||
do_test 2.3 {
|
do_test 2.3 {
|
||||||
S delete
|
S delete
|
||||||
|
237
ext/session/sessionalter.test
Normal file
237
ext/session/sessionalter.test
Normal file
@@ -0,0 +1,237 @@
|
|||||||
|
# 2023 October 02
|
||||||
|
#
|
||||||
|
# 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 implements that the sessions module interacts well with
|
||||||
|
# the ALTER TABLE ADD COLUMN command.
|
||||||
|
#
|
||||||
|
|
||||||
|
if {![info exists testdir]} {
|
||||||
|
set testdir [file join [file dirname [info script]] .. .. test]
|
||||||
|
}
|
||||||
|
source [file join [file dirname [info script]] session_common.tcl]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
|
||||||
|
ifcapable !session {finish_test; return}
|
||||||
|
set testprefix sessionalter
|
||||||
|
|
||||||
|
|
||||||
|
forcedelete test.db2
|
||||||
|
sqlite3 db2 test.db2
|
||||||
|
|
||||||
|
do_execsql_test 1.0 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test -db db2 1.1 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c DEFAULT 1234);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_then_apply_sql {
|
||||||
|
INSERT INTO t1 VALUES(1, 'one');
|
||||||
|
INSERT INTO t1 VALUES(2, 'two');
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test -db db2 1.2 {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} {
|
||||||
|
1 one 1234
|
||||||
|
2 two 1234
|
||||||
|
}
|
||||||
|
|
||||||
|
do_then_apply_sql {
|
||||||
|
UPDATE t1 SET b='four' WHERE a=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test -db db2 1.3 {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} {
|
||||||
|
1 one 1234
|
||||||
|
2 four 1234
|
||||||
|
}
|
||||||
|
|
||||||
|
do_then_apply_sql {
|
||||||
|
DELETE FROM t1 WHERE a=1;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_execsql_test -db db2 1.4 {
|
||||||
|
SELECT * FROM t1
|
||||||
|
} {
|
||||||
|
2 four 1234
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------------
|
||||||
|
reset_db
|
||||||
|
|
||||||
|
do_execsql_test 2.0 {
|
||||||
|
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
do_test 2.1 {
|
||||||
|
sqlite3session S db main
|
||||||
|
S attach t1
|
||||||
|
set {} {}
|
||||||
|
} {}
|
||||||
|
do_execsql_test 2.2 {
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
ALTER TABLE t1 ADD COLUMN c DEFAULT 'abcd';
|
||||||
|
INSERT INTO t1 VALUES(2, 3, 4);
|
||||||
|
}
|
||||||
|
do_changeset_test 2.3 S {
|
||||||
|
{INSERT t1 0 X.. {} {i 1 i 2 t abcd}}
|
||||||
|
{INSERT t1 0 X.. {} {i 2 i 3 i 4}}
|
||||||
|
}
|
||||||
|
|
||||||
|
do_iterator_test 2.4 {} {
|
||||||
|
DELETE FROM t1 WHERE a=2;
|
||||||
|
ALTER TABLE t1 ADD COLUMN d DEFAULT 'abcd';
|
||||||
|
ALTER TABLE t1 ADD COLUMN e DEFAULT 5;
|
||||||
|
ALTER TABLE t1 ADD COLUMN f DEFAULT 7.2;
|
||||||
|
-- INSERT INTO t1 VALUES(9, 9, 9, 9);
|
||||||
|
} {
|
||||||
|
{DELETE t1 0 X..... {i 2 i 3 i 4 t abcd i 5 f 7.2} {}}
|
||||||
|
}
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
# Tests of the sqlite3changegroup_xxx() APIs.
|
||||||
|
#
|
||||||
|
reset_db
|
||||||
|
do_execsql_test 3.0 {
|
||||||
|
CREATE TABLE t1(x INTEGER PRIMARY KEY, y);
|
||||||
|
CREATE TABLE t2(x PRIMARY KEY, y);
|
||||||
|
CREATE TABLE t3(x, y);
|
||||||
|
CREATE TABLE t4(y PRIMARY KEY, x) WITHOUT ROWID;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES(1, 2), (3, 4), (5, 6);
|
||||||
|
INSERT INTO t2 VALUES('one', 'two'), ('three', 'four'), ('five', 'six');
|
||||||
|
INSERT INTO t3 VALUES(1, 2), (3, 4), (5, 6);
|
||||||
|
|
||||||
|
INSERT INTO t4(x, y) VALUES(1, 2), (3, 4), (5, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
db_save_and_close
|
||||||
|
foreach {tn sql1 at sql2} {
|
||||||
|
1 {
|
||||||
|
INSERT INTO t1(x, y) VALUES(7, 8);
|
||||||
|
} {
|
||||||
|
ALTER TABLE t1 ADD COLUMN z DEFAULT 10;
|
||||||
|
} {
|
||||||
|
UPDATE t1 SET y=11 WHERE x=7;
|
||||||
|
}
|
||||||
|
|
||||||
|
2 {
|
||||||
|
UPDATE t2 SET y='two.two' WHERE x='one';
|
||||||
|
DELETE FROM t2 WHERE x='five';
|
||||||
|
INSERT INTO t2(x, y) VALUES('seven', 'eight');
|
||||||
|
} {
|
||||||
|
ALTER TABLE t2 ADD COLUMN z;
|
||||||
|
ALTER TABLE t2 ADD COLUMN zz;
|
||||||
|
} {
|
||||||
|
}
|
||||||
|
|
||||||
|
3 {
|
||||||
|
DELETE FROM t2 WHERE x='five';
|
||||||
|
} {
|
||||||
|
ALTER TABLE t2 ADD COLUMN z DEFAULT 'xyz';
|
||||||
|
} {
|
||||||
|
}
|
||||||
|
|
||||||
|
4 {
|
||||||
|
UPDATE t2 SET y='two.two' WHERE x='three';
|
||||||
|
} {
|
||||||
|
ALTER TABLE t2 ADD COLUMN z;
|
||||||
|
} {
|
||||||
|
UPDATE t2 SET z='abc' WHERE x='one';
|
||||||
|
}
|
||||||
|
|
||||||
|
5* {
|
||||||
|
UPDATE t2 SET y='two.two' WHERE x='three';
|
||||||
|
} {
|
||||||
|
ALTER TABLE t2 ADD COLUMN z DEFAULT 'defu1';
|
||||||
|
} {
|
||||||
|
}
|
||||||
|
|
||||||
|
6* {
|
||||||
|
INSERT INTO t2(x, y) VALUES('nine', 'ten');
|
||||||
|
} {
|
||||||
|
ALTER TABLE t2 ADD COLUMN z;
|
||||||
|
ALTER TABLE t2 ADD COLUMN a DEFAULT 'eelve';
|
||||||
|
ALTER TABLE t2 ADD COLUMN b DEFAULT x'1234abcd';
|
||||||
|
ALTER TABLE t2 ADD COLUMN c DEFAULT 4.2;
|
||||||
|
ALTER TABLE t2 ADD COLUMN d DEFAULT NULL;
|
||||||
|
} {
|
||||||
|
}
|
||||||
|
|
||||||
|
7 {
|
||||||
|
INSERT INTO t3(x, y) VALUES(7, 8);
|
||||||
|
UPDATE t3 SET y='fourteen' WHERE x=1;
|
||||||
|
DELETE FROM t3 WHERE x=3;
|
||||||
|
} {
|
||||||
|
ALTER TABLE t3 ADD COLUMN c;
|
||||||
|
} {
|
||||||
|
INSERT INTO t3(x, y, c) VALUES(9, 10, 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
8 {
|
||||||
|
INSERT INTO t4(x, y) VALUES(7, 8);
|
||||||
|
UPDATE t4 SET y='fourteen' WHERE x=1;
|
||||||
|
DELETE FROM t4 WHERE x=3;
|
||||||
|
} {
|
||||||
|
ALTER TABLE t4 ADD COLUMN c;
|
||||||
|
} {
|
||||||
|
INSERT INTO t4(x, y, c) VALUES(9, 10, 11);
|
||||||
|
}
|
||||||
|
} {
|
||||||
|
foreach {tn2 cmd} {
|
||||||
|
1 changeset_from_sql
|
||||||
|
2 patchset_from_sql
|
||||||
|
} {
|
||||||
|
db_restore_and_reopen
|
||||||
|
|
||||||
|
set C1 [$cmd $sql1]
|
||||||
|
execsql $at
|
||||||
|
set C2 [$cmd $sql2]
|
||||||
|
|
||||||
|
sqlite3changegroup grp
|
||||||
|
grp schema db main
|
||||||
|
grp add $C1
|
||||||
|
grp add $C2
|
||||||
|
set T1 [grp output]
|
||||||
|
grp delete
|
||||||
|
|
||||||
|
db_restore_and_reopen
|
||||||
|
execsql $at
|
||||||
|
set T2 [$cmd "$sql1 ; $sql2"]
|
||||||
|
|
||||||
|
if {[string range $tn end end]!="*"} {
|
||||||
|
do_test 3.1.$tn.$tn2.1 { changeset_to_list $T1 } [changeset_to_list $T2]
|
||||||
|
set testname "$tn.$tn2"
|
||||||
|
} else {
|
||||||
|
set testname "[string range $tn 0 end-1].$tn2"
|
||||||
|
}
|
||||||
|
|
||||||
|
db_restore_and_reopen
|
||||||
|
proc xConflict {args} { return "REPLACE" }
|
||||||
|
sqlite3changeset_apply_v2 db $T1 xConflict
|
||||||
|
set S1 [scksum db main]
|
||||||
|
|
||||||
|
db_restore_and_reopen
|
||||||
|
sqlite3changeset_apply_v2 db $T2 xConflict
|
||||||
|
set S2 [scksum db main]
|
||||||
|
|
||||||
|
# if { $tn==7 } { puts [changeset_to_list $T1] }
|
||||||
|
|
||||||
|
do_test 3.1.$tn.2 { set S1 } $S2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
finish_test
|
||||||
|
|
59
ext/session/sessionfault3.test
Normal file
59
ext/session/sessionfault3.test
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# 2016 October 6
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
#***********************************************************************
|
||||||
|
#
|
||||||
|
# The focus of this file is testing the session module.
|
||||||
|
#
|
||||||
|
|
||||||
|
if {![info exists testdir]} {
|
||||||
|
set testdir [file join [file dirname [info script]] .. .. test]
|
||||||
|
}
|
||||||
|
source [file join [file dirname [info script]] session_common.tcl]
|
||||||
|
source $testdir/tester.tcl
|
||||||
|
ifcapable !session {finish_test; return}
|
||||||
|
set testprefix sessionfault3
|
||||||
|
|
||||||
|
do_execsql_test 1.0 {
|
||||||
|
CREATE TABLE t1(a, b, PRIMARY KEY(a));
|
||||||
|
INSERT INTO t1 VALUES(1, 2);
|
||||||
|
INSERT INTO t1 VALUES(3, 4);
|
||||||
|
INSERT INTO t1 VALUES('five', 'six');
|
||||||
|
}
|
||||||
|
|
||||||
|
set C1 [changeset_from_sql {
|
||||||
|
INSERT INTO t1 VALUES('seven', 'eight');
|
||||||
|
UPDATE t1 SET b=6 WHERE a='five';
|
||||||
|
DELETE FROM t1 WHERE a=1;
|
||||||
|
}]
|
||||||
|
|
||||||
|
do_execsql_test 1.1 {
|
||||||
|
ALTER TABLE t1 ADD COLUMN d DEFAULT 123;
|
||||||
|
ALTER TABLE t1 ADD COLUMN e DEFAULT 'string';
|
||||||
|
}
|
||||||
|
|
||||||
|
set C2 [changeset_from_sql {
|
||||||
|
UPDATE t1 SET e='new value' WHERE a='seven';
|
||||||
|
INSERT INTO t1 VALUES(0, 0, 0, 0);
|
||||||
|
}]
|
||||||
|
|
||||||
|
do_faultsim_test 1 -faults oom* -prep {
|
||||||
|
sqlite3changegroup G
|
||||||
|
} -body {
|
||||||
|
G schema db main
|
||||||
|
G add $::C1
|
||||||
|
G add $::C2
|
||||||
|
G output
|
||||||
|
set {} {}
|
||||||
|
} -test {
|
||||||
|
catch { G delete }
|
||||||
|
faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_test
|
File diff suppressed because it is too large
Load Diff
@@ -884,6 +884,18 @@ int sqlite3changeset_concat(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Upgrade the Schema of a Changeset/Patchset
|
||||||
|
*/
|
||||||
|
int sqlite3changeset_upgrade(
|
||||||
|
sqlite3 *db,
|
||||||
|
const char *zDb,
|
||||||
|
int nIn, const void *pIn, /* Input changeset */
|
||||||
|
int *pnOut, void **ppOut /* OUT: Inverse of input */
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Changegroup Handle
|
** CAPI3REF: Changegroup Handle
|
||||||
**
|
**
|
||||||
@@ -930,6 +942,38 @@ typedef struct sqlite3_changegroup sqlite3_changegroup;
|
|||||||
*/
|
*/
|
||||||
int sqlite3changegroup_new(sqlite3_changegroup **pp);
|
int sqlite3changegroup_new(sqlite3_changegroup **pp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: Add a Schema to a Changegroup
|
||||||
|
** METHOD: sqlite3_changegroup_schema
|
||||||
|
**
|
||||||
|
** This method may be used to optionally enforce the rule that the changesets
|
||||||
|
** added to the changegroup handle must match the schema of database zDb
|
||||||
|
** ("main", "temp", or the name of an attached database). If
|
||||||
|
** sqlite3changegroup_add() is called to add a changeset that is not compatible
|
||||||
|
** with the configured schema, SQLITE_SCHEMA is returned and the changegroup
|
||||||
|
** object is left in an undefined state.
|
||||||
|
**
|
||||||
|
** A changeset schema is considered compatible with the database schema in
|
||||||
|
** the same way as for sqlite3changeset_apply(). Specifically, for each
|
||||||
|
** table in the changeset, there exists a database table with:
|
||||||
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> The name identified by the changeset, and
|
||||||
|
** <li> at least as many columns as recorded in the changeset, and
|
||||||
|
** <li> the primary key columns in the same position as recorded in
|
||||||
|
** the changeset.
|
||||||
|
** </ul>
|
||||||
|
**
|
||||||
|
** The output of the changegroup object always has the same schema as the
|
||||||
|
** database nominated using this function. In cases where changesets passed
|
||||||
|
** to sqlite3changegroup_add() have fewer columns than the corresponding table
|
||||||
|
** in the database schema, these are filled in using the default column
|
||||||
|
** values from the database schema. This makes it possible to combined
|
||||||
|
** changesets that have different numbers of columns for a single table
|
||||||
|
** within a changegroup, provided that they are otherwise compatible.
|
||||||
|
*/
|
||||||
|
int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Add A Changeset To A Changegroup
|
** CAPI3REF: Add A Changeset To A Changegroup
|
||||||
** METHOD: sqlite3_changegroup
|
** METHOD: sqlite3_changegroup
|
||||||
@@ -998,13 +1042,18 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp);
|
|||||||
** If the new changeset contains changes to a table that is already present
|
** If the new changeset contains changes to a table that is already present
|
||||||
** in the changegroup, then the number of columns and the position of the
|
** in the changegroup, then the number of columns and the position of the
|
||||||
** primary key columns for the table must be consistent. If this is not the
|
** primary key columns for the table must be consistent. If this is not the
|
||||||
** case, this function fails with SQLITE_SCHEMA. If the input changeset
|
** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup
|
||||||
** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is
|
** object has been configured with a database schema using the
|
||||||
** returned. Or, if an out-of-memory condition occurs during processing, this
|
** sqlite3changegroup_schema() API, then it is possible to combine changesets
|
||||||
** function returns SQLITE_NOMEM. In all cases, if an error occurs the state
|
** with different numbers of columns for a single table, provided that
|
||||||
** of the final contents of the changegroup is undefined.
|
** they are otherwise compatible.
|
||||||
**
|
**
|
||||||
** If no error occurs, SQLITE_OK is returned.
|
** If the input changeset appears to be corrupt and the corruption is
|
||||||
|
** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition
|
||||||
|
** occurs during processing, this function returns SQLITE_NOMEM.
|
||||||
|
**
|
||||||
|
** In all cases, if an error occurs the state of the final contents of the
|
||||||
|
** changegroup is undefined. If no error occurs, SQLITE_OK is returned.
|
||||||
*/
|
*/
|
||||||
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
|
int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
|
||||||
|
|
||||||
|
@@ -1452,12 +1452,144 @@ static int SQLITE_TCLAPI test_sqlite3session_config(
|
|||||||
return TCL_OK;
|
return TCL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct TestChangegroup TestChangegroup;
|
||||||
|
struct TestChangegroup {
|
||||||
|
sqlite3_changegroup *pGrp;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Destructor for Tcl changegroup command object.
|
||||||
|
*/
|
||||||
|
static void test_changegroup_del(void *clientData){
|
||||||
|
TestChangegroup *pGrp = (TestChangegroup*)clientData;
|
||||||
|
sqlite3changegroup_delete(pGrp->pGrp);
|
||||||
|
ckfree(pGrp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Tclcmd: $changegroup schema DB DBNAME
|
||||||
|
** Tclcmd: $changegroup add CHANGESET
|
||||||
|
** Tclcmd: $changegroup output
|
||||||
|
** Tclcmd: $changegroup delete
|
||||||
|
*/
|
||||||
|
static int SQLITE_TCLAPI test_changegroup_cmd(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
TestChangegroup *p = (TestChangegroup*)clientData;
|
||||||
|
static struct ChangegroupCmd {
|
||||||
|
const char *zSub;
|
||||||
|
int nArg;
|
||||||
|
const char *zMsg;
|
||||||
|
int iSub;
|
||||||
|
} aSub[] = {
|
||||||
|
{ "schema", 2, "DB DBNAME", }, /* 0 */
|
||||||
|
{ "add", 1, "CHANGESET", }, /* 1 */
|
||||||
|
{ "output", 0, "", }, /* 2 */
|
||||||
|
{ "delete", 0, "", }, /* 3 */
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
int rc = TCL_OK;
|
||||||
|
int iSub = 0;
|
||||||
|
|
||||||
|
if( objc<2 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
rc = Tcl_GetIndexFromObjStruct(interp,
|
||||||
|
objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
|
||||||
|
);
|
||||||
|
if( rc!=TCL_OK ) return rc;
|
||||||
|
if( objc!=2+aSub[iSub].nArg ){
|
||||||
|
Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg);
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( iSub ){
|
||||||
|
case 0: { /* schema */
|
||||||
|
sqlite3 *db = 0;
|
||||||
|
const char *zDb = Tcl_GetString(objv[3]);
|
||||||
|
if( dbHandleFromObj(interp, objv[2], &db) ){
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
rc = sqlite3changegroup_schema(p->pGrp, db, zDb);
|
||||||
|
if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
case 1: { /* add */
|
||||||
|
int nByte = 0;
|
||||||
|
const u8 *aByte = Tcl_GetByteArrayFromObj(objv[2], &nByte);
|
||||||
|
rc = sqlite3changegroup_add(p->pGrp, nByte, (void*)aByte);
|
||||||
|
if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
case 2: { /* output */
|
||||||
|
int nByte = 0;
|
||||||
|
u8 *aByte = 0;
|
||||||
|
rc = sqlite3changegroup_output(p->pGrp, &nByte, (void**)&aByte);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
rc = test_session_error(interp, rc, 0);
|
||||||
|
}else{
|
||||||
|
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aByte, nByte));
|
||||||
|
}
|
||||||
|
sqlite3_free(aByte);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
default: { /* delete */
|
||||||
|
assert( iSub==3 );
|
||||||
|
Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Tclcmd: sqlite3changegroup CMD
|
||||||
|
*/
|
||||||
|
static int SQLITE_TCLAPI test_sqlite3changegroup(
|
||||||
|
void * clientData,
|
||||||
|
Tcl_Interp *interp,
|
||||||
|
int objc,
|
||||||
|
Tcl_Obj *CONST objv[]
|
||||||
|
){
|
||||||
|
int rc; /* sqlite3changegroup_new() return code */
|
||||||
|
TestChangegroup *p; /* New wrapper object */
|
||||||
|
|
||||||
|
if( objc!=2 ){
|
||||||
|
Tcl_WrongNumArgs(interp, 1, objv, "CMD");
|
||||||
|
return TCL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = (TestChangegroup*)ckalloc(sizeof(TestChangegroup));
|
||||||
|
memset(p, 0, sizeof(TestChangegroup));
|
||||||
|
rc = sqlite3changegroup_new(&p->pGrp);
|
||||||
|
if( rc!=SQLITE_OK ){
|
||||||
|
ckfree((char*)p);
|
||||||
|
return test_session_error(interp, rc, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tcl_CreateObjCommand(
|
||||||
|
interp, Tcl_GetString(objv[1]), test_changegroup_cmd, (ClientData)p,
|
||||||
|
test_changegroup_del
|
||||||
|
);
|
||||||
|
Tcl_SetObjResult(interp, objv[1]);
|
||||||
|
return TCL_OK;
|
||||||
|
}
|
||||||
|
|
||||||
int TestSession_Init(Tcl_Interp *interp){
|
int TestSession_Init(Tcl_Interp *interp){
|
||||||
struct Cmd {
|
struct Cmd {
|
||||||
const char *zCmd;
|
const char *zCmd;
|
||||||
Tcl_ObjCmdProc *xProc;
|
Tcl_ObjCmdProc *xProc;
|
||||||
} aCmd[] = {
|
} aCmd[] = {
|
||||||
{ "sqlite3session", test_sqlite3session },
|
{ "sqlite3session", test_sqlite3session },
|
||||||
|
{ "sqlite3changegroup", test_sqlite3changegroup },
|
||||||
{ "sqlite3session_foreach", test_sqlite3session_foreach },
|
{ "sqlite3session_foreach", test_sqlite3session_foreach },
|
||||||
{ "sqlite3changeset_invert", test_sqlite3changeset_invert },
|
{ "sqlite3changeset_invert", test_sqlite3changeset_invert },
|
||||||
{ "sqlite3changeset_concat", test_sqlite3changeset_concat },
|
{ "sqlite3changeset_concat", test_sqlite3changeset_concat },
|
||||||
|
90
manifest
90
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Remove\ssome\sunnecessary\scode.\s\sReport\serrors\sfor\sinvalid\sJSONB\sinput\son\nan\sextract.
|
C Merge\sthe\slatest\strunk\sfixes\sand\senhancements\sinto\sthe\sjsonb\sbranch,\sand\nespecially\sthe\sJSON\scache\sspill\sUAF\sfix.
|
||||||
D 2023-10-07T23:35:07.967
|
D 2023-10-09T12:57:03.290
|
||||||
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,59 +235,61 @@ 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 7278812b41ced95fe67a9e5823aee027d641fd26fdfabe66c62b102a3a4e0631
|
F ext/jni/GNUmakefile 8c44e22bad18ecc266dd8c521f215e95dc3741d9e337c51b175029abaedcfb35
|
||||||
F ext/jni/README.md 9fceaeb17cecdc5d699dfc83c0cbc3a03fdb3b86bf676381894166c73375ee75
|
F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4
|
||||||
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
|
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
|
||||||
F ext/jni/src/c/sqlite3-jni.c 2c4948634fd7f6460b074b72328b9c885ec11333bbc98144f745e4d6203a7ac2
|
F ext/jni/src/c/sqlite3-jni.c fb8f178d27df828e3c797b4427a0a20545b44f5147ce38d09ce9b465be5a840b
|
||||||
F ext/jni/src/c/sqlite3-jni.h 74e3da791f748f02d0d684562126cf6bfdd2a85cbb6a5d1354b14fcd46e187bc
|
F ext/jni/src/c/sqlite3-jni.h be1fdff7ab3a2bb357197271c8ac5d2bf6ff59380c106dde3a13be88724bad22
|
||||||
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 e6135be32f12bf140bffa39be7fd1a45ad83b2661ed49c08dbde04c8485feb38
|
F ext/jni/src/org/sqlite/jni/AuthorizerCallback.java fde5f758ad170ca45ae00b12194c8ba8d8f3090bd64cc3e002dd9c5e7dff8568
|
||||||
F ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java 5e4a75611c026730289d776469d6122cb2699d6970af5f53fe85e74d49930476
|
F ext/jni/src/org/sqlite/jni/AutoExtensionCallback.java c0fbfd3779fc92982c7935325a7484dee43eeb80d716989ed31218f453addb94
|
||||||
F ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java d316373b12b3bf1a421f1f7eed08128fa8dd52bb98617ba28c161aaabd71d1ee
|
F ext/jni/src/org/sqlite/jni/BusyHandlerCallback.java 4cb7fc70efd55583fed6033c34a8719da42975ca97ef4781dda0b9f6cc8ec2e8
|
||||||
|
F ext/jni/src/org/sqlite/jni/CApi.java c1dde485a3a3f43c46c8d9c527f9ba5bf303fe0409b2c0de253fb7b6e1055f7e w ext/jni/src/org/sqlite/jni/SQLite3Jni.java
|
||||||
F ext/jni/src/org/sqlite/jni/CallbackProxy.java 064a8a00e4c63cc501c30504f93ca996d422c5f010067f969b2d0a10f0868153
|
F ext/jni/src/org/sqlite/jni/CallbackProxy.java 064a8a00e4c63cc501c30504f93ca996d422c5f010067f969b2d0a10f0868153
|
||||||
F ext/jni/src/org/sqlite/jni/CollationCallback.java df327348e1a34ee65210208d694d690e5ee0bfe901410122e07caf6c98b2b7c8
|
F ext/jni/src/org/sqlite/jni/CollationCallback.java 8cf57cb014a645ecc12609eed17308852a597bc5e83d82a4fdb90f7fadc25f9d
|
||||||
F ext/jni/src/org/sqlite/jni/CollationNeededCallback.java 07df5fa161a0b81154295258037f662e7c372735c2899c76e81cb3abd9fd3b39
|
F ext/jni/src/org/sqlite/jni/CollationNeededCallback.java 0c62245e000d5db52576c728cac20f6a31f31f5cf40ca4cbcd64b22964e82ae5
|
||||||
F ext/jni/src/org/sqlite/jni/CommitHookCallback.java 77cf8bb4f5548113e9792978f3f8a454614f420fa0ad73939421cbff4e7776f2
|
F ext/jni/src/org/sqlite/jni/CommitHookCallback.java d15bd87ca6159a48b281966cf7a6e67dd17e2fabf974a797c9e3a66a74f361e8
|
||||||
F ext/jni/src/org/sqlite/jni/ConfigLogCallback.java 636ed6b89ed03f15bc2a6f6f47bf7853b8328e5a8269e52e80630708efa703a6
|
F ext/jni/src/org/sqlite/jni/ConfigLogCallback.java 16bb391d8d4ae89cc43baa3cfa0c80c988003627b7ea872deb41156a76f7e867
|
||||||
F ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java e3656909eab7ed0f7e457c5b82df160ca22dd5e954c0a306ec1fca61b0d266b4
|
F ext/jni/src/org/sqlite/jni/ConfigSqllogCallback.java 6d6b64638123acb70ffefcd5d2345b1bea3d3b528727d1684cc20cc2357f03a0
|
||||||
F ext/jni/src/org/sqlite/jni/NativePointerHolder.java 3eb36b5e81993a847f5ec03d23ab219a92671f817547b6a85d312667faeedd8b
|
F ext/jni/src/org/sqlite/jni/NativePointerHolder.java 3eb36b5e81993a847f5ec03d23ab219a92671f817547b6a85d312667faeedd8b
|
||||||
F ext/jni/src/org/sqlite/jni/OutputPointer.java 2f57c05672ddc9b38e3f8eed11759896cf0bf01107ffd24d5182b99f6e7254b6
|
F ext/jni/src/org/sqlite/jni/OutputPointer.java 2f57c05672ddc9b38e3f8eed11759896cf0bf01107ffd24d5182b99f6e7254b6
|
||||||
F ext/jni/src/org/sqlite/jni/PrepareMultiCallback.java 878ed9cc8000def1a4e6d7113d52bba6fce0aa6733b4eb216d68dfbe096776ac
|
F ext/jni/src/org/sqlite/jni/PrepareMultiCallback.java 6f051951fecab41f2e842b1ac1d3c498706de9387c86f62564e2afbe03d026cb
|
||||||
F ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java eccaed8dc9c6289f07ef3fc109891c6be1e7cc6c88723d90174b68706fc21cda
|
F ext/jni/src/org/sqlite/jni/PreupdateHookCallback.java 242dc2afea13c45b4809d41b6a919e0a4003508713ceffe5f6545270138c6a7b
|
||||||
F ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java 7b9ff2218129ece98ba60c57eeedcd8447e9e3b6e5d0f5e5d3eb0f0c5037d48d
|
F ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java 247a47f49a1dd54fda28201c27796d2600a5c904f47fa21697a5377d49febe56
|
||||||
F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86
|
F ext/jni/src/org/sqlite/jni/ResultCode.java dc7400b8b18df10027525d8d0f04300b2c6afc617d4d980923f8b5bb14412f3a
|
||||||
F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java d12352c0e22840de484ffa9b11ed5058bb0daca2e9f218055d3c54c947a273c4
|
F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java ec6cd96bff5d3bc5af079cbf1469ae7fb34c50583a23581a58d6b2f8b55bafd3
|
||||||
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/SQLTester.java da42be06a2d644e0b915b40508934c1f32391e5308ab8767c1e2e65a281a198f
|
F ext/jni/src/org/sqlite/jni/SQLTester.java d246c67f93e2fa2603bd106dbb3246ea725c987dffd6e5d42214ae262f750c68
|
||||||
F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 9860c1cebd8a38041306f2ee7563f2898fcbdf77e4bfa393fba25b4924edcb5d
|
|
||||||
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/Sqlite.java 44b23a929e5d625b35c83fd49a80ada944bdd8b2bdece3ca7d400b33a2652fbd
|
||||||
|
F ext/jni/src/org/sqlite/jni/SqliteException.java f5d17a10202c0983fb074f66a0b48cf1e573b1da2eaeda679825e3edc1829706
|
||||||
F ext/jni/src/org/sqlite/jni/TableColumnMetadata.java 54511b4297fa28dcb3f49b24035e34ced10e3fd44fd0e458e784f4d6b0096dab
|
F ext/jni/src/org/sqlite/jni/TableColumnMetadata.java 54511b4297fa28dcb3f49b24035e34ced10e3fd44fd0e458e784f4d6b0096dab
|
||||||
F ext/jni/src/org/sqlite/jni/Tester1.java ced62ed417c3326f93d2e90b3bb64ac2db58ac42a7ad7a5965b24545434e3200
|
F ext/jni/src/org/sqlite/jni/Tester1.java f7b85fe24cf6c3e43bdf7e390617657e8137359f804d76921829c2a8c41b6df1
|
||||||
F ext/jni/src/org/sqlite/jni/TesterFts5.java 854c737bb5c9463ee92a8ee230013e924236dd4b74d4688dd62c17f38d5837db
|
F ext/jni/src/org/sqlite/jni/Tester2.java 75aa079e2baf8f73d95299da092e611656be0f6e12fe2fa051fdd984657857e2
|
||||||
F ext/jni/src/org/sqlite/jni/TraceV2Callback.java beb0b064c1a5f8bfe585a324ed39a4e33edbe379a3fc60f1401661620d3ca7c0
|
F ext/jni/src/org/sqlite/jni/TesterFts5.java d60fe9944a81156b3b5325dd1b0e8e92a1547468f39fd1266d06f7bb6a95fa70
|
||||||
F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java 8376f4a931f2d5612b295c003c9515ba933ee76d8f95610e89c339727376e36c
|
F ext/jni/src/org/sqlite/jni/TraceV2Callback.java f157edd9c72e7d2243c169061487cd7bb51a0d50f3ac976dbcbbacf748ab1fc2
|
||||||
|
F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java 959d4677a857c9079c6e96ddd10918b946d68359af6252b6f284379069ea3d27
|
||||||
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 44ea75a3c6c39513be9052eaa845b258a953f6af59e61002d715363fa52a7175
|
|
||||||
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java a99341e88154e70447596b1af6a27c586317df41a7e0f246fd41370cd7b723b2
|
F ext/jni/src/org/sqlite/jni/annotation/NotNull.java a99341e88154e70447596b1af6a27c586317df41a7e0f246fd41370cd7b723b2
|
||||||
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba
|
F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba
|
||||||
F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca
|
F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/Fts5.java e94681023785f1eff5399f0ddc82f46b035977d350f14838db659236ebdf6b41
|
F ext/jni/src/org/sqlite/jni/fts5/Fts5.java e94681023785f1eff5399f0ddc82f46b035977d350f14838db659236ebdf6b41
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 7058da97059b8e156c17561a47ecd7faa0fc3e2d8c2588b9a28dbff8d06202dd
|
F ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 7058da97059b8e156c17561a47ecd7faa0fc3e2d8c2588b9a28dbff8d06202dd
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java e2680721bd83129d0d650ba845b44d7634a9489a90a56c5ce3c54508bf470743
|
F ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java c8e06475a6172a7cd61b2bad9cfb18b6f059ffdd2935e62856f95785a14fe0e5
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 2a7f3d76a1206e6a43d4c4ed9609b294d5431cc7d8fb875d8419f76efa6e56dc
|
F ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 2a7f3d76a1206e6a43d4c4ed9609b294d5431cc7d8fb875d8419f76efa6e56dc
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java cc9a53846a168a215238af224c31cef0e8379780e36e8a5e743b00c08145cf19
|
F ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java cc9a53846a168a215238af224c31cef0e8379780e36e8a5e743b00c08145cf19
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java 1efd1220ea328a32f2d2a1b16c735864159e929480f71daad4de9d5944839167
|
F ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java 1efd1220ea328a32f2d2a1b16c735864159e929480f71daad4de9d5944839167
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java e2ad9bc06a9d307e0a6221c11645783898906455a92b1f7d5ec9b9ff1af1b8ea
|
F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java 90f09477331c371a8abe0a6504cfe094bc075b29a800be9d72a2c92a7bb49db1
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 1fe0f5692c1d67475d12b067f0469949073446f18c56eba5ee5da6ddd06db9b9
|
F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 1fe0f5692c1d67475d12b067f0469949073446f18c56eba5ee5da6ddd06db9b9
|
||||||
F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java ea993738b851038c16d98576abd0db3d6028a231f075a394fb8a78c7834d0f6c
|
F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java ea993738b851038c16d98576abd0db3d6028a231f075a394fb8a78c7834d0f6c
|
||||||
F ext/jni/src/org/sqlite/jni/package-info.java a3946db2504de747a1993c4f6e8ce604bec5a8e5a134b292c3b07527bc321a99
|
F ext/jni/src/org/sqlite/jni/package-info.java 7d465cbdf9050761db0db6d0c542afaaad7dc67f61510860592159c48bfc40e8
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3.java 5cd95c182a38b874ad973b3c16a70a69786fe82a6793abf147639803dec7ecac
|
F ext/jni/src/org/sqlite/jni/sqlite3.java 4fa76f9c618264ed17ab613570076002c0b78717261b263350cd92d6d6b01242
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_backup.java 12182124c4d4928d78db5a07ea285f1d7af04c7a148f0759a1972d5bfa87311e
|
F ext/jni/src/org/sqlite/jni/sqlite3_backup.java 42db8b2f9cd8e9e16217273890e5d4afbb102603d7130a2cb1651f1c69c1cfa4
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_blob.java fc631ad52feea6e3d1d62b0d0e769ac107c01bc0ddd20eb512aff07b428cda6d
|
F ext/jni/src/org/sqlite/jni/sqlite3_blob.java 7c341bca1856475fc3bf3697251e0cf1d737ddcb099c65d90afdc164aaddcc51
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_context.java 66ca95ce904044263a4aff684abe262d56f73e6b06bca6cf650761d79d7779ad
|
F ext/jni/src/org/sqlite/jni/sqlite3_context.java ba8da75eaaeb557c986af3fb4dbc69501cf2b083ca33497f2c0c70dbc0a53f2c
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java cf7f076d8b0f2a23faebbd64e12e8b3dd1977378ca828245d186f1b98458127d
|
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java fa0703004721c49d6d08a0c1e99439fadb8cebaebf42b81ee3f427d7f950d1eb
|
||||||
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
|
||||||
F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
|
F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
|
||||||
F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745
|
F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745
|
||||||
@@ -513,7 +515,7 @@ F ext/session/changesetfuzz.c 227076ab0ae4447d742c01ee88a564da6478bbf26b65108bf8
|
|||||||
F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a
|
F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a
|
||||||
F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e
|
F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e
|
||||||
F ext/session/session2.test ee83bb973b9ce17ccce4db931cdcdae65eb40bbb22089b2fe6aa4f6be3b9303f
|
F ext/session/session2.test ee83bb973b9ce17ccce4db931cdcdae65eb40bbb22089b2fe6aa4f6be3b9303f
|
||||||
F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479
|
F ext/session/session3.test 2cc1629cfb880243aec1a7251145e07b78411d851b39b2aa1390704550db8e6a
|
||||||
F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40
|
F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40
|
||||||
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
|
F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169
|
||||||
F ext/session/session6.test 35279f2ec45448cd2e24a61688219dc6cf7871757716063acf4a8b5455e1e926
|
F ext/session/session6.test 35279f2ec45448cd2e24a61688219dc6cf7871757716063acf4a8b5455e1e926
|
||||||
@@ -529,11 +531,13 @@ F ext/session/sessionG.test 3efe388282d641b65485b5462e67851002cd91a282dc95b685d0
|
|||||||
F ext/session/sessionH.test 71bbff6b1abb2c4ac62b84dee53273c37e0b21e5fde3aed80929403e091ef859
|
F ext/session/sessionH.test 71bbff6b1abb2c4ac62b84dee53273c37e0b21e5fde3aed80929403e091ef859
|
||||||
F ext/session/session_common.tcl e5598096425486b363718e2cda48ee85d660c96b4f8ea9d9d7a4c3ef514769da
|
F ext/session/session_common.tcl e5598096425486b363718e2cda48ee85d660c96b4f8ea9d9d7a4c3ef514769da
|
||||||
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
|
F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3
|
||||||
|
F ext/session/sessionalter.test 72722f6f971c7cb6302a1a3c43ff256c0db1aaf19ae625ecdf710d53f08b1237
|
||||||
F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee
|
F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee
|
||||||
F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf
|
F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf
|
||||||
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
|
F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec
|
||||||
F ext/session/sessionfault.test 573bf027fb870d57bd4e7cf50822a3e4b17b2b923407438747aaa918dec57a09
|
F ext/session/sessionfault.test 573bf027fb870d57bd4e7cf50822a3e4b17b2b923407438747aaa918dec57a09
|
||||||
F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576dc79ed344c46fbf41c
|
F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576dc79ed344c46fbf41c
|
||||||
|
F ext/session/sessionfault3.test 7c7547202775de268f3fe6f074c4d0d165151829710b4e64f90d4a01645ba9e7
|
||||||
F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25
|
F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25
|
||||||
F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09
|
F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09
|
||||||
F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7
|
F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7
|
||||||
@@ -543,9 +547,9 @@ F ext/session/sessionrowid.test 85187c2f1b38861a5844868126f69f9ec62223a03449a98a
|
|||||||
F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
|
F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795
|
||||||
F ext/session/sessionstat1.test b039e38e2ba83767b464baf39b297cc0b1cc6f3292255cb467ea7e12d0d0280c
|
F ext/session/sessionstat1.test b039e38e2ba83767b464baf39b297cc0b1cc6f3292255cb467ea7e12d0d0280c
|
||||||
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc
|
||||||
F ext/session/sqlite3session.c 0fe9107318140cefa1b50f2e1e0f330ab359022599e5976820db349f33efae11
|
F ext/session/sqlite3session.c ea28d07a280dc82efd4e98417a10b582058dc11a0f2a6ac3b194aa20d233d758
|
||||||
F ext/session/sqlite3session.h 653e9d49c4edae231df8a4c8d69c2145195aedb32462d4b44229dbee7d2680fb
|
F ext/session/sqlite3session.h 4d1f69f1d8bfd4798e8f6431de301d17bb2e4097de2f77ca4dad494bb6c60dc0
|
||||||
F ext/session/test_session.c 5285482f83cd92b4c1fe12fcf88210566a18312f4f2aa110f6399dae46aeccbb
|
F ext/session/test_session.c be0610a8ab717c3f9c898576d8b4c43e5eb75384a47fed0a0b22768067552778
|
||||||
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
|
||||||
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
|
||||||
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb
|
||||||
@@ -670,7 +674,7 @@ F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51
|
|||||||
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6
|
||||||
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
|
||||||
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276
|
||||||
F src/json.c e97d03f1c19e403bfe0f0a1deaf50b3e3d657bb8addd5dfe7f9dcf72bcfa3109
|
F src/json.c 8717fe7a6461f24ba7b92ccd323c8e2417f44f2a959704c5a05a7aac1ca0df12
|
||||||
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
|
||||||
F src/loadext.c 98cfba10989b3da6f1807ad42444017742db7f100a54f1032af7a8b1295912c0
|
F src/loadext.c 98cfba10989b3da6f1807ad42444017742db7f100a54f1032af7a8b1295912c0
|
||||||
F src/main.c 618aeb399e993cf561864f4b0cf6a331ee4f355cf663635f8d9da3193a46aa40
|
F src/main.c 618aeb399e993cf561864f4b0cf6a331ee4f355cf663635f8d9da3193a46aa40
|
||||||
@@ -1303,7 +1307,7 @@ F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd286
|
|||||||
F test/json/json-q1-b.txt 606818a5fba6d9e418c9f4ea7d8418af026775042dad81439b72447a147a462c
|
F test/json/json-q1-b.txt 606818a5fba6d9e418c9f4ea7d8418af026775042dad81439b72447a147a462c
|
||||||
F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307
|
F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307
|
||||||
F test/json/json-speed-check.sh b060a9a6c696c0a807d8929400fa11bd7113edc58b0d66b9795f424f8d0db326 x
|
F test/json/json-speed-check.sh b060a9a6c696c0a807d8929400fa11bd7113edc58b0d66b9795f424f8d0db326 x
|
||||||
F test/json101.test e8ccd09f965c594f38ef486ddf7913f0fcac97be20a785a41c3d7cd4289e82de
|
F test/json101.test abb5a0cfde077a6f1124604e75806fbe889bc1c0acc11d32897f191e1f9c6b2c
|
||||||
F test/json102.test 557a46e16df1aa9bdbc4076a71a45814ea0e7503d6621d87d42a8c04cbc2b0ef
|
F test/json102.test 557a46e16df1aa9bdbc4076a71a45814ea0e7503d6621d87d42a8c04cbc2b0ef
|
||||||
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
|
F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe
|
||||||
F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
|
F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1
|
||||||
@@ -2124,8 +2128,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 7b52b266b066f1385144c1103a3a411306db5f44568366ae1e93cd8cce799bbc
|
P cbea16c29eb0507f39b5a1cf744a3bb9bb7c71ac156e84a19d03a37cb1816891 a163fecca90cab9d1b7bf8ebac78d498775eed7b6d81e7920e3401633c3a4b60
|
||||||
R 878d86e1e87a30f2fb868ea5f585d29f
|
R 1dd322f61ae3b783d06705b01094df38
|
||||||
U drh
|
U drh
|
||||||
Z 509d9208ad89eff1e0f2ca5c213ed021
|
Z 41e410a665a938a0454df231f95bd4b4
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
cbea16c29eb0507f39b5a1cf744a3bb9bb7c71ac156e84a19d03a37cb1816891
|
9422c24f4a8b290dcae61e50ec81be5b314b22c61a2bca1e194e47da1316b6e6
|
@@ -4766,6 +4766,7 @@ static void jsonReplaceFunc(
|
|||||||
}
|
}
|
||||||
pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
|
pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
|
||||||
if( pParse==0 ) return;
|
if( pParse==0 ) return;
|
||||||
|
pParse->nJPRef++;
|
||||||
for(i=1; i<(u32)argc; i+=2){
|
for(i=1; i<(u32)argc; i+=2){
|
||||||
zPath = (const char*)sqlite3_value_text(argv[i]);
|
zPath = (const char*)sqlite3_value_text(argv[i]);
|
||||||
pParse->useMod = 1;
|
pParse->useMod = 1;
|
||||||
@@ -4778,6 +4779,7 @@ static void jsonReplaceFunc(
|
|||||||
jsonReturnNodeAsJson(pParse, pParse->aNode, ctx, 1);
|
jsonReturnNodeAsJson(pParse, pParse->aNode, ctx, 1);
|
||||||
replace_err:
|
replace_err:
|
||||||
jsonDebugPrintParse(pParse);
|
jsonDebugPrintParse(pParse);
|
||||||
|
jsonParseFree(pParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -4813,6 +4815,7 @@ static void jsonSetFunc(
|
|||||||
}
|
}
|
||||||
pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
|
pParse = jsonParseCached(ctx, argv[0], ctx, argc>1);
|
||||||
if( pParse==0 ) return;
|
if( pParse==0 ) return;
|
||||||
|
pParse->nJPRef++;
|
||||||
for(i=1; i<(u32)argc; i+=2){
|
for(i=1; i<(u32)argc; i+=2){
|
||||||
zPath = (const char*)sqlite3_value_text(argv[i]);
|
zPath = (const char*)sqlite3_value_text(argv[i]);
|
||||||
bApnd = 0;
|
bApnd = 0;
|
||||||
@@ -4829,9 +4832,8 @@ static void jsonSetFunc(
|
|||||||
}
|
}
|
||||||
jsonDebugPrintParse(pParse);
|
jsonDebugPrintParse(pParse);
|
||||||
jsonReturnNodeAsJson(pParse, pParse->aNode, ctx, 1);
|
jsonReturnNodeAsJson(pParse, pParse->aNode, ctx, 1);
|
||||||
|
|
||||||
jsonSetDone:
|
jsonSetDone:
|
||||||
/* no cleanup required */;
|
jsonParseFree(pParse);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1098,4 +1098,30 @@ do_execsql_test json101-21.27 {
|
|||||||
SELECT json_group_object(x,y) FROM c;
|
SELECT json_group_object(x,y) FROM c;
|
||||||
} {{{"a":1,"b":2.0,"c":null,:"three","e":"four"}}}
|
} {{{"a":1,"b":2.0,"c":null,:"three","e":"four"}}}
|
||||||
|
|
||||||
|
# 2023-10-09 https://sqlite.org/forum/forumpost/b25edc1d46
|
||||||
|
# UAF due to JSON cache overflow
|
||||||
|
#
|
||||||
|
do_execsql_test json101-22.1 {
|
||||||
|
SELECT json_set(
|
||||||
|
'{}',
|
||||||
|
'$.a', json('1'),
|
||||||
|
'$.a', json('2'),
|
||||||
|
'$.b', json('3'),
|
||||||
|
'$.b', json('4'),
|
||||||
|
'$.c', json('5'),
|
||||||
|
'$.c', json('6')
|
||||||
|
);
|
||||||
|
} {{{"a":2,"b":4,"c":6}}}
|
||||||
|
do_execsql_test json101-22.2 {
|
||||||
|
SELECT json_replace(
|
||||||
|
'{"a":7,"b":8,"c":9}',
|
||||||
|
'$.a', json('1'),
|
||||||
|
'$.a', json('2'),
|
||||||
|
'$.b', json('3'),
|
||||||
|
'$.b', json('4'),
|
||||||
|
'$.c', json('5'),
|
||||||
|
'$.c', json('6')
|
||||||
|
);
|
||||||
|
} {{{"a":2,"b":4,"c":6}}}
|
||||||
|
|
||||||
finish_test
|
finish_test
|
||||||
|
Reference in New Issue
Block a user