]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Bind a subset of sqlite3_config() to JNI: threading modes and sqllog.
authorstephan <stephan@noemail.net>
Wed, 23 Aug 2023 10:36:12 +0000 (10:36 +0000)
committerstephan <stephan@noemail.net>
Wed, 23 Aug 2023 10:36:12 +0000 (10:36 +0000)
FossilOrigin-Name: fce8ecaf7f2e69a168978e6993e58c452c45f76c39da33f2869c9d947c16cab1

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

index f1a6c552e9f4b74943a0146df3036d8169147e79..1d77fc5f749163d7e779cb66ec4f83bd331a7371 100644 (file)
@@ -68,6 +68,7 @@ JAVA_FILES.main := $(patsubst %,$(dir.src.jni)/%,\
   ResultCode.java \
   RollbackHook.java \
   SQLFunction.java \
+  SQLLog.java \
   sqlite3_context.java \
   sqlite3.java \
   SQLite3Jni.java \
@@ -160,6 +161,7 @@ SQLITE_OPT = \
   -DSQLITE_ENABLE_DBSTAT_VTAB \
   -DSQLITE_ENABLE_BYTECODE_VTAB \
   -DSQLITE_ENABLE_OFFSET_SQL_FUNC \
+  -DSQLITE_ENABLE_SQLLOG \
   -DSQLITE_OMIT_LOAD_EXTENSION \
   -DSQLITE_OMIT_DEPRECATED \
   -DSQLITE_OMIT_SHARED_CACHE \
index e6a4b71c3045a49b6d4a6092786594c52e6e9cad..543f3be549fe2f566944c46f7892d87024a90dd0 100644 (file)
@@ -503,6 +503,11 @@ struct S3JniGlobalType {
                            always have this set to the current JNIEnv
                            object. Used only for sanity checking. */;
   } perDb;
+#ifdef SQLITE_ENABLE_SQLLOG
+  struct {
+    S3JniHook sqllog  /* sqlite3_config(SQLITE_CONFIG_SQLLOG) callback */;
+  } hooks;
+#endif
   /*
   ** Refs to global classes and methods. Obtained during static init
   ** and never released.
@@ -2275,6 +2280,97 @@ JDECL(jboolean,1compileoption_1used)(JENV_CSELF, jstring name){
   return rc;
 }
 
+/*
+** sqlite3_config(SQLITE_CONFIG_...) wrapper for a small subset of
+** options.
+*/
+JDECL(jint,1config__I)(JENV_CSELF, jint n){
+  switch(n){
+    case SQLITE_CONFIG_SINGLETHREAD:
+    case SQLITE_CONFIG_MULTITHREAD:
+    case SQLITE_CONFIG_SERIALIZED:
+      return sqlite3_config( n );
+    default:
+      return SQLITE_MISUSE;
+  }
+}
+
+#ifdef SQLITE_ENABLE_SQLLOG
+/* C-to-Java SQLITE_CONFIG_SQLLOG wrapper. */
+static void s3jni_config_sqllog(void *ignored, sqlite3 *pDb, const char *z, int op){
+  jobject jArg0 = 0;
+  jstring jArg1 = 0;
+  LocalJniGetEnv;
+  S3JniEnv * const jc = S3JniGlobal_env_cache(env);
+  S3JniDb * const ps = S3JniDb_for_db(env, 0, pDb);
+  S3JniHook * const hook = &SJG.hooks.sqllog;
+
+  if( !ps || !hook->jObj ) return;
+  jArg0 = REF_L(ps->jDb);
+  switch(op){
+    case 0: /* db opened */
+    case 1: /* SQL executed */
+      jArg1 = s3jni_utf8_to_jstring(jc, z, -1);
+      break;
+    case 2: /* db closed */
+      break;
+    default:
+      (*env)->FatalError(env, "Unhandled 4th arg to SQLITE_CONFIG_SQLLOG.");
+      break;
+  }
+  (*env)->CallVoidMethod(env, hook->jObj, hook->midCallback, jArg0, jArg1, op);
+  IFTHREW{
+    EXCEPTION_WARN_CALLBACK_THREW("SQLITE_CONFIG_SQLLOG callback");
+    EXCEPTION_CLEAR;
+  }
+  UNREF_L(jArg0);
+  UNREF_L(jArg1);
+}
+//! Requirement of SQLITE_CONFIG_SQLLOG.
+void sqlite3_init_sqllog(void){
+  sqlite3_config( SQLITE_CONFIG_SQLLOG, s3jni_config_sqllog, 0 );
+}
+#endif
+
+/* sqlite3_config(SQLITE_CONFIG_SQLLOG) wrapper. */
+JDECL(jint,1config__Lorg_sqlite_jni_SQLLog_2)(JENV_CSELF, jobject jLog){
+#ifdef SQLITE_ENABLE_SQLLOG
+  S3JniHook tmpHook;
+  S3JniHook * const hook = &tmpHook;
+  S3JniHook * const hookOld = & SJG.hooks.sqllog;
+  int rc = 0;
+  if( !jLog ){
+    S3JniHook_unref(env, hookOld, 0);
+    return 0;
+  }
+  if( hookOld->jObj && (*env)->IsSameObject(env, jLog, hookOld->jObj) ){
+    return 0;
+  }
+  hook->klazz = REF_G( (*env)->GetObjectClass(env, jLog) );
+  hook->midCallback = (*env)->GetMethodID(env, hook->klazz, "xSqllog",
+                                          "(Lorg/sqlite/jni/sqlite3;"
+                                          "Ljava/lang/String;"
+                                          "I)V");
+  if( !hook->midCallback ){
+    EXCEPTION_WARN_IGNORE;
+    S3JniHook_unref(env, hook, 0);
+    return SQLITE_ERROR;
+  }
+  hook->jObj = REF_G(jLog);
+  rc = sqlite3_config( SQLITE_CONFIG_SQLLOG, s3jni_config_sqllog, 0 );
+  if( rc ){
+    S3JniHook_unref(env, hook, 0);
+  }else{
+    S3JniHook_unref(env, hookOld, 0);
+    *hookOld = *hook;
+  }
+  return rc;
+#else
+  MARKER(("Warning: built without SQLITE_ENABLE_SQLLOG.\n"));
+  return SQLITE_RANGE;
+#endif
+}
+
 JDECL(jobject,1context_1db_1handle)(JENV_CSELF, jobject jpCx){
   sqlite3 * const pDb = sqlite3_context_db_handle(PtrGet_sqlite3_context(jpCx));
   S3JniDb * const ps = pDb ? S3JniDb_for_db(env, 0, pDb) : 0;
index e189df69470ea07fc8e03dee4f87385b80818774..0a8736f2a7ba275bb02c8093efc5908dbafdefb7 100644 (file)
@@ -1083,6 +1083,22 @@ JNIEXPORT jstring JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1compileoption_
 JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1compileoption_1used
   (JNIEnv *, jclass, jstring);
 
+/*
+ * Class:     org_sqlite_jni_SQLite3Jni
+ * Method:    sqlite3_config
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__I
+  (JNIEnv *, jclass, jint);
+
+/*
+ * Class:     org_sqlite_jni_SQLite3Jni
+ * Method:    sqlite3_config
+ * Signature: (Lorg/sqlite/jni/SQLLog;)I
+ */
+JNIEXPORT jint JNICALL Java_org_sqlite_jni_SQLite3Jni_sqlite3_1config__Lorg_sqlite_jni_SQLLog_2
+  (JNIEnv *, jclass, jobject);
+
 /*
  * Class:     org_sqlite_jni_SQLite3Jni
  * Method:    sqlite3_create_collation
diff --git a/ext/jni/src/org/sqlite/jni/SQLLog.java b/ext/jni/src/org/sqlite/jni/SQLLog.java
new file mode 100644 (file)
index 0000000..c1bc0aa
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+** 2023-08-23
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file is part of the JNI bindings for the sqlite3 C API.
+*/
+package org.sqlite.jni;
+
+/**
+   A callback for use with sqlite3_config(SQLLog).
+*/
+public interface SQLLog {
+  /**
+     Must function as described for sqlite3_config(SQLITE_CONFIG_SQLLOG)
+     callback, with the slight signature change.
+  */
+  void xSqllog(sqlite3 db, String msg, int msgType );
+}
index 22178faed6a2c4ca52eb8d2da8194e3f0fd68306..e64ecf491483abb097df5e16283d5897aa84f608 100644 (file)
@@ -454,6 +454,31 @@ public final class SQLite3Jni {
     @NotNull String optName
   );
 
+  /*
+  ** Works like in the C API with the exception that it only supports
+  ** the following subset of configution flags:
+  **
+  ** - SQLITE_CONFIG_SINGLETHREAD
+  ** - SQLITE_CONFIG_MULTITHREAD
+  ** - SQLITE_CONFIG_SERIALIZED
+  **
+  ** Others may be added in the future. It returns SQLITE_MISUSE if
+  ** given an argument it does not handle.
+  */
+  public static native int sqlite3_config(int op);
+
+  /*
+  ** If the native library was built with SQLITE_ENABLE_SQLLOG defined
+  ** then this acts as a proxy for C's
+  ** sqlite3_config(SQLITE_ENABLE_SQLLOG,...). This sets or clears the
+  ** logger. If installation of a logger fails, any previous logger is
+  ** retained.
+  **
+  ** If not built with SQLITE_ENABLE_SQLLOG defined, this returns
+  ** SQLITE_RANGE.
+  */
+  public static native int sqlite3_config( @Nullable SQLLog logger );
+
   public static native int sqlite3_create_collation(
     @NotNull sqlite3 db, @NotNull String name, int eTextRep,
     @NotNull Collation col
index c075a2d03608a1fbb6195f0508195c9b0e59f973..fc350814b4a2ee1da486b16eac40b824329a914f 100644 (file)
@@ -1321,6 +1321,7 @@ public class Tester1 implements Runnable {
     boolean doSomethingForDev = false;
     Integer nRepeat = 1;
     boolean forceFail = false;
+    boolean sqlLog = false;
     for( int i = 0; i < args.length; ){
       String arg = args[i++];
       if(arg.startsWith("-")){
@@ -1338,6 +1339,8 @@ public class Tester1 implements Runnable {
           listRunTests = true;
         }else if(arg.equals("fail")){
           forceFail = true;
+        }else if(arg.equals("sqllog")){
+          sqlLog = true;
         }else if(arg.equals("naps")){
           takeNaps = true;
         }else{
@@ -1366,8 +1369,27 @@ public class Tester1 implements Runnable {
       }
     }
 
+    if( sqlLog ){
+      int rc = sqlite3_config( new SQLLog() {
+          @Override public void xSqllog(sqlite3 db, String msg, int op){
+            switch(op){
+              case 0: outln("Opening db: ",db); break;
+              case 1: outln(db,": ",msg); break;
+              case 2: outln("Closing db: ",db); break;
+            }
+          }
+        });
+      affirm( 0==rc );
+    }
+
     final long timeStart = System.currentTimeMillis();
     int nLoop = 0;
+    affirm( 0==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ),
+            "Could not switch to single-thread mode." );
+    affirm( 0==sqlite3_config( SQLITE_CONFIG_MULTITHREAD ),
+            "Could not switch to multithread mode."  );
+    affirm( 0==sqlite3_config( SQLITE_CONFIG_SERIALIZED ),
+            "Could not switch to serialized threading mode."  );
     outln("libversion_number: ",
           sqlite3_libversion_number(),"\n",
           sqlite3_libversion(),"\n",SQLITE_SOURCE_ID);
index b7b5f634215cfa2ce0ca5448cd9d7976813fa256..ff7bb357eb9620d044ba68356b418dad7665dd0f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Numerous\sminor\scleanups\sand\scode\sstyle\sconformance\simprovements.
-D 2023-08-23T09:05:16.380
+C Bind\sa\ssubset\sof\ssqlite3_config()\sto\sJNI:\sthreading\smodes\sand\ssqllog.
+D 2023-08-23T10:36:12.341
 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 a38d7c5ad4ab1e209e2a9352ff06add1d9a0bc666351714bfc8858625330c16b
+F ext/jni/GNUmakefile 33abc2f4f4bbd5451d6be5e6f2e109c045cc326cd942d602a3908a0c7b3c6f49
 F ext/jni/README.md ddcc6be0c0d65f1e2fd687de9f40d38c82630fd61f83cc9550773caa19dd8be1
 F ext/jni/jar-dist.make 9a03d10dbb5a74c724bfec4b76fd9e4c9865cbbc858d731cb48f38ac897d73a3
-F ext/jni/src/c/sqlite3-jni.c aba2bf845c512b835c795263c2c460faaa926967b497d7dbcf3cdbe98a2d0396
-F ext/jni/src/c/sqlite3-jni.h 8b0ab1a3f0f92b75d4ff50db4a88b66a137cfb561268eb15bb3993ed174dbb74
+F ext/jni/src/c/sqlite3-jni.c 01c6cf041d1b9937a97c7700006a532d3b11fd4991931e31ffa7a777b97fba11
+F ext/jni/src/c/sqlite3-jni.h 44bcb4eb3517c089f8f24f1546ea66b350d0661a4b0fa148425c9a41cabf487d
 F ext/jni/src/org/sqlite/jni/Authorizer.java 1308988f7f40579ea0e4deeaec3c6be971630566bd021c31367fe3f5140db892
 F ext/jni/src/org/sqlite/jni/AutoExtension.java 3b62c915e45ce73f63343ca9195ec63592244d616a1908b7587bdd45de1b97dd
 F ext/jni/src/org/sqlite/jni/BusyHandler.java 1b1d3e5c86cd796a0580c81b6af6550ad943baa25e47ada0dcca3aff3ebe978c
@@ -255,8 +255,9 @@ F ext/jni/src/org/sqlite/jni/ProgressHandler.java 6f62053a828a572de809828b1ee495
 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/SQLite3Jni.java 2f36370cfdec01d309720392b2c3e4af6afce0b6ece8188b5c3ed688a5a1e63a
-F ext/jni/src/org/sqlite/jni/Tester1.java 93bd76f2294fa2f592395c9d823adb38a9be3846bff00debeff02310f4e9e6be
+F ext/jni/src/org/sqlite/jni/SQLLog.java c60610b35208416940822e834d61f08fbbe5d6e06b374b541b49e41fd56c9798
+F ext/jni/src/org/sqlite/jni/SQLite3Jni.java 2de5729a33cf2636160eb6893a4234c99669521a352bfffbf60410bd493ebece
+F ext/jni/src/org/sqlite/jni/Tester1.java 4e17a30e9da15954ba71ef52beb5b347f312594a0facbaf86e1f29481c4dc65c
 F ext/jni/src/org/sqlite/jni/TesterFts5.java de095e3b701fba0c56d7b8b2993dc22bcbaa9de8f992904a93729ad729a91576
 F ext/jni/src/org/sqlite/jni/Tracer.java a5cece9f947b0af27669b8baec300b6dd7ff859c3e6a6e4a1bd8b50f9714775d
 F ext/jni/src/org/sqlite/jni/UpdateHook.java e58645a1727f8a9bbe72dc072ec5b40d9f9362cb0aa24acfe93f49ff56a9016d
@@ -2092,8 +2093,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 aebbc24afb339ed07b7cd767fbc0d25f3e9c3d9bb5ef3d1c10b04b605c7261bc
-R 8d2509e7997f13cf4f5b727ee9382226
+P 6c92d884920e4ace54913fc60ceef6e43a4351f45a4cb3c4a0ed3d29d544a31b
+R ebb24a95583279229c99fb88e45995e0
 U stephan
-Z 2c18e9ca7bc91670a10ef4d3cc234c7a
+Z 0a740a88323f212cff509af7c6f7ae11
 # Remove this line to create a well-formed Fossil manifest.
index 15b46f2538fbd996861fed06f02390f5dcc80d33..23b760f68b6c0e0865c4328c74eaeeb24b01254f 100644 (file)
@@ -1 +1 @@
-6c92d884920e4ace54913fc60ceef6e43a4351f45a4cb3c4a0ed3d29d544a31b
\ No newline at end of file
+fce8ecaf7f2e69a168978e6993e58c452c45f76c39da33f2869c9d947c16cab1
\ No newline at end of file