# e.g. /usr/lib/jvm/default-javajava-19-openjdk-amd64
JDK_HOME ?= $(JAVA_HOME)
# ^^^ JDK_HOME is not as widely used as JAVA_HOME
-bin.javac := $(JDK_HOME)/bin/javac
-bin.java := $(JDK_HOME)/bin/java
-bin.jar := $(JDK_HOME)/bin/jar
+bin.jar := $(JDK_HOME)/bin/jar
+bin.java := $(JDK_HOME)/bin/java
+bin.javac := $(JDK_HOME)/bin/javac
+bin.javadoc := $(JDK_HOME)/bin/javadoc
ifeq (,$(wildcard $(JDK_HOME)))
$(error set JDK_HOME to the top-most dir of your JDK installation.)
endif
package.jar := sqlite3-jni.jar
-dir.top := ../..
-dir.tool := ../../tool
-dir.jni := $(patsubst %/,%,$(dir $(MAKEFILE)))
-
+dir.top := ../..
+dir.tool := ../../tool
+dir.jni := $(patsubst %/,%,$(dir $(MAKEFILE)))
dir.src := $(dir.jni)/src
dir.src.c := $(dir.src)/c
dir.bld := $(dir.jni)/bld
dir.bld.c := $(dir.bld)
dir.src.jni := $(dir.src)/org/sqlite/jni
dir.src.jni.tester := $(dir.src.jni)/tester
+mkdir := mkdir -p
$(dir.bld.c):
- mkdir -p $@
+ $(mkdir) $@
classpath := $(dir.src)
CLEAN_FILES := $(package.jar)
jar: $(package.jar)
+dir.doc := $(dir.jni)/doc
+doc: $(JAVA_FILES.main)
+ $(bin.javadoc) -cp $(classpath) -d $(dir.doc) org.sqlite.jni
+
+########################################################################
+# Clean up...
CLEAN_FILES += $(dir.bld.c)/* \
$(dir.src.jni)/*.class \
$(dir.src.jni.tester)/*.class \
** index field of those entries are the keys for this particular
** cache.
*/
- NphCache_SIZE = sizeof(S3NphRefs) / sizeof(S3NphRef)
+ S3Jni_NphCache_size = sizeof(S3NphRefs) / sizeof(S3NphRef)
};
/*
** by the sqlite3_context binding. */;
};
-/** State for various hook callbacks. */
+/*
+** State for binding C callbacks to Java methods.
+*/
typedef struct S3JniHook S3JniHook;
struct S3JniHook{
jobject jObj /* global ref to Java instance */;
jmethodID midCallback /* callback method. Signature depends on
** jObj's type */;
+ /* We lookup the jObj.xDestroy() method as-needed for contexts which
+ ** have custom finalizers. */
};
/*
** JNIEnv when necessary.
*/
JavaVM * jvm;
- /* Cache of Java refs/IDs for NativePointerHolder subclasses.
+ /*
+ ** Cache of Java refs/IDs for NativePointerHolder subclasses.
** Initialized on demand.
*/
- S3JniNphClass nph[NphCache_SIZE];
+ S3JniNphClass nph[S3Jni_NphCache_size];
/*
** Cache of per-thread state.
*/
#endif
/* Helpers for working with specific mutexes. */
-#define MUTEX_ENV_ASSERT_LOCKED \
+#define S3JniMutex_Env_assertLocked \
assert( 0 != SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
-#define MUTEX_ENV_ASSERT_LOCKER \
+#define S3JniMutex_Env_assertLocker \
assert( (env) == SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
-#define MUTEX_ENV_ASSERT_NOTLOCKER \
+#define S3JniMutex_Env_assertNotLocker \
assert( (env) != SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" )
-#define MUTEX_ENV_ENTER \
- MUTEX_ENV_ASSERT_NOTLOCKER; \
+#define S3JniMutex_Env_enter \
+ S3JniMutex_Env_assertNotLocker; \
/*MARKER(("Entering ENV mutex@%p %s.\n", env));*/ \
sqlite3_mutex_enter( SJG.envCache.mutex ); \
++SJG.metrics.nMutexEnv; \
SJG.envCache.locker = env
-#define MUTEX_ENV_LEAVE \
+#define S3JniMutex_Env_leave \
/*MARKER(("Leaving ENV mutex @%p %s.\n", env));*/ \
- MUTEX_ENV_ASSERT_LOCKER; \
+ S3JniMutex_Env_assertLocker; \
SJG.envCache.locker = 0; \
sqlite3_mutex_leave( SJG.envCache.mutex )
-#define MUTEX_EXT_ENTER \
+#define S3JniMutex_Ext_enter \
/*MARKER(("Entering autoExt mutex@%p %s.\n", env));*/ \
sqlite3_mutex_enter( SJG.autoExt.mutex ); \
++SJG.metrics.nMutexAutoExt
-#define MUTEX_EXT_LEAVE \
+#define S3JniMutex_Ext_leave \
/*MARKER(("Leaving autoExt mutex@%p %s.\n", env));*/ \
sqlite3_mutex_leave( SJG.autoExt.mutex )
-#define MUTEX_NPH_ENTER \
- MUTEX_ENV_ASSERT_NOTLOCKER; \
+#define S3JniMutex_Nph_enter \
+ S3JniMutex_Env_assertNotLocker; \
/*MARKER(("Entering NPH mutex@%p %s.\n", env));*/ \
sqlite3_mutex_enter( SJG.envCache.mutex ); \
++SJG.metrics.nMutexEnv2; \
SJG.envCache.locker = env
-#define MUTEX_NPH_LEAVE \
+#define S3JniMutex_Nph_leave \
/*MARKER(("Leaving NPH mutex @%p %s.\n", env));*/ \
- MUTEX_ENV_ASSERT_LOCKER; \
+ S3JniMutex_Env_assertLocker; \
SJG.envCache.locker = 0; \
sqlite3_mutex_leave( SJG.envCache.mutex )
-#define MUTEX_PDB_ENTER \
+#define S3JniMutex_Pdb_enter \
/*MARKER(("Entering PerDb mutex@%p %s.\n", env));*/ \
sqlite3_mutex_enter( SJG.perDb.mutex ); \
++SJG.metrics.nMutexPerDb; \
SJG.perDb.locker = env;
-#define MUTEX_PDB_LEAVE \
+#define S3JniMutex_Pdb_leave \
/*MARKER(("Leaving PerDb mutex@%p %s.\n", env));*/ \
SJG.perDb.locker = 0; \
sqlite3_mutex_leave( SJG.perDb.mutex )
*/
static S3JniEnv * S3JniGlobal_env_cache(JNIEnv * const env){
struct S3JniEnv * row;
- MUTEX_ENV_ENTER;
+ S3JniMutex_Env_enter;
row = SJG.envCache.aHead;
for( ; row; row = row->pNext ){
if( row->env == env ){
s3jni_incr( &SJG.metrics.envCacheHits );
- MUTEX_ENV_LEAVE;
+ S3JniMutex_Env_leave;
return row;
}
}
SJG.envCache.aHead = row;
row->env = env;
- MUTEX_ENV_LEAVE;
+ S3JniMutex_Env_leave;
return row;
}
*/
static void S3JniDb_set_aside(JNIEnv * env, S3JniDb * const s){
if(s){
- MUTEX_PDB_ENTER;
+ S3JniMutex_Pdb_enter;
assert(s->pPrev != s);
assert(s->pNext != s);
assert(s->pPrev ? (s->pPrev!=s->pNext) : 1);
s->pNext = SJG.perDb.aFree;
if(s->pNext) s->pNext->pPrev = s;
SJG.perDb.aFree = s;
- MUTEX_PDB_LEAVE;
+ S3JniMutex_Pdb_leave;
}
}
*/
static int S3JniGlobal_env_uncache(JNIEnv * const env){
struct S3JniEnv * row;
- MUTEX_ENV_ASSERT_LOCKED;
+ S3JniMutex_Env_assertLocked;
row = SJG.envCache.aHead;
for( ; row; row = row->pNext ){
if( row->env == env ){
**
** It is up to the caller to populate the other members of the
** returned object if needed, taking care to lock the population with
-** MUTEX_NPH_ENTER/LEAVE.
+** S3JniMutex_Nph_enter/LEAVE.
**
** This simple cache catches >99% of searches in the current
** (2023-07-31) tests.
cached as well.
*/
S3JniNphClass * const pNC = &SJG.nph[pRef->index];
+ assert( (void*)pRef>=(void*)&S3NphRefs && (void*)pRef<(void*)(&S3NphRefs + 1)
+ && "pRef is out of range." );
if( !pNC->pRef ){
- MUTEX_NPH_ENTER;
+ S3JniMutex_Nph_enter;
if( !pNC->pRef ){
pNC->pRef = pRef;
pNC->klazz = (*env)->FindClass(env, pRef->zName);
EXCEPTION_IS_FATAL("FindClass() unexpectedly threw");
pNC->klazz = REF_G(pNC->klazz);
}
- MUTEX_NPH_LEAVE;
+ S3JniMutex_Nph_leave;
}
return pNC;
}
static jfieldID NativePointerHolder_getField(JNIEnv * const env, S3NphRef const* pRef){
S3JniNphClass * const pNC = S3JniGlobal_nph_cache(env, pRef);
if( !pNC->fidValue ){
- MUTEX_NPH_ENTER;
+ S3JniMutex_Nph_enter;
if( !pNC->fidValue ){
pNC->fidValue = (*env)->GetFieldID(env, pNC->klazz, "nativePointer", "J");
EXCEPTION_IS_FATAL("Code maintenance required: missing nativePointer field.");
}
- MUTEX_NPH_LEAVE;
+ S3JniMutex_Nph_leave;
}
return pNC->fidValue;
}
static S3JniDb * S3JniDb_alloc(JNIEnv * const env, sqlite3 *pDb,
jobject jDb){
S3JniDb * rv;
- MUTEX_PDB_ENTER;
+ S3JniMutex_Pdb_enter;
if( SJG.perDb.aFree ){
rv = SJG.perDb.aFree;
SJG.perDb.aFree = rv->pNext;
rv->jDb = REF_G(jDb);
rv->pDb = pDb;
}
- MUTEX_PDB_LEAVE;
+ S3JniMutex_Pdb_leave;
return rv;
}
static S3JniDb * S3JniDb_for_db(JNIEnv * const env, jobject jDb, sqlite3 *pDb){
S3JniDb * s = 0;
if( jDb || pDb ){
- MUTEX_PDB_ENTER;
+ S3JniMutex_Pdb_enter;
s = SJG.perDb.aUsed;
if( !pDb ){
assert( jDb );
break;
}
}
- MUTEX_PDB_LEAVE;
+ S3JniMutex_Pdb_leave;
}
return s;
}
S3JniNphClass * const pNC =
S3JniGlobal_nph_cache(env, &S3NphRefs.sqlite3_context);
if( !pNC->fidAggCtx ){
- MUTEX_NPH_ENTER;
+ S3JniMutex_Nph_enter;
if( !pNC->fidAggCtx ){
pNC->fidAggCtx = (*env)->GetFieldID(env, pNC->klazz, "aggregateContext", "J");
EXCEPTION_IS_FATAL("Cannot get sqlite3_contex.aggregateContext member.");
}
- MUTEX_NPH_LEAVE;
+ S3JniMutex_Nph_leave;
}
pAgg = sqlite3_aggregate_context(pCx, isFinal ? 0 : sizeof(void*));
if( pAgg || isFinal ){
jobject const jOut){
S3JniNphClass * const pNC = S3JniGlobal_nph_cache(env, pRef);
if( !pNC->fidValue ){
- MUTEX_NPH_ENTER;
+ S3JniMutex_Nph_enter;
if( !pNC->fidValue ){
pNC->fidValue = (*env)->GetFieldID(env, pNC->klazz, "value", zTypeSig);
EXCEPTION_IS_FATAL("setupOutputPointer() could not find OutputPointer.*.value");
}
- MUTEX_NPH_LEAVE;
+ S3JniMutex_Nph_leave;
}
return pNC->fidValue;
}
jobject rv = 0;
S3JniNphClass * const pNC = S3JniGlobal_nph_cache(env, pRef);
if( !pNC->midCtor ){
- MUTEX_NPH_ENTER;
+ S3JniMutex_Nph_enter;
if( !pNC->midCtor ){
pNC->midCtor = (*env)->GetMethodID(env, pNC->klazz, "<init>", "()V");
EXCEPTION_IS_FATAL("Cannot find constructor for class.");
}
- MUTEX_NPH_LEAVE;
+ S3JniMutex_Nph_leave;
}
rv = (*env)->NewObject(env, pNC->klazz, pNC->midCtor);
EXCEPTION_IS_FATAL("No-arg constructor threw.");
** local reference to it, to avoid a race condition with another
** thread manipulating the list during the call and invaliding
** what ax points to. */;
- MUTEX_EXT_ENTER;
+ S3JniMutex_Ext_enter;
if( i >= SJG.autoExt.nExt ){
go = 0;
}else{
ax.jObj = REF_L(SJG.autoExt.pExt[i].jObj);
ax.midFunc = SJG.autoExt.pExt[i].midFunc;
}
- MUTEX_EXT_LEAVE;
+ S3JniMutex_Ext_leave;
if( ax.jObj ){
rc = (*env)->CallIntMethod(env, ax.jObj, ax.midFunc, ps->jDb);
UNREF_L(ax.jObj);
int rc = 0;
if( !jAutoExt ) return SQLITE_MISUSE;
- MUTEX_EXT_ENTER;
+ S3JniMutex_Ext_enter;
for( i = 0; i < SJG.autoExt.nExt; ++i ){
/* Look for match or first empty slot. */
ax = &SJG.autoExt.pExt[i];
if( ax->jObj && (*env)->IsSameObject(env, ax->jObj, jAutoExt) ){
- MUTEX_EXT_LEAVE;
+ S3JniMutex_Ext_leave;
return 0 /* this as a no-op. */;
}
}
++SJG.autoExt.nExt;
}
}
- MUTEX_EXT_LEAVE;
+ S3JniMutex_Ext_leave;
return rc;
}
S3JniAutoExtension * ax;
jboolean rc = JNI_FALSE;
int i;
- MUTEX_EXT_ENTER;
+ S3JniMutex_Ext_enter;
/* This algo mirrors the one in the core. */
for( i = SJG.autoExt.nExt-1; i >= 0; --i ){
ax = &SJG.autoExt.pExt[i];
break;
}
}
- MUTEX_EXT_LEAVE;
+ S3JniMutex_Ext_leave;
return rc;
}
/* Clears all entries from S3JniGlobal.autoExt. */
static void s3jni_reset_auto_extension(JNIEnv *env){
int i;
- MUTEX_EXT_ENTER;
+ S3JniMutex_Ext_enter;
for( i = 0; i < SJG.autoExt.nExt; ++i ){
S3JniAutoExtension_clear( env, &SJG.autoExt.pExt[i] );
}
SJG.autoExt.nExt = 0;
- MUTEX_EXT_LEAVE;
+ S3JniMutex_Ext_leave;
}
S3JniApi(sqlite3_reset_auto_extension(),void,1reset_1auto_1extension)(
JniArgsEnvClass
){
s3jni_reset_auto_extension(env);
- MUTEX_ENV_ENTER;
+ S3JniMutex_Env_enter;
while( SJG.envCache.aHead ){
S3JniGlobal_env_uncache( SJG.envCache.aHead->env );
}
- MUTEX_ENV_LEAVE;
+ S3JniMutex_Env_leave;
/* Do not clear S3JniGlobal.jvm: it's legal to call
sqlite3_initialize() again to restart the lib. */
return sqlite3_shutdown();
SO(S3JniDb);
SO(S3NphRefs);
printf("\t(^^^ %u NativePointerHolder subclasses)\n",
- (unsigned)NphCache_SIZE);
+ (unsigned)S3Jni_NphCache_size);
SO(S3JniGlobal);
SO(S3JniAutoExtension);
SO(S3JniUdf);
jobject pNPH = new_NativePointerHolder_object(
env, &S3NphRefs.Fts5ExtensionApi, s3jni_ftsext()
);
- MUTEX_ENV_ENTER;
+ S3JniMutex_Env_enter;
if( pNPH ){
if( !SJG.fts5.jFtsExt ){
SJG.fts5.jFtsExt = REF_G(pNPH);
}
UNREF_L(pNPH);
}
- MUTEX_ENV_LEAVE;
+ S3JniMutex_Env_leave;
}
return SJG.fts5.jFtsExt;
}
JNIEXPORT jboolean JNICALL
Java_org_sqlite_jni_SQLite3Jni_uncacheJniEnv(JniArgsEnvClass){
int rc;
- MUTEX_ENV_ENTER;
+ S3JniMutex_Env_enter;
rc = S3JniGlobal_env_uncache(env);
- MUTEX_ENV_LEAVE;
+ S3JniMutex_Env_leave;
return rc ? JNI_TRUE : JNI_FALSE;
}
/*
* Class: org_sqlite_jni_SQLite3Jni
- * Method: sqlite3_do_something_for_developer
+ * Method: sqlite3_jni_internal_details
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1do_1something_1for_1developer
+JNIEXPORT void JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1jni_1internal_1details
(JNIEnv *, jclass);
#ifdef __cplusplus
access to the callback functions needed in order to implement SQL
functions in Java.
+ <p>
+
This class is not used by itself, but is a marker base class. The
three UDF types are modelled by the inner classes Scalar,
Aggregate<T>, and Window<T>. Most simply, clients may subclass
managing their accumulator state across calls to the UDF's
callbacks.
- If a given aggregate or window function is called multiple times
+ <p>If a given aggregate or window function is called multiple times
in a single SQL statement, e.g. SELECT MYFUNC(A), MYFUNC(B)...,
then the clients need some way of knowing which call is which so
that they can map their state between their various UDF callbacks
and reset it via xFinal(). This class takes care of such
mappings.
- This class works by mapping
+ <p>This class works by mapping
sqlite3_context.getAggregateContext() to a single piece of
state, of a client-defined type (the T part of this class), which
persists across a "matching set" of the UDF's callbacks.
- This class is a helper providing commonly-needed functionality -
+ <p>This class is a helper providing commonly-needed functionality -
it is not required for use with aggregate or window functions.
Client UDFs are free to perform such mappings using custom
approaches. The provided Aggregate<T> and Window<T> classes
without requiring that the client update the underlying map's
entry.
- T must be of a type which can be legally stored as a value in
+ <p>T must be of a type which can be legally stored as a value in
java.util.HashMap<KeyType,T>.
*/
public ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
}
}
- //! Subclass for creating scalar functions.
+ /**
+ Subclass for creating scalar functions.
+ */
public static abstract class Scalar extends SQLFunction {
/**
argument, the context is set to the given initial value. On all other
calls, the 2nd argument is ignored.
- @see PerContextState<T>#takeAggregateState()
+ @see SQLFunction.PerContextState#getAggregateState()
*/
protected final ValueHolder<T> getAggregateState(sqlite3_context cx, T initialValue){
return map.getAggregateState(cx, initialValue);
To be called from the implementation's xFinal() method to fetch
the final state of the UDF and remove its mapping.
- @see PerContextState<T>#takeAggregateState()
+ see SQLFunction.PerContextState#takeAggregateState()
*/
protected final T takeAggregateState(sqlite3_context cx){
return map.takeAggregateState(cx);
/**
This annotation is for flagging parameters which may not legally be
- null. Note that the C-style API does _not_ throw any
+ null. Note that the C-style API does not throw any
NullPointerExceptions on its own because it has a no-throw policy
in order to retain its C-style semantics.
This class contains the entire sqlite3 JNI API binding. For
client-side use, a static import is recommended:
- ```
+ {@code
import static org.sqlite.jni.SQLite3Jni.*;
- ```
+ }
The C-side part can be found in sqlite3-jni.c.
- Only functions which materially differ from their C counterparts
+ <p>Only functions which materially differ from their C counterparts
are documented here. The C documetation is otherwise applicable
here:
- https://sqlite.org/c3ref/intro.html
+ <p>{link https://sqlite.org/c3ref/intro.html}
- A handful of Java-specific APIs have been added.
+ <p>A handful of Java-specific APIs have been added.
- ******************************************************************
- *** Warning regarding Java's Modified UTF-8 vs standard UTF-8: ***
- ******************************************************************
+ <p>Notes regarding Java's Modified UTF-8 vs standard UTF-8:
- SQLite internally uses UTF-8 encoding, whereas Java natively uses
+ <p>SQLite internally uses UTF-8 encoding, whereas Java natively uses
UTF-16. Java JNI has routines for converting to and from UTF-8,
- _but_ JNI uses what its docs call modified UTF-8 (see links below)
+ but JNI uses what its docs call modified UTF-8 (see links below)
Care must be taken when converting Java strings to or from standard
UTF-8 to ensure that the proper conversion is performed. In short,
Java's `String.getBytes(StandardCharsets.UTF_8)` performs the proper
conversion in Java, and there are no JNI C APIs for that conversion
(JNI's `NewStringUTF()` requires its input to be in MUTF-8).
- The known consequences and limitations this discrepancy places on
+ <p>The known consequences and limitations this discrepancy places on
the SQLite3 JNI binding include:
- - Any functions which return state from a database take extra care
- to perform proper conversion, at the cost of efficiency.
+ <ul>
+
+ <li>Any functions which return state from a database take extra care
+ to perform proper conversion, at the cost of efficiency.</li>
+
+ <li>C functions which take C-style strings without a length argument
+ require special care when taking input from Java. In particular,
+ Java strings converted to byte arrays for encoding purposes are not
+ NUL-terminated, and conversion to a Java byte array must be careful
+ to add one. Functions which take a length do not require this so
+ long as the length is provided. Search the SQLite3Jni class for "\0"
+ for many examples.
- - C functions which take C-style strings without a length argument
- require special care when taking input from Java. In particular,
- Java strings converted to byte arrays for encoding purposes are
- not NUL-terminated, and conversion to a Java byte array must be
- careful to add one. Functions which take a length do not require
- this so long as the length is provided. Search the SQLite3Jni
- class for "\0" for many examples.
+ <li>Similarly, C-side code which deals with strings which might not
+ be NUL-terminated (e.g. while tokenizing in FTS5-related code)
+ cannot use JNI's new-string functions to return them to Java because
+ none of those APIs take a string-length argument. Such cases must
+ return byte arrays instead of strings.
- - Similarly, C-side code which deals with strings which might not be
- NUL-terminated (e.g. while tokenizing in FTS5-related code) cannot
- use JNI's new-string functions to return them to Java because none
- of those APIs take a string-length argument. Such cases must
- return byte arrays instead of strings.
+ </ul>
- Further reading:
+ <p>Further reading:
- - https://stackoverflow.com/questions/57419723
- - https://stackoverflow.com/questions/7921016
- - https://itecnote.com/tecnote/java-getting-true-utf-8-characters-in-java-jni/
- - https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#unicode
- - https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8
+ <p><a href="https://stackoverflow.com/questions/57419723">https://stackoverflow.com/questions/57419723</a>
+ <p><a href="https://stackoverflow.com/questions/7921016">https://stackoverflow.com/questions/7921016</a>
+ <p><a href="https://itecnote.com/tecnote/java-getting-true-utf-8-characters-in-java-jni/">https://itecnote.com/tecnote/java-getting-true-utf-8-characters-in-java-jni/</a>
+ <p><a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#unicode">https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#unicode</a>
+ <p><a href="https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8">https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8</a>
*/
public final class SQLite3Jni {
This will clean up any cached per-JNIEnv info. Calling into the
library will re-initialize the cache on demand.
- This process does _not_ close any databases or finalize
+ This process does not close any databases or finalize
any prepared statements because their ownership does not depend on
a given thread. For proper library behavior, and to
avoid C-side leaks, be sure to finalize all statements and close
/**
Internal impl of the public sqlite3_strglob() method. Neither argument
- may be NULL and both _MUST_ be NUL-terminated.
+ may be NULL and both MUST be NUL-terminated.
*/
private static native int sqlite3_strglob(
@NotNull byte[] glob, @NotNull byte[] txt
/**
Internal impl of the public sqlite3_strlike() method. Neither
- argument may be NULL and both _MUST_ be NUL-terminated.
+ argument may be NULL and both MUST be NUL-terminated.
*/
private static native int sqlite3_strlike(
@NotNull byte[] glob, @NotNull byte[] txt, int escChar
/**
This is NOT part of the public API. It exists solely as a place
- to hook in arbitrary C-side code during development and testing
- of this library.
+ for this code's developers to collect internal metrics and such.
+ It has no stable interface. It may go way or change behavior at
+ any time.
*/
- public static native void sqlite3_do_something_for_developer();
+ public static native void sqlite3_jni_internal_details();
//////////////////////////////////////////////////////////////////////
// SQLITE_... constants follow...
outln("\tAssertions checked: ",affirmCount);
outln("\tDatabases opened: ",metrics.dbOpen);
if( doSomethingForDev ){
- sqlite3_do_something_for_developer();
+ sqlite3_jni_internal_details();
}
sqlite3_shutdown();
int nMethods = 0;
--- /dev/null
+/**
+ This package houses a JNI binding to the SQLite3 C API.
+
+ The docs are in progress.
+*/
+package org.sqlite.jni;
t.outln("Aborted ",t.nAbortedScript," script(s).");
}
if( dumpInternals ){
- sqlite3_do_something_for_developer();
+ sqlite3_jni_internal_details();
}
}
}
-C Doc,\scode\sstyle,\sand\slegibility\scleanups.
-D 2023-08-24T17:25:05.398
+C More\scode\slegibility\sand\sstyle\simprovements\sin\sthe\sJNI\spieces.\sStart\swork\son\sa\sjavadoc\sbuild.
+D 2023-08-24T18:43:25.053
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
-F ext/jni/GNUmakefile 2e17aae8debf0b0ee12010500eae7bd9557f8ad5554f0161c39a41f229e84e3e
+F ext/jni/GNUmakefile 6b3c0fd8d055c129735702d0b288589d25544dd404a00d46d9eb43770fe7f78f
F ext/jni/README.md 9d3caa2e038bfe5e8356a9e8ff66f93ca0647ac278339eeea296f10017f5cf35
F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
-F ext/jni/src/c/sqlite3-jni.c 1da808c65c101d603bc4d8c755aff618c6ce9331b79ef431128ff076cdfca8f7
-F ext/jni/src/c/sqlite3-jni.h d1ee39fe20cb5ac189c5b4c3afa5ff47e259ccfed006eee629c2fdf9fc474856
+F ext/jni/src/c/sqlite3-jni.c 8db2fcc05dd7749f9f4175e2654344feccac6abfd19fd9db0d116c6350e3b625
+F ext/jni/src/c/sqlite3-jni.h 2b81cfb83933cb18e5f690487f4556591d3329538809c847d00190aa4d69aa1d
F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
F ext/jni/src/org/sqlite/jni/AutoExtension.java bcc1849b2fccbe5e2d7ac9e9ac7f8d05a6d7088a8fedbaad90e39569745a61e6
F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
F ext/jni/src/org/sqlite/jni/ProgressHandler.java 6f62053a828a572de809828b1ee495380677e87daa29a1c57a0e2c06b0a131dc
F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86
F ext/jni/src/org/sqlite/jni/RollbackHook.java b04c8abcc6ade44a8a57129e33765793f69df0ba909e49ba18d73f4268d92564
-F ext/jni/src/org/sqlite/jni/SQLFunction.java f697cf2a81c4119f2baf0682af689686f0466f1dd83dba00885f5603e693fe16
+F ext/jni/src/org/sqlite/jni/SQLFunction.java 5851698d96ee29171d68930ad758d0f5a253f7575f1feb890d82b2557a8d3ef5
F ext/jni/src/org/sqlite/jni/SQLLog.java c60610b35208416940822e834d61f08fbbe5d6e06b374b541b49e41fd56c9798
-F ext/jni/src/org/sqlite/jni/SQLite3Jni.java eaf6a3d6814465c2a9e67d6b32a4af2b8efaaa69cf905f8bb81c05222bfaf602
-F ext/jni/src/org/sqlite/jni/Tester1.java 3fcc891398e412fdbd49b40140c1ded83991218d396016184237bf74e1bc18c5
+F ext/jni/src/org/sqlite/jni/SQLite3Jni.java d96f10a097c1d614b44353e85a65368d9aca565d5ae57fae0104811594fbdfba
+F ext/jni/src/org/sqlite/jni/Tester1.java 76f308ad9bf0bd74374561c30c65564ed24583a465264b751d9e2333980149f1
F ext/jni/src/org/sqlite/jni/TesterFts5.java 6f135c60e24c89e8eecb9fe61dde0f3bb2906de668ca6c9186bcf34bdaf94629
F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d
F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d
F ext/jni/src/org/sqlite/jni/fts5_api.java 5198be71c162e3e0cb1f4962a7cdf0d7596e8af53f70c4af6db24aab8d53d9ba
F ext/jni/src/org/sqlite/jni/fts5_extension_function.java ac825035d7d83fc7fd960347abfa6803e1614334a21533302041823ad5fc894c
F ext/jni/src/org/sqlite/jni/fts5_tokenizer.java e530b36e6437fcc500e95d5d75fbffe272bdea20d2fac6be2e1336c578fba98b
+F ext/jni/src/org/sqlite/jni/package-info.java 1a547913d681411d65c5fe0bca840f049abe5612740154a125545ea9e2481747
F ext/jni/src/org/sqlite/jni/sqlite3.java 62b1b81935ccf3393472d17cb883dc5ff39c388ec3bc1de547f098a0217158fc
F ext/jni/src/org/sqlite/jni/sqlite3_context.java fe7797a696978f057528a57b7a11e7797ed41fd7afcf100c5ebb67055d9f706f
F ext/jni/src/org/sqlite/jni/sqlite3_stmt.java 78e6d1b95ac600a9475e9db4623f69449322b0c93d1bd4e1616e76ed547ed9fc
F ext/jni/src/org/sqlite/jni/sqlite3_value.java 3d1d4903e267bc0bc81d57d21f5e85978eff389a1a6ed46726dbe75f85e6914a
-F ext/jni/src/org/sqlite/jni/tester/SQLTester.java 2835eb3dd1e14767ca49354c224150c70300d8013d6d51dd875f7d9380faa278
+F ext/jni/src/org/sqlite/jni/tester/SQLTester.java bc3d6797a2f6cb7d443a0b72af84e5a45e0416b96af52e432d28e123db1970c3
F ext/jni/src/org/sqlite/jni/tester/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e
F ext/jni/src/tests/000-000-sanity.test cfe6dc1b950751d6096e3f5695becaadcdaa048bfe9567209d6eb676e693366d
F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 862f9828e078ae138c3533658c45e4c45155975794e752b9b3a71a693842f37a
-R eb32cfcd718e24e179eb7f83fffb0fa5
+P cf185bcd25629d882a030b8b87048179a120ab1f84aa1d68b279c499dbdf0dba
+R 409ebb8571a40aa1108ef1efd5f91432
U stephan
-Z 2f5c08343242711ee223d20d111fc13d
+Z 85677113ed9046ae48bf181600ab6418
# Remove this line to create a well-formed Fossil manifest.
-cf185bcd25629d882a030b8b87048179a120ab1f84aa1d68b279c499dbdf0dba
\ No newline at end of file
+62b404d62fd62f4d220838b59c9f38a71afa2d4a8c3af0a5c9495fa7020972cf
\ No newline at end of file