]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More code legibility and style improvements in the JNI pieces. Start work on a javado...
authorstephan <stephan@noemail.net>
Thu, 24 Aug 2023 18:43:25 +0000 (18:43 +0000)
committerstephan <stephan@noemail.net>
Thu, 24 Aug 2023 18:43:25 +0000 (18:43 +0000)
FossilOrigin-Name: 62b404d62fd62f4d220838b59c9f38a71afa2d4a8c3af0a5c9495fa7020972cf

ext/jni/GNUmakefile
ext/jni/src/c/sqlite3-jni.c
ext/jni/src/c/sqlite3-jni.h
ext/jni/src/org/sqlite/jni/SQLFunction.java
ext/jni/src/org/sqlite/jni/SQLite3Jni.java
ext/jni/src/org/sqlite/jni/Tester1.java
ext/jni/src/org/sqlite/jni/package-info.java [new file with mode: 0644]
ext/jni/src/org/sqlite/jni/tester/SQLTester.java
manifest
manifest.uuid

index e3dfb53c1d3d86ee0c53234437980390129b81d5..a6711043fc4c02cf276efcfb58185fecd99ec37f 100644 (file)
@@ -6,9 +6,10 @@ JAVA_HOME ?= $(HOME)/jdk/current
 # 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
@@ -17,18 +18,18 @@ $(MAKEFILE):
 
 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)
@@ -285,6 +286,12 @@ $(package.jar): $(CLASS_FILES) $(MAKEFILE) $(package.jar.in)
 
 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 def5f813fb8ddbc7148a19f1e4ed435f2dbac9d8..c62aa1765a699a22252567741c6c734acd036f8b 100644 (file)
@@ -297,7 +297,7 @@ enum {
   ** 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)
 };
 
 /*
@@ -318,12 +318,16 @@ struct S3JniNphClass {
                               **  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. */
 };
 
 /*
@@ -433,10 +437,11 @@ struct S3JniGlobalType {
   **   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.
   */
@@ -542,47 +547,47 @@ static void s3jni_incr( volatile unsigned int * const p ){
 #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 )
@@ -612,12 +617,12 @@ static void * s3jni_malloc(JNIEnv * const env, size_t n){
 */
 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;
     }
   }
@@ -637,7 +642,7 @@ static S3JniEnv * S3JniGlobal_env_cache(JNIEnv * const env){
   SJG.envCache.aHead = row;
   row->env = env;
 
-  MUTEX_ENV_LEAVE;
+  S3JniMutex_Env_leave;
   return row;
 }
 
@@ -897,7 +902,7 @@ static void S3JniHook_unref(JNIEnv * const env, S3JniHook * const s, int doXDest
 */
 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);
@@ -927,7 +932,7 @@ static void S3JniDb_set_aside(JNIEnv * env, S3JniDb * const s){
     s->pNext = SJG.perDb.aFree;
     if(s->pNext) s->pNext->pPrev = s;
     SJG.perDb.aFree = s;
-    MUTEX_PDB_LEAVE;
+    S3JniMutex_Pdb_leave;
   }
 }
 
@@ -938,7 +943,7 @@ static void S3JniDb_set_aside(JNIEnv * env, S3JniDb * const s){
 */
 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 ){
@@ -967,7 +972,7 @@ static int S3JniGlobal_env_uncache(JNIEnv * const 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.
@@ -989,15 +994,17 @@ static S3JniNphClass * S3JniGlobal_nph_cache(JNIEnv * const env, S3NphRef const*
      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;
 }
@@ -1009,12 +1016,12 @@ static S3JniNphClass * S3JniGlobal_nph_cache(JNIEnv * const env, S3NphRef const*
 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;
 }
@@ -1057,7 +1064,7 @@ static void * NativePointerHolder_get(JNIEnv * env, jobject pObj, S3NphRef const
 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;
@@ -1088,7 +1095,7 @@ static S3JniDb * S3JniDb_alloc(JNIEnv * const env, sqlite3 *pDb,
     rv->jDb = REF_G(jDb);
     rv->pDb = pDb;
   }
-  MUTEX_PDB_LEAVE;
+  S3JniMutex_Pdb_leave;
   return rv;
 }
 
@@ -1106,7 +1113,7 @@ static S3JniDb * S3JniDb_alloc(JNIEnv * const env, sqlite3 *pDb,
 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 );
@@ -1117,7 +1124,7 @@ static S3JniDb * S3JniDb_for_db(JNIEnv * const env, jobject jDb, sqlite3 *pDb){
         break;
       }
     }
-    MUTEX_PDB_LEAVE;
+    S3JniMutex_Pdb_leave;
   }
   return s;
 }
@@ -1183,12 +1190,12 @@ static int udf_setAggregateContext(JNIEnv * env, jobject jCx,
   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 ){
@@ -1218,12 +1225,12 @@ static jfieldID setupOutputPointer(JNIEnv * const env, S3NphRef const * pRef,
                                    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;
 }
@@ -1430,12 +1437,12 @@ static jobject new_NativePointerHolder_object(JNIEnv * const env, S3NphRef const
   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.");
@@ -1855,14 +1862,14 @@ static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr,
       ** 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);
@@ -1890,12 +1897,12 @@ S3JniApi(sqlite3_auto_extension(),jint,1auto_1extension)(
   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. */;
     }
   }
@@ -1931,7 +1938,7 @@ S3JniApi(sqlite3_auto_extension(),jint,1auto_1extension)(
       ++SJG.autoExt.nExt;
     }
   }
-  MUTEX_EXT_LEAVE;
+  S3JniMutex_Ext_leave;
   return rc;
 }
 
@@ -2082,7 +2089,7 @@ S3JniApi(sqlite3_cancel_auto_extension(),jboolean,1cancel_1auto_1extension)(
   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];
@@ -2098,7 +2105,7 @@ S3JniApi(sqlite3_cancel_auto_extension(),jboolean,1cancel_1auto_1extension)(
       break;
     }
   }
-  MUTEX_EXT_LEAVE;
+  S3JniMutex_Ext_leave;
   return rc;
 }
 
@@ -3204,12 +3211,12 @@ S3JniApi(sqlite3_reset(),jint,1reset)(
 /* 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)(
@@ -3571,11 +3578,11 @@ S3JniApi(sqlite3_shutdown(),jint,1shutdown)(
   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();
@@ -3812,7 +3819,7 @@ JniDecl(void,1do_1something_1for_1developer)(JniArgsEnvClass){
   SO(S3JniDb);
   SO(S3NphRefs);
   printf("\t(^^^ %u NativePointerHolder subclasses)\n",
-         (unsigned)NphCache_SIZE);
+         (unsigned)S3Jni_NphCache_size);
   SO(S3JniGlobal);
   SO(S3JniAutoExtension);
   SO(S3JniUdf);
@@ -3945,14 +3952,14 @@ static jobject s3jni_getFts5ExensionApi(JNIEnv * const env){
     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;
 }
@@ -4655,9 +4662,9 @@ Java_org_sqlite_jni_tester_SQLTester_installCustomExtensions(JniArgsEnvClass){
 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;
 }
 
index 8ec6184cd1728b8e38a6e7f772327d191ab18160..b9f03983a316a86183fff68a7787ad3dcbf70733 100644 (file)
@@ -1789,10 +1789,10 @@ JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1value_1subtype
 
 /*
  * 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
index c8e87ff8275a181db47408c45918a33420fd5dc0..bc6f608736ef7f524162bdbb010dd0ec95f0b881 100644 (file)
@@ -19,6 +19,8 @@ package org.sqlite.jni;
    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
@@ -36,19 +38,19 @@ public abstract class SQLFunction {
      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
@@ -69,7 +71,7 @@ public abstract class SQLFunction {
        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){
@@ -95,7 +97,9 @@ public abstract class SQLFunction {
     }
   }
 
-  //! Subclass for creating scalar functions.
+  /**
+     Subclass for creating scalar functions.
+  */
   public static abstract class Scalar extends SQLFunction {
 
     /**
@@ -151,7 +155,7 @@ public abstract class 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);
@@ -161,7 +165,7 @@ public abstract class SQLFunction {
        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);
index 91a80ec4312366347c6dc362b333678c5bbe6b7a..e5a8b6e2438f1d66ff6f402dc1a400e60f3d246d 100644 (file)
@@ -33,7 +33,7 @@ import java.lang.annotation.ElementType;
 
 /**
    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.
 
@@ -50,62 +50,64 @@ import java.lang.annotation.ElementType;
   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 {
@@ -124,7 +126,7 @@ 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
@@ -1194,7 +1196,7 @@ public final class SQLite3Jni {
 
   /**
      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
@@ -1211,7 +1213,7 @@ public final class SQLite3Jni {
 
   /**
      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
@@ -1319,10 +1321,11 @@ public final class SQLite3Jni {
 
   /**
      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...
index 250c25bc0659dc32962e7140e92e6c2221e162f2..eb383fe8d27131be6c88873f2ed89b5d7af156f9 100644 (file)
@@ -1575,7 +1575,7 @@ public class Tester1 implements Runnable {
     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;
diff --git a/ext/jni/src/org/sqlite/jni/package-info.java b/ext/jni/src/org/sqlite/jni/package-info.java
new file mode 100644 (file)
index 0000000..2629d29
--- /dev/null
@@ -0,0 +1,6 @@
+/**
+   This package houses a JNI binding to the SQLite3 C API.
+
+   The docs are in progress.
+*/
+package org.sqlite.jni;
index ef3b839bc154ba2ac83dd64c62aae58f6f2ecc25..e5107dca278ed4cbb4a5081f056766cc157bbbe5 100644 (file)
@@ -629,7 +629,7 @@ public class SQLTester {
         t.outln("Aborted ",t.nAbortedScript," script(s).");
       }
       if( dumpInternals ){
-        sqlite3_do_something_for_developer();
+        sqlite3_jni_internal_details();
       }
     }
   }
index 414c6b82a441d7c827111c7a831231ff8e315925..ba8d4aea9660cb8c90051c900e31960cb26fe650 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-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
@@ -232,11 +232,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 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
@@ -255,10 +255,10 @@ F ext/jni/src/org/sqlite/jni/PreUpdateHook.java dec00a706b58c67989f0ff56c4f0a703
 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
@@ -266,11 +266,12 @@ F ext/jni/src/org/sqlite/jni/ValueHolder.java f022873abaabf64f3dd71ab0d6037c6e71
 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
@@ -2094,8 +2095,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 862f9828e078ae138c3533658c45e4c45155975794e752b9b3a71a693842f37a
-R eb32cfcd718e24e179eb7f83fffb0fa5
+P cf185bcd25629d882a030b8b87048179a120ab1f84aa1d68b279c499dbdf0dba
+R 409ebb8571a40aa1108ef1efd5f91432
 U stephan
-Z 2f5c08343242711ee223d20d111fc13d
+Z 85677113ed9046ae48bf181600ab6418
 # Remove this line to create a well-formed Fossil manifest.
index d8198b164bf8d1db5279db828f3d9628e6c49f33..af25bbe4449282e5e242c6173fa15046da15fd1b 100644 (file)
@@ -1 +1 @@
-cf185bcd25629d882a030b8b87048179a120ab1f84aa1d68b279c499dbdf0dba
\ No newline at end of file
+62b404d62fd62f4d220838b59c9f38a71afa2d4a8c3af0a5c9495fa7020972cf
\ No newline at end of file