]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Make JNI interfaces of sqlite3_column/value_text() match the C ones better. Internal...
authorstephan <stephan@noemail.net>
Fri, 1 Sep 2023 13:27:59 +0000 (13:27 +0000)
committerstephan <stephan@noemail.net>
Fri, 1 Sep 2023 13:27:59 +0000 (13:27 +0000)
FossilOrigin-Name: eb24f97253d9c8e7c728c2ac67a0824b10ca67362ac4f8abb94d5d3c54c58c5b

ext/jni/GNUmakefile
ext/jni/src/c/sqlite3-jni.c
ext/jni/src/c/sqlite3-jni.h
ext/jni/src/org/sqlite/jni/SQLite3Jni.java
ext/jni/src/org/sqlite/jni/Tester1.java
ext/jni/src/org/sqlite/jni/TesterFts5.java
ext/jni/src/org/sqlite/jni/annotation/Canonical.java
manifest
manifest.uuid

index 3e4d54fb0536d492c4acf03caf550420f70ae73f..ae0c53f9021eebbd16b9afa2a83521c8feebc7a3 100644 (file)
@@ -176,6 +176,7 @@ $(sqlite3.c): $(sqlite3.h)
 
 opt.threadsafe ?= 1
 opt.fatal-oom ?= 1
+opt.debug ?= 1
 SQLITE_OPT = \
   -DSQLITE_ENABLE_RTREE \
   -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
@@ -193,10 +194,13 @@ SQLITE_OPT = \
   -DSQLITE_TEMP_STORE=2 \
   -DSQLITE_USE_URI=1 \
   -DSQLITE_C=$(sqlite3.c) \
-  -DSQLITE_JNI_FATAL_OOM=$(opt.fatal-oom) \
-  -DSQLITE_DEBUG
+  -DSQLITE_JNI_FATAL_OOM=$(opt.fatal-oom)
 
-SQLITE_OPT += -g -DDEBUG -UNDEBUG
+ifeq (1,$(opt.debug))
+  SQLITE_OPT += -DSQLITE_DEBUG -g -DDEBUG -UNDEBUG
+else
+  SQLITE_OPT += -O2
+endif
 
 ifeq (1,$(enable.fts5))
   SQLITE_OPT += -DSQLITE_ENABLE_FTS5
@@ -318,16 +322,21 @@ endif
 tester-ext: tester-local
 tester: tester-ext
 tests: tester
-
 ########################################################################
 # Build each SQLITE_THREADMODE variant and run all tests against them.
 multitest: clean
-       $(MAKE) opt.threadsafe=0 opt.oom=1 tests clean
-       $(MAKE) opt.threadsafe=0 opt.oom=0 tests clean
-       $(MAKE) opt.threadsafe=1 opt.oom=1 tests clean
-       $(MAKE) opt.threadsafe=1 opt.oom=0 tests clean
-       $(MAKE) opt.threadsafe=2 opt.oom=1 tests clean
-       $(MAKE) opt.threadsafe=2 opt.oom=0 tests clean
+define MULTIOPT
+multitest: multitest-$(1)
+multitest-$(1):
+       $$(MAKE) opt.debug=$$(opt.debug) $(patsubst %,opt.%,$(2)) tests clean
+endef
+
+$(eval $(call MULTIOPT,01,threadsafe=0 oom=1))
+$(eval $(call MULTIOPT,00,threadsafe=0 oom=0))
+$(eval $(call MULTIOPT,11,threadsafe=1 oom=1))
+$(eval $(call MULTIOPT,10,threadsafe=1 oom=0))
+$(eval $(call MULTIOPT,21,threadsafe=2 oom=1))
+$(eval $(call MULTIOPT,20,threadsafe=2 oom=0))
 
 
 ########################################################################
index 553886df6b75a5f2d7d18db1a9a6b66c94e98bd4..831a4d8001be370f47d3965ac69d984ed205ab91 100644 (file)
 ** S3JniApi's intent is that CFunc be the C API func(s) the
 ** being-declared JNI function is wrapping, making it easier to find
 ** that function's JNI-side entry point. The other args are for JniDecl.
- */
+** See the many examples in this file.
+*/
 #define S3JniApi(CFunc,ReturnType,Suffix) JniDecl(ReturnType,Suffix)
 
 /*
@@ -302,10 +303,10 @@ struct S3JniNphRef {
 };
 
 /*
-** Cache keys for each concrete NativePointerHolder subclass and
-** OutputPointer.T type. The members are to be used with
-** s3jni_nph() and friends, and each one's member->index
-** corresponds to its index in the S3JniGlobal.nph[] array.
+** Cache keys for each concrete NativePointerHolder subclasses and
+** OutputPointer.T types. The members are to be used with s3jni_nph()
+** and friends, and each one's member->index corresponds to its index
+** in the S3JniGlobal.nph[] array.
 */
 static const struct {
   const S3JniNphRef sqlite3;
@@ -361,6 +362,8 @@ static const struct {
 #undef RefO
 };
 
+#define S3JniNph(T) &S3JniNphRefs.T
+
 enum {
   /*
   ** Size of the NativePointerHolder cache.  Need enough space for
@@ -380,10 +383,24 @@ enum {
 */
 typedef struct S3JniNphClass S3JniNphClass;
 struct S3JniNphClass {
-  volatile const S3JniNphRef * pRef /* Entry from S3JniNphRefs. */;
-  jclass klazz                /* global ref to the concrete
-                              ** NativePointerHolder subclass
-                              ** represented by zClassName */;
+  volatile const S3JniNphRef * pRef /* Entry from S3JniNphRefs */;
+  /*
+  ** klazz is a global ref to the class represented by pRef.
+  **
+  ** According to:
+  **
+  **   https://developer.ibm.com/articles/j-jni/
+  **
+  ** > ... the IDs returned for a given class don't change for the
+  **   lifetime of the JVM process. But the call to get the field or
+  **   method can require significant work in the JVM, because fields
+  **   and methods might have been inherited from superclasses, making
+  **   the JVM walk up the class hierarchy to find them. Because the
+  **   IDs are the same for a given class, you should look them up
+  **   once and then reuse them. Similarly, looking up class objects
+  **   can be expensive, so they should be cached as well.
+  */
+  jclass klazz;
   volatile jmethodID midCtor  /* klazz's no-arg constructor. Used by
                               ** new_NativePointerHolder_object(). */;
   volatile jfieldID fidValue  /* NativePointerHolder.nativePointer or
@@ -465,7 +482,7 @@ static const char * const S3JniDb_clientdata_key = "S3JniDb";
 */
 typedef struct S3JniEnv S3JniEnv;
 struct S3JniEnv {
-  JNIEnv *env            /* env in which this cache entry was created */;
+  JNIEnv *env /* JNIEnv in which this cache entry was created */;
   /*
   ** pdbOpening is used to coordinate the Java/DB connection of a
   ** being-open()'d db in the face of auto-extensions.
@@ -561,7 +578,6 @@ struct S3JniGlobalType {
   **   threads. Caching a copy of the JavaVM object enables any thread
   **   with access to the cached object to get access to its own
   **   JNIEnv when necessary.
-  **
   */
   JavaVM * jvm;
   /* Global mutex. */
@@ -577,9 +593,8 @@ struct S3JniGlobalType {
   struct {
     S3JniEnv * aHead      /* Linked list of in-use instances */;
     S3JniEnv * aFree      /* Linked list of free instances */;
-    sqlite3_mutex * mutex /* mutex for aHead and aFree, first-time
-                             inits of nph[] entries, and
-                             NativePointerHolder_get/set(). */;
+    sqlite3_mutex * mutex /* mutex for aHead and aFree, and first-time
+                             inits of nph[] entries. */;
     void const * locker   /* env mutex is held on this object's behalf.
                              Used only for sanity checking. */;
   } envCache;
@@ -1040,7 +1055,7 @@ static char * s3jni_exception_error_msg(JNIEnv * const env, jthrowable jx){
 ** Returns errCode unless it is 0, in which case SQLITE_ERROR is
 ** returned.
 */
-static int s3jni__db_exception(JNIEnv * const env, S3JniDb * const ps,
+static int s3jni__db_exception(JNIEnv * const env, sqlite3 * const pDb,
                               int errCode, const char *zDfltMsg){
   jthrowable const ex = (*env)->ExceptionOccurred(env);
 
@@ -1048,17 +1063,17 @@ static int s3jni__db_exception(JNIEnv * const env, S3JniDb * const ps,
   if( ex ){
     char * zMsg;
     S3JniExceptionClear;
-    S3JniDb_mutex_enter;
     zMsg = s3jni_exception_error_msg(env, ex);
-    s3jni_db_error(ps->pDb, errCode, zMsg ? zMsg : zDfltMsg);
+    s3jni_db_error(pDb, errCode, zMsg ? zMsg : zDfltMsg);
     sqlite3_free(zMsg);
     S3JniUnrefLocal(ex);
-    S3JniDb_mutex_leave;
+  }else if( zDfltMsg ){
+    s3jni_db_error(pDb, errCode, zDfltMsg);
   }
   return errCode;
 }
-#define s3jni_db_exception(JniDb,ERRCODE,DFLTMSG) \
-  s3jni__db_exception(env, (JniDb), (ERRCODE), (DFLTMSG) )
+#define s3jni_db_exception(pDb,ERRCODE,DFLTMSG) \
+  s3jni__db_exception(env, (pDb), (ERRCODE), (DFLTMSG) )
 
 /*
 ** Extracts the (void xDestroy()) method from jObj and applies it to
@@ -1140,8 +1155,7 @@ static void S3JniHook__unref(JNIEnv * const env, S3JniHook * const s){
   }
   *s = S3JniHook_empty;
 }
-#define S3JniHook_unref(hook) \
-  S3JniHook__unref(env, (hook))
+#define S3JniHook_unref(hook) S3JniHook__unref(env, (hook))
 
 /*
 ** Allocates one blank S3JniHook object from the recycling bin, if
@@ -1260,6 +1274,7 @@ static void S3JniDb__set_aside(JNIEnv * const env, S3JniDb * const s){
 static int S3JniEnv_uncache(JNIEnv * const env){
   struct S3JniEnv * row;
   struct S3JniEnv * pPrev = 0;
+
   S3JniEnv_mutex_assertLocked;
   row = SJG.envCache.aHead;
   for( ; row; pPrev = row, row = row->pNext ){
@@ -1296,26 +1311,13 @@ static int S3JniEnv_uncache(JNIEnv * const env){
 ** (2023-07-31) tests.
 */
 static S3JniNphClass * s3jni__nph(JNIEnv * const env, S3JniNphRef const* pRef){
-  /**
-   According to:
-
-     https://developer.ibm.com/articles/j-jni/
-
-     > ... the IDs returned for a given class don't change for the
-     lifetime of the JVM process. But the call to get the field or
-     method can require significant work in the JVM, because
-     fields and methods might have been inherited from
-     superclasses, making the JVM walk up the class hierarchy to
-     find them. Because the IDs are the same for a given class,
-     you should look them up once and then reuse them. Similarly,
-     looking up class objects can be expensive, so they should be
-     cached as well.
-  */
   S3JniNphClass * const pNC = &SJG.nph[pRef->index];
+
   assert( (void*)pRef>=(void*)&S3JniNphRefs && (void*)pRef<(void*)(&S3JniNphRefs + 1)
-          && "pRef is out of range." );
+          && "pRef is out of range" );
   assert( pRef->index>=0
-          && (pRef->index < (sizeof(S3JniNphRefs) / sizeof(S3JniNphRef))) );
+          && (pRef->index < (sizeof(S3JniNphRefs) / sizeof(S3JniNphRef)))
+          && "pRef->index is out of range" );
   if( !pNC->pRef ){
     S3JniNph_mutex_enter;
     if( !pNC->pRef ){
@@ -1410,7 +1412,7 @@ static void * NativePointerHolder__get(JNIEnv * env, jobject pObj,
 ** argument is a Java sqlite3 object, as this operation only has void
 ** pointers to work with.
 */
-#define PtrGet_T(T,OBJ) NativePointerHolder_get(OBJ, &S3JniNphRefs.T)
+#define PtrGet_T(T,OBJ) NativePointerHolder_get(OBJ, S3JniNph(T))
 #define PtrGet_sqlite3(OBJ) PtrGet_T(sqlite3, OBJ)
 #define PtrGet_sqlite3_stmt(OBJ) PtrGet_T(sqlite3_stmt, OBJ)
 #define PtrGet_sqlite3_value(OBJ) PtrGet_T(sqlite3_value, OBJ)
@@ -1528,7 +1530,7 @@ static int S3JniAutoExtension_init(JNIEnv *const env,
 static void OutputPointer_set_Bool(JNIEnv * const env, jobject const jOut,
                                     int v){
   (*env)->SetBooleanField(env, jOut, s3jni_nphop_field(
-                            env, &S3JniNphRefs.OutputPointer_Bool
+                            env, S3JniNph(OutputPointer_Bool)
                           ), v ? JNI_TRUE : JNI_FALSE );
   S3JniExceptionIsFatal("Cannot set OutputPointer.Bool.value");
 }
@@ -1540,7 +1542,7 @@ static void OutputPointer_set_Bool(JNIEnv * const env, jobject const jOut,
 static void OutputPointer_set_Int32(JNIEnv * const env, jobject const jOut,
                                     int v){
   (*env)->SetIntField(env, jOut, s3jni_nphop_field(
-                        env, &S3JniNphRefs.OutputPointer_Int32
+                        env, S3JniNph(OutputPointer_Int32)
                       ), (jint)v);
   S3JniExceptionIsFatal("Cannot set OutputPointer.Int32.value");
 }
@@ -1552,7 +1554,7 @@ static void OutputPointer_set_Int32(JNIEnv * const env, jobject const jOut,
 static void OutputPointer_set_Int64(JNIEnv * const env, jobject const jOut,
                                     jlong v){
   (*env)->SetLongField(env, jOut, s3jni_nphop_field(
-                         env, &S3JniNphRefs.OutputPointer_Int64
+                         env, S3JniNph(OutputPointer_Int64)
                        ), v);
   S3JniExceptionIsFatal("Cannot set OutputPointer.Int64.value");
 }
@@ -1575,7 +1577,7 @@ static void OutputPointer_set_obj(JNIEnv * const env,
 */
 static void OutputPointer_set_sqlite3(JNIEnv * const env, jobject const jOut,
                                       jobject jDb){
-  OutputPointer_set_obj(env, &S3JniNphRefs.OutputPointer_sqlite3, jOut, jDb);
+  OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3), jOut, jDb);
 }
 
 /*
@@ -1584,7 +1586,7 @@ static void OutputPointer_set_sqlite3(JNIEnv * const env, jobject const jOut,
 */
 static void OutputPointer_set_sqlite3_stmt(JNIEnv * const env, jobject const jOut,
                                            jobject jStmt){
-  OutputPointer_set_obj(env, &S3JniNphRefs.OutputPointer_sqlite3_stmt, jOut, jStmt);
+  OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_stmt), jOut, jStmt);
 }
 
 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
@@ -1594,7 +1596,7 @@ static void OutputPointer_set_sqlite3_stmt(JNIEnv * const env, jobject const jOu
 */
 static void OutputPointer_set_sqlite3_value(JNIEnv * const env, jobject const jOut,
                                             jobject jValue){
-  OutputPointer_set_obj(env, &S3JniNphRefs.OutputPointer_sqlite3_value, jOut, jValue);
+  OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_value), jOut, jValue);
 }
 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 
@@ -1606,7 +1608,7 @@ static void OutputPointer_set_sqlite3_value(JNIEnv * const env, jobject const jO
 */
 static void OutputPointer_set_ByteArray(JNIEnv * const env, jobject const jOut,
                                         jbyteArray const v){
-  OutputPointer_set_obj(env, &S3JniNphRefs.OutputPointer_ByteArray, jOut, v);
+  OutputPointer_set_obj(env, S3JniNph(OutputPointer_ByteArray), jOut, v);
 }
 #endif
 #endif /* SQLITE_ENABLE_FTS5 */
@@ -1617,7 +1619,7 @@ static void OutputPointer_set_ByteArray(JNIEnv * const env, jobject const jOut,
 */
 static void OutputPointer_set_String(JNIEnv * const env, jobject const jOut,
                                      jstring const v){
-  OutputPointer_set_obj(env, &S3JniNphRefs.OutputPointer_String, jOut, v);
+  OutputPointer_set_obj(env, S3JniNph(OutputPointer_String), jOut, v);
 }
 
 /*
@@ -1651,15 +1653,15 @@ static void ResultJavaValue_finalizer(void *v){
 
 
 /*
-** Returns a new Java instance of the class named by zClassName, which
+** Returns a new Java instance of the class referred to by pRef, which
 ** MUST be interface-compatible with NativePointerHolder and MUST have
 ** a no-arg constructor. The NativePointerHolder_set() method is
 ** passed the new Java object and pNative. Hypothetically returns NULL
 ** if Java fails to allocate, but the JNI docs are not entirely clear
 ** on that detail.
 **
-** Always use a static pointer from the S3JniNphRefs struct for the 2nd
-** argument so that we can use pRef->index as an O(1) cache key.
+** Always use a static pointer from the S3JniNphRefs struct for the
+** 2nd argument.
 */
 static jobject new_NativePointerHolder_object(JNIEnv * const env, S3JniNphRef const * pRef,
                                               const void * pNative){
@@ -1681,16 +1683,16 @@ static jobject new_NativePointerHolder_object(JNIEnv * const env, S3JniNphRef co
 }
 
 static inline jobject new_sqlite3_wrapper(JNIEnv * const env, sqlite3 *sv){
-  return new_NativePointerHolder_object(env, &S3JniNphRefs.sqlite3, sv);
+  return new_NativePointerHolder_object(env, S3JniNph(sqlite3), sv);
 }
 static inline jobject new_sqlite3_context_wrapper(JNIEnv * const env, sqlite3_context *sv){
-  return new_NativePointerHolder_object(env, &S3JniNphRefs.sqlite3_context, sv);
+  return new_NativePointerHolder_object(env, S3JniNph(sqlite3_context), sv);
 }
 static inline jobject new_sqlite3_stmt_wrapper(JNIEnv * const env, sqlite3_stmt *sv){
-  return new_NativePointerHolder_object(env, &S3JniNphRefs.sqlite3_stmt, sv);
+  return new_NativePointerHolder_object(env, S3JniNph(sqlite3_stmt), sv);
 }
 static inline jobject new_sqlite3_value_wrapper(JNIEnv * const env, sqlite3_value *sv){
-  return new_NativePointerHolder_object(env, &S3JniNphRefs.sqlite3_value, sv);
+  return new_NativePointerHolder_object(env, S3JniNph(sqlite3_value), sv);
 }
 
 /* Helper typedefs for UDF callback types. */
@@ -1815,7 +1817,7 @@ static int udf_args(JNIEnv *env,
   *jArgv = 0;
   if( !jcx ) goto error_oom;
   ja = (*env)->NewObjectArray(
-    env, argc, s3jni_nph(&S3JniNphRefs.sqlite3_value)->klazz,
+    env, argc, s3jni_nph(S3JniNph(sqlite3_value))->klazz,
     NULL);
   s3jni_oom_check( ja );
   if( !ja ) goto error_oom;
@@ -2117,7 +2119,7 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr,
   if( rc ){
     return rc;
   }
-  NativePointerHolder_set(&S3JniNphRefs.sqlite3, ps->jDb, pDb)
+  NativePointerHolder_set(S3JniNph(sqlite3), ps->jDb, pDb)
     /* As of here, the Java/C connection is complete except for the
        (temporary) lack of finalizer for the ps object. */;
   ps->pDb = pDb;
@@ -2156,7 +2158,7 @@ S3JniApi(sqlite3_auto_extension(),jint,1auto_1extension)(
   JniArgsEnvClass, jobject jAutoExt
 ){
   int i;
-  S3JniAutoExtension * ax;
+  S3JniAutoExtension * ax = 0;
   int rc = 0;
 
   if( !jAutoExt ) return SQLITE_MISUSE;
@@ -2336,7 +2338,7 @@ static int s3jni_busy_handler(void* pState, int n){
                                hook.midCallback, (jint)n);
     S3JniIfThrew{
       S3JniExceptionWarnCallbackThrew("sqlite3_busy_handler() callback");
-      rc = s3jni_db_exception(ps, SQLITE_ERROR,
+      rc = s3jni_db_exception(ps->pDb, SQLITE_ERROR,
                               "sqlite3_busy_handler() callback threw.");
     }
     S3JniHook_localundup(hook);
@@ -2440,7 +2442,7 @@ static jint s3jni_close_db(JNIEnv * const env, jobject jDb, int version){
       ? (jint)sqlite3_close(ps->pDb)
       : (jint)sqlite3_close_v2(ps->pDb);
     if( 0==rc ){
-      NativePointerHolder_set(&S3JniNphRefs.sqlite3, jDb, 0);
+      NativePointerHolder_set(S3JniNph(sqlite3), jDb, 0);
     }
   }
   return (jint)rc;
@@ -2529,7 +2531,7 @@ S3JniApi(sqlite3_collation_needed(),jint,1collation_1needed)(
     );
     S3JniUnrefLocal(klazz);
     S3JniIfThrew {
-      rc = s3jni_db_exception(ps, SQLITE_MISUSE,
+      rc = s3jni_db_exception(ps->pDb, SQLITE_MISUSE,
                               "Cannot not find matching call() in "
                               "CollationNeededCallback object.");
     }else{
@@ -2574,7 +2576,7 @@ S3JniApi(sqlite3_column_int64(),jlong,1column_1int64)(
   return (jlong)sqlite3_column_int64(PtrGet_sqlite3_stmt(jpStmt), (int)ndx);
 }
 
-S3JniApi(sqlite3_column_text(),jbyteArray,1column_1text_1utf8)(
+S3JniApi(sqlite3_column_text(),jbyteArray,1column_1text)(
   JniArgsEnvClass, jobject jpStmt, jint ndx
 ){
   sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt);
@@ -2583,6 +2585,9 @@ S3JniApi(sqlite3_column_text(),jbyteArray,1column_1text_1utf8)(
   return p ? s3jni_new_jbyteArray(p, n) : NULL;
 }
 
+#if 0
+// this impl might prove useful, but we'd need to publish the
+// bytearray-returning impl with a different name.
 S3JniApi(sqlite3_column_text(),jstring,1column_1text)(
   JniArgsEnvClass, jobject jpStmt, jint ndx
 ){
@@ -2591,6 +2596,7 @@ S3JniApi(sqlite3_column_text(),jstring,1column_1text)(
   const unsigned char * const p = sqlite3_column_text(stmt, (int)ndx);
   return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0;
 }
+#endif
 
 S3JniApi(sqlite3_column_text16(),jstring,1column_1text16)(
   JniArgsEnvClass, jobject jpStmt, jint ndx
@@ -2610,7 +2616,7 @@ S3JniApi(sqlite3_column_value(),jobject,1column_1value)(
 }
 
 /*
-** Impl for both commit hooks (if isCommit is true) or rollback hooks.
+** Impl for commit hooks (if isCommit is true) or rollback hooks.
 */
 static int s3jni_commit_rollback_hook_impl(int isCommit, S3JniDb * const ps){
   S3JniDeclLocal_env;
@@ -2625,8 +2631,7 @@ static int s3jni_commit_rollback_hook_impl(int isCommit, S3JniDb * const ps){
       ? (int)(*env)->CallIntMethod(env, hook.jObj, hook.midCallback)
       : (int)((*env)->CallVoidMethod(env, hook.jObj, hook.midCallback), 0);
     S3JniIfThrew{
-      S3JniExceptionClear;
-      rc = s3jni_db_error(ps->pDb, SQLITE_ERROR, "hook callback threw.");
+      rc = s3jni_db_exception(ps->pDb, SQLITE_ERROR, "hook callback threw");
     }
     S3JniHook_localundup(hook);
   }
@@ -3159,7 +3164,7 @@ S3JniApi(sqlite3_finalize(),jint,1finalize)(
   sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt);
   if( pStmt ){
     rc = sqlite3_finalize(pStmt);
-    NativePointerHolder_set(&S3JniNphRefs.sqlite3_stmt, jpStmt, 0);
+    NativePointerHolder_set(S3JniNph(sqlite3_stmt), jpStmt, 0);
   }
   return rc;
 }
@@ -3283,7 +3288,7 @@ static int s3jni_open_post(JNIEnv * const env, S3JniEnv * const jc,
     assert(ps->jDb);
     if( 0==ps->pDb ){
       ps->pDb = *ppDb;
-      NativePointerHolder_set(&S3JniNphRefs.sqlite3, ps->jDb, *ppDb);
+      NativePointerHolder_set(S3JniNph(sqlite3), ps->jDb, *ppDb);
     }else{
       assert( ps->pDb==*ppDb
               && "Set up via s3jni_run_java_auto_extensions()" );
@@ -3390,7 +3395,7 @@ end:
       OutputPointer_set_Int32(env, outTail, (int)(zTail ? (zTail - (const char *)pBuf) : 0));
     }
     if( pStmt ){
-      NativePointerHolder_set(&S3JniNphRefs.sqlite3_stmt, jStmt, pStmt);
+      NativePointerHolder_set(S3JniNph(sqlite3_stmt), jStmt, pStmt);
     }else{
       /* Happens for comments and whitespace. */
       S3JniUnrefLocal(jStmt);
@@ -3473,7 +3478,7 @@ static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId,
                            (jint)opId, jDbName, jTable, (jlong)iKey1);
     S3JniIfThrew{
       S3JniExceptionWarnCallbackThrew("sqlite3_(pre)update_hook() callback");
-      s3jni_db_exception(ps, 0,
+      s3jni_db_exception(ps->pDb, 0,
                          "sqlite3_(pre)update_hook() callback threw");
     }
   }
@@ -3644,7 +3649,7 @@ static int s3jni_progress_handler_impl(void *pP){
   if( hook.jObj ){
     rc = (int)(*env)->CallIntMethod(env, hook.jObj, hook.midCallback);
     S3JniIfThrew{
-      rc = s3jni_db_exception(ps, rc,
+      rc = s3jni_db_exception(ps->pDb, rc,
                               "sqlite3_progress_handler() callback threw");
     }
     S3JniHook_localundup(hook);
@@ -3940,7 +3945,7 @@ int s3jni_xAuth(void* pState, int op,const char*z0, const char*z1,
     rc = (*env)->CallIntMethod(env, hook.jObj, hook.midCallback, (jint)op,
                                s0, s1, s3, s3);
     S3JniIfThrew{
-      rc = s3jni_db_exception(ps, rc, "sqlite3_set_authorizer() callback");
+      rc = s3jni_db_exception(ps->pDb, rc, "sqlite3_set_authorizer() callback");
     }
     S3JniUnrefLocal(s0);
     S3JniUnrefLocal(s1);
@@ -4215,7 +4220,7 @@ static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){
     case SQLITE_TRACE_ROW:
       break;
     case SQLITE_TRACE_CLOSE:
-      jP = ps->jDb;
+      jP = jPUnref = S3JniRefLocal(ps->jDb);
       break;
     default:
       assert(!"cannot happen - unkown trace flag");
@@ -4234,7 +4239,7 @@ static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){
       rc = (int)(*env)->CallIntMethod(env, hook.jObj, hook.midCallback,
                                       (jint)traceflag, jP, jX);
       S3JniIfThrew{
-        rc = s3jni_db_exception(ps, SQLITE_ERROR,
+        rc = s3jni_db_exception(ps->pDb, SQLITE_ERROR,
                                 "sqlite3_trace_v2() callback threw.");
       }
     }
@@ -4364,7 +4369,7 @@ S3JniApi(sqlite3_value_java_object(),jobject,1value_1java_1object)(
                                ResultJavaValuePtrStr);
 }
 
-S3JniApi(sqlite3_value_text_utf8(),jbyteArray,1value_1text_1utf8)(
+S3JniApi(sqlite3_value_text(),jbyteArray,1value_1text)(
   JniArgsEnvClass, jobject jpSVal
 ){
   sqlite3_value * const sv = PtrGet_sqlite3_value(jpSVal);
@@ -4373,6 +4378,9 @@ S3JniApi(sqlite3_value_text_utf8(),jbyteArray,1value_1text_1utf8)(
   return p ? s3jni_new_jbyteArray(p, n) : 0;
 }
 
+#if 0
+// this impl might prove useful, but we'd need to publish the
+// bytearray-returning impl with a different name.
 S3JniApi(sqlite3_value_text(),jstring,1value_1text)(
   JniArgsEnvClass, jobject jpSVal
 ){
@@ -4381,6 +4389,7 @@ S3JniApi(sqlite3_value_text(),jstring,1value_1text)(
   const unsigned char * const p = sqlite3_value_text(sv);
   return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0;
 }
+#endif
 
 S3JniApi(sqlite3_value_text16(),jstring,1value_1text16)(
   JniArgsEnvClass, jobject jpSVal
@@ -4483,10 +4492,10 @@ JniDecl(void,1jni_1internal_1details)(JniArgsEnvClass){
   JNIEXPORT ReturnType JNICALL                  \
   JniFuncNameFtsTok(Suffix)
 
-#define PtrGet_fts5_api(OBJ) NativePointerHolder_get(OBJ,&S3JniNphRefs.fts5_api)
-#define PtrGet_fts5_tokenizer(OBJ) NativePointerHolder_get(OBJ,&S3JniNphRefs.fts5_tokenizer)
-#define PtrGet_Fts5Context(OBJ) NativePointerHolder_get(OBJ,&S3JniNphRefs.Fts5Context)
-#define PtrGet_Fts5Tokenizer(OBJ) NativePointerHolder_get(OBJ,&S3JniNphRefs.Fts5Tokenizer)
+#define PtrGet_fts5_api(OBJ) NativePointerHolder_get(OBJ,S3JniNph(fts5_api))
+#define PtrGet_fts5_tokenizer(OBJ) NativePointerHolder_get(OBJ,S3JniNph(fts5_tokenizer))
+#define PtrGet_Fts5Context(OBJ) NativePointerHolder_get(OBJ,S3JniNph(Fts5Context))
+#define PtrGet_Fts5Tokenizer(OBJ) NativePointerHolder_get(OBJ,S3JniNph(Fts5Tokenizer))
 #define Fts5ExtDecl Fts5ExtensionApi const * const fext = s3jni_ftsext()
 
 /**
@@ -4548,10 +4557,10 @@ static inline Fts5ExtensionApi const * s3jni_ftsext(void){
 }
 
 static inline jobject new_Fts5Context_wrapper(JNIEnv * const env, Fts5Context *sv){
-  return new_NativePointerHolder_object(env, &S3JniNphRefs.Fts5Context, sv);
+  return new_NativePointerHolder_object(env, S3JniNph(Fts5Context), sv);
 }
 static inline jobject new_fts5_api_wrapper(JNIEnv * const env, fts5_api *sv){
-  return new_NativePointerHolder_object(env, &S3JniNphRefs.fts5_api, sv);
+  return new_NativePointerHolder_object(env, S3JniNph(fts5_api), sv);
 }
 
 /*
@@ -4561,7 +4570,7 @@ static inline jobject new_fts5_api_wrapper(JNIEnv * const env, fts5_api *sv){
 static jobject s3jni_getFts5ExensionApi(JNIEnv * const env){
   if( !SJG.fts5.jFtsExt ){
     jobject pNPH = new_NativePointerHolder_object(
-      env, &S3JniNphRefs.Fts5ExtensionApi, s3jni_ftsext()
+      env, S3JniNph(Fts5ExtensionApi), s3jni_ftsext()
     );
     S3JniEnv_mutex_enter;
     if( pNPH ){
@@ -5016,11 +5025,11 @@ static jint s3jni_fts5_xTokenize(JniArgsEnvObj, S3JniNphRef const *pRef,
   s.tok.jba = S3JniRefLocal(jbaText);
   s.tok.zPrev = (const char *)pText;
   s.tok.nPrev = (int)nText;
-  if( pRef == &S3JniNphRefs.Fts5ExtensionApi ){
+  if( pRef == S3JniNph(Fts5ExtensionApi) ){
     rc = fext->xTokenize(PtrGet_Fts5Context(jFcx),
                          (const char *)pText, (int)nText,
                          &s, s3jni_xTokenize_xToken);
-  }else if( pRef == &S3JniNphRefs.fts5_tokenizer ){
+  }else if( pRef == S3JniNph(fts5_tokenizer) ){
     fts5_tokenizer * const pTok = PtrGet_fts5_tokenizer(jSelf);
     rc = pTok->xTokenize(PtrGet_Fts5Tokenizer(jFcx), &s, tokFlags,
                          (const char *)pText, (int)nText,
@@ -5038,13 +5047,13 @@ static jint s3jni_fts5_xTokenize(JniArgsEnvObj, S3JniNphRef const *pRef,
 
 JniDeclFtsXA(jint,xTokenize)(JniArgsEnvObj,jobject jFcx, jbyteArray jbaText,
                              jobject jCallback){
-  return s3jni_fts5_xTokenize(env, jSelf, &S3JniNphRefs.Fts5ExtensionApi,
+  return s3jni_fts5_xTokenize(env, jSelf, S3JniNph(Fts5ExtensionApi),
                               0, jFcx, jbaText, jCallback);
 }
 
 JniDeclFtsTok(jint,xTokenize)(JniArgsEnvObj,jobject jFcx, jint tokFlags,
                               jbyteArray jbaText, jobject jCallback){
-  return s3jni_fts5_xTokenize(env, jSelf, &S3JniNphRefs.Fts5Tokenizer,
+  return s3jni_fts5_xTokenize(env, jSelf, S3JniNph(Fts5Tokenizer),
                               tokFlags, jFcx, jbaText, jCallback);
 }
 
@@ -5337,5 +5346,5 @@ Java_org_sqlite_jni_SQLite3Jni_init(JniArgsEnvClass){
 
   sqlite3_shutdown()
     /* So that it becomes legal for Java-level code to call
-    ** sqlite3_config(), if it's ever implemented. */;
+    ** sqlite3_config(). */;
 }
index 1c9e4a641c98582375ad189f8249789d322ec5b1..754d57063f381c31a5cca70362ec508c0423a216 100644 (file)
@@ -1059,20 +1059,12 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1origin
 JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1table_1name
   (JNIEnv *, jclass, jobject, jint);
 
-/*
- * Class:     org_sqlite_jni_SQLite3Jni
- * Method:    sqlite3_column_text_utf8
- * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text_1utf8
-  (JNIEnv *, jclass, jobject, jint);
-
 /*
  * Class:     org_sqlite_jni_SQLite3Jni
  * Method:    sqlite3_column_text
- * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)Ljava/lang/String;
+ * Signature: (Lorg/sqlite/jni/sqlite3_stmt;I)[B
  */
-JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text
+JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1column_1text
   (JNIEnv *, jclass, jobject, jint);
 
 /*
@@ -1851,20 +1843,12 @@ JNIEXPORT jlong JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1int64
 JNIEXPORT jobject JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1java_1object
   (JNIEnv *, jclass, jobject);
 
-/*
- * Class:     org_sqlite_jni_SQLite3Jni
- * Method:    sqlite3_value_text_utf8
- * Signature: (Lorg/sqlite/jni/sqlite3_value;)[B
- */
-JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text_1utf8
-  (JNIEnv *, jclass, jobject);
-
 /*
  * Class:     org_sqlite_jni_SQLite3Jni
  * Method:    sqlite3_value_text
- * Signature: (Lorg/sqlite/jni/sqlite3_value;)Ljava/lang/String;
+ * Signature: (Lorg/sqlite/jni/sqlite3_value;)[B
  */
-JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text
+JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1text
   (JNIEnv *, jclass, jobject);
 
 /*
index e6eafa0bef8666d9c12d88256748d1a329066d28..9225e4828107d0bbf30e07221d5ee037524bf5e5 100644 (file)
@@ -416,24 +416,13 @@ public final class SQLite3Jni {
   );
 
   /**
-     Returns the given column's contents as UTF-8-encoded (not MUTF-8)
-     text. Returns null if the C-level sqlite3_column_text() returns
-     NULL.
-
-     @see #sqlite3_column_text
-  */
-  @Canonical(cname="sqlite3_column_text")
-  public static native byte[] sqlite3_column_text_utf8(
-    @NotNull sqlite3_stmt stmt, int ndx
-  );
-
-  /**
-     Provides the same feature as the same-named C API but returns the
-     text in Java-native encoding rather than the C API's UTF-8.
-
-     @see #sqlite3_column_text16
+     Functions identially to the C API, and this note is just to
+     stress that the returned bytes are encoded as UTF-8. It returns
+     null if the underlying C-level sqlite3_column_text() returns NULL
+     or on allocation error.
   */
-  public static native String sqlite3_column_text(
+  @Canonical
+  public static native byte[] sqlite3_column_text(
     @NotNull sqlite3_stmt stmt, int ndx
   );
 
@@ -471,7 +460,7 @@ public final class SQLite3Jni {
   //       }
   //       case SQLITE_FLOAT: rv = new Double(sqlite3_value_double(v)); break;
   //       case SQLITE_BLOB: rv = sqlite3_value_blob(v); break;
-  //       case SQLITE_TEXT: rv = sqlite3_value_text(v); break;
+  //       case SQLITE_TEXT: rv = sqlite3_value_text16(v); break;
   //       default: break;
   //     }
   //   }
@@ -1172,6 +1161,10 @@ public final class SQLite3Jni {
     @NotNull sqlite3_context cx, long n
   );
 
+  /**
+     This overload is private because its final parameter is arguably
+     unnecessary in Java.
+  */
   @Canonical
   private static native void sqlite3_result_blob(
     @NotNull sqlite3_context cx, @Nullable byte[] blob, int maxLen
@@ -1195,8 +1188,11 @@ public final class SQLite3Jni {
 
      </ul>
 
-     If @param maxLen is larger than blob.length, it is truncated to
-     that value. If it is negative, results are undefined.
+     <p>If @param maxLen is larger than blob.length, it is truncated
+     to that value. If it is negative, results are undefined.</p>
+
+     <p>This overload is private because its final parameter is
+     arguably unnecessary in Java.</p>
   */
   @Canonical
   private static native void sqlite3_result_blob64(
@@ -1209,6 +1205,10 @@ public final class SQLite3Jni {
     sqlite3_result_blob64(cx, blob, (long)(null==blob ? 0 : blob.length));
   }
 
+  /**
+     This overload is private because its final parameter is
+     arguably unnecessary in Java.
+  */
   @Canonical
   private static native void sqlite3_result_text(
     @NotNull sqlite3_context cx, @Nullable byte[] utf8, int maxLen
@@ -1249,6 +1249,9 @@ public final class SQLite3Jni {
      text.length, it is silently truncated to text.length. If it is
      negative, results are undefined. If text is null, the subsequent
      arguments are ignored.
+
+     This overload is private because its maxLength parameter is
+     arguably unnecessary in Java.
   */
   @Canonical
   private static native void sqlite3_result_text64(
@@ -1342,6 +1345,13 @@ public final class SQLite3Jni {
   /**
      Internal impl of the public sqlite3_strglob() method. Neither
      argument may be NULL and both MUST be NUL-terminated UTF-8.
+
+     This overload is private because: (A) to keep users from
+     inadvertently passing non-NUL-terminated byte arrays (an easy
+     thing to do). (B) it is cheaper to NUL-terminate the
+     String-to-byte-array conversion in the Java implementation
+     (sqlite3_strglob(String,String)) than to do that in C, so that
+     signature is the public-facing one.
   */
   @Canonical
   private static native int sqlite3_strglob(
@@ -1358,8 +1368,7 @@ public final class SQLite3Jni {
   }
 
   /**
-     Internal impl of the public sqlite3_strlike() method. Neither
-     argument may be NULL and both MUST be NUL-terminated UTF-8.
+     The LIKE counterpart of the private sqlite3_strglob() method.
   */
   @Canonical
   private static native int sqlite3_strlike(
@@ -1502,30 +1511,14 @@ public final class SQLite3Jni {
   }
 
   /**
-     Returns the given value as UTF-8-encoded bytes, or null if the
-     underlying C-level sqlite3_value_text() returns NULL.
+     Functions identially to the C API, and this note is just to
+     stress that the returned bytes are encoded as UTF-8. It returns
+     null if the underlying C-level sqlite3_value_text() returns NULL
+     or on allocation error.
   */
-  @Canonical(cname="sqlite3_value_text",
-             comment="Renamed because its String-returning overload would "+
-             "otherwise be ambiguous.")
-  public static native byte[] sqlite3_value_text_utf8(@NotNull sqlite3_value v);
-
-  /**
-     Provides the same feature as the same-named C API but returns the
-     text in Java-native encoding rather than the C API's UTF-8.
-
-     @see #sqlite3_value_text16
-  */
-  public static native String sqlite3_value_text(@NotNull sqlite3_value v);
+  @Canonical
+  public static native byte[] sqlite3_value_text(@NotNull sqlite3_value v);
 
-  /**
-     In the Java layer, sqlite3_value_text() and
-     sqlite3_value_text16() are functionally equivalent, the
-     difference being only where the encoding to UTF-16 (if necessary)
-     takes place. This function does it via SQLite and
-     sqlite3_value_text() fetches UTF-8 (SQLite's default encoding)
-     and converts it to UTF-16 in Java.
-  */
   @Canonical
   public static native String sqlite3_value_text16(@NotNull sqlite3_value v);
 
index 5d3623f677aadef9b8c36d241d8703018f405f5f..ce8eb6bd23c7732dede2f263977c200cf1cb71b0 100644 (file)
@@ -453,9 +453,14 @@ public class Tester1 implements Runnable {
       final sqlite3_value sv = sqlite3_value_dup(sqlite3_column_value(stmt,0));
       final String txt = sqlite3_column_text16(stmt, 0);
       sbuf.append( txt );
-      affirm( txt.equals(sqlite3_column_text(stmt, 0)) );
+      affirm( txt.equals(new String(
+                           sqlite3_column_text(stmt, 0),
+                           StandardCharsets.UTF_8
+                         )) );
       affirm( txt.length() < sqlite3_value_bytes(sv) );
-      affirm( txt.equals(sqlite3_value_text(sv)) );
+      affirm( txt.equals(new String(
+                           sqlite3_value_text(sv),
+                           StandardCharsets.UTF_8)) );
       affirm( txt.length() == sqlite3_value_bytes16(sv)/2 );
       affirm( txt.equals(sqlite3_value_text16(sv)) );
       sqlite3_value_free(sv);
@@ -464,6 +469,20 @@ public class Tester1 implements Runnable {
     sqlite3_finalize(stmt);
     affirm(3 == n);
     affirm("w😃rldhell🤩!🤩".equals(sbuf.toString()));
+
+    stmt = prepare(db, "SELECT ?, ?");
+    rc = sqlite3_bind_text(stmt, 1, "");
+    affirm( 0==rc );
+    rc = sqlite3_bind_text(stmt, 2, (String)null);
+    affirm( 0==rc );
+    rc = sqlite3_step(stmt);
+    affirm( SQLITE_ROW==rc );
+    byte[] colBa = sqlite3_column_text(stmt, 0);
+    affirm( 0==colBa.length );
+    colBa = sqlite3_column_text(stmt, 1);
+    affirm( null==colBa );
+    sqlite3_finalize(stmt);
+
     sqlite3_close_v2(db);
   }
 
index feb6d6303d3b25c27f03adbacdd54c46ec5dab76..70c8e255d2eee18e8e153624f702d4cc33d9e278 100644 (file)
@@ -50,7 +50,7 @@ public class TesterFts5 {
               int rc = ext.xColumnText(fCx, i, op);
               affirm( 0 == rc );
               final String val = op.value;
-              affirm( val.equals(sqlite3_value_text(argv[i])) );
+              affirm( val.equals(sqlite3_value_text16(argv[i])) );
               //outln("xFunction col "+i+": "+val);
             }
           }
index 80164a4dda804155d7b38c8b54b5c3506f85233a..24b0f82d4c6a4fac922061bb8242ef053beb7f9b 100644 (file)
@@ -7,35 +7,22 @@ package org.sqlite.jni.annotation;
    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. The Java API adds a
-   number of overloads to simplify use, as well as a few Java-specific
-   functions, and those are never flagged as @Canonical.
+   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. The Java API adds a number of 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>In rare cases, the Java interface for a canonical function has a
-   different name than its C counterpart. For such cases,
-   (cname=the-C-side-name) is passed to this annotation and a
-   Java-side implementation with a slightly different signature is
-   added with the canonical name. As of this writing, that applies
-   only to {@link org.sqlite.jni.SQLite3Jni#sqlite3_value_text_utf8}
-   and {@link org.sqlite.jni.SQLite3Jni#sqlite3_column_text_utf8}.
-
    <p>The comment property can be used to add a comment.
 */
 @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{
-  /**
-     Java functions which directly map to a canonical function but
-     change its name for some reason should not the original name
-     in this property.
-  */
-  String cname() default ""/*doesn't allow null*/;
   /**
      Brief comments about the binding, e.g. noting any major
      semantic differences.
index 85245e43d14f731f5d635ffcfb9cc86959e0d45d..e8040dc975688126935d5897baec5d72aba4bb1a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\ssome\snewly-dead\scode.
-D 2023-09-01T10:37:15.903
+C Make\sJNI\sinterfaces\sof\ssqlite3_column/value_text()\smatch\sthe\sC\sones\sbetter.\sInternal\sJNI\scleanups\sand\ssimplifications.
+D 2023-09-01T13:27:59.308
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -234,11 +234,11 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c
 F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9
 F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282
 F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8
-F ext/jni/GNUmakefile 591d05030e7fa787615d88fb5b7e8377e1e777612fce4d4eed9b595843f1d014
+F ext/jni/GNUmakefile bcf386da9510e45034d90b2f7b91ab51adcd2db9e080f3900a1e63caf5999659
 F ext/jni/README.md 1332b1fa27918bd5d9ca2d0d4f3ac3a6ab86b9e3699dc5bfe32904a027f3d2a9
 F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa
-F ext/jni/src/c/sqlite3-jni.c 69a78f7f7b94b58e272184d005813322bad24ed78ea392563b657faa3cc56218
-F ext/jni/src/c/sqlite3-jni.h 383a357c8920e05ea2b6ca7f9548ee04a263319f018ef3daeeaa719727be8b72
+F ext/jni/src/c/sqlite3-jni.c 2da08d92d1cd858353071a2559a260333425e87a79f3da09d85f07f35930a573
+F ext/jni/src/c/sqlite3-jni.h c22f0189254abe26fad3ba132b484785b19a1aa96d34d30d7d8c5ffe6a9b25d1
 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/AuthorizerCallback.java e6135be32f12bf140bffa39be7fd1a45ad83b2661ed49c08dbde04c8485feb38
@@ -262,17 +262,17 @@ F ext/jni/src/org/sqlite/jni/ProgressHandlerCallback.java 7b9ff2218129ece98ba60c
 F ext/jni/src/org/sqlite/jni/ResultCode.java ba701f20213a5f259e94cfbfdd36eb7ac7ce7797f2c6c7fca2004ff12ce20f86
 F ext/jni/src/org/sqlite/jni/RollbackHookCallback.java d12352c0e22840de484ffa9b11ed5058bb0daca2e9f218055d3c54c947a273c4
 F ext/jni/src/org/sqlite/jni/SQLFunction.java 544a875d33fd160467d82e2397ac33157b29971d715a821a4fad3c899113ee8c
-F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 5a05c67b994d3f431d61203ab1de842d49491714e78cf99ccd5aa5257b66e9ff
+F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 35ead9802bf3b16f9afba663ac73f629b3ebdc5cacad151f38403daee9f1e6b0
 F ext/jni/src/org/sqlite/jni/ScalarFunction.java 6d387bb499fbe3bc13c53315335233dbf6a0c711e8fa7c521683219b041c614c
 F ext/jni/src/org/sqlite/jni/TableColumnMetadata.java 54511b4297fa28dcb3f49b24035e34ced10e3fd44fd0e458e784f4d6b0096dab
-F ext/jni/src/org/sqlite/jni/Tester1.java 95fd3d3c0068cd7ebf2e89bb7db16fba541e6cf872f64f08c1e1350f6585682b
-F ext/jni/src/org/sqlite/jni/TesterFts5.java 6f135c60e24c89e8eecb9fe61dde0f3bb2906de668ca6c9186bcf34bdaf94629
+F ext/jni/src/org/sqlite/jni/Tester1.java d4ab6f3f83cbb96e763dd4feb6e5527864d9957eb5e79259bfbe57dcf6d0103e
+F ext/jni/src/org/sqlite/jni/TesterFts5.java 02b59ea7d75666fd565d90bb8dc7b0c09441bb9d1af091fad9f6d7377297a474
 F ext/jni/src/org/sqlite/jni/TraceV2Callback.java beb0b064c1a5f8bfe585a324ed39a4e33edbe379a3fc60f1401661620d3ca7c0
 F ext/jni/src/org/sqlite/jni/UpdateHookCallback.java 8376f4a931f2d5612b295c003c9515ba933ee76d8f95610e89c339727376e36c
 F ext/jni/src/org/sqlite/jni/ValueHolder.java f022873abaabf64f3dd71ab0d6037c6e71cece3b8819fa10bf26a5461dc973ee
 F ext/jni/src/org/sqlite/jni/WindowFunction.java 488980f4dbb6bdd7067d6cb9c43e4075475e51c54d9b74a5834422654b126246
 F ext/jni/src/org/sqlite/jni/XDestroyCallback.java 50c5ca124ef6c6b735a7e136e7a23a557be367e61b56d4aab5777a614ab46cc2
-F ext/jni/src/org/sqlite/jni/annotation/Canonical.java ff9fc59004303d8ef89c516ede9ef5f51c881e9c9ba982f0ebb1bdd9a18550bc
+F ext/jni/src/org/sqlite/jni/annotation/Canonical.java d9ff79f1bf9d063d0c3e3b768ec7df15f51e4ca51a5bb291d33b7a6ea9a24f3a
 F ext/jni/src/org/sqlite/jni/annotation/NotNull.java d48ebd7ae6bbb78bd47d54431c85e1521c89b1d3864a2b6eafd9c0e1b2341457
 F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 6f962a98c9a5c6e9d21c50ae8716b16bdfdc934a191608cbb7e12ea588ddb6af
 F ext/jni/src/org/sqlite/jni/annotation/package-info.java f66bfb621c6494e67c03ed38a9e26a3bd6af99b9f9f6ef79556bcec30a025a22
@@ -2116,8 +2116,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 5fe5b0a585dbfa06cfca1fea40aea5ea3ccfe8295f41306ad2d5b851ace27203
-R e68a872b68a0b0146fb6e1b06b988d94
+P dc0fa76b395c5e352116dc33cc1b455e5e9c9f01c285af52ccba4d37e4453b87
+R 8eeecadbd0aad723daa22691fc77aaf3
 U stephan
-Z 2904ef85d8a184bf73f88a40f15d384b
+Z 2c93c72b42f574b692bce8cc766cb46c
 # Remove this line to create a well-formed Fossil manifest.
index 1740a09513daa54b104477ee8fa218c0f1b13747..f6e2e419ea59156c5459b5d25a10541519b88399 100644 (file)
@@ -1 +1 @@
-dc0fa76b395c5e352116dc33cc1b455e5e9c9f01c285af52ccba4d37e4453b87
\ No newline at end of file
+eb24f97253d9c8e7c728c2ac67a0824b10ca67362ac4f8abb94d5d3c54c58c5b
\ No newline at end of file