From: stephan Date: Wed, 23 Aug 2023 10:36:12 +0000 (+0000) Subject: Bind a subset of sqlite3_config() to JNI: threading modes and sqllog. X-Git-Tag: version-3.44.0~305^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e97ab42968863298de499151c3f073a4b749a36;p=thirdparty%2Fsqlite.git Bind a subset of sqlite3_config() to JNI: threading modes and sqllog. FossilOrigin-Name: fce8ecaf7f2e69a168978e6993e58c452c45f76c39da33f2869c9d947c16cab1 --- diff --git a/ext/jni/GNUmakefile b/ext/jni/GNUmakefile index f1a6c552e9..1d77fc5f74 100644 --- a/ext/jni/GNUmakefile +++ b/ext/jni/GNUmakefile @@ -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 \ diff --git a/ext/jni/src/c/sqlite3-jni.c b/ext/jni/src/c/sqlite3-jni.c index e6a4b71c30..543f3be549 100644 --- a/ext/jni/src/c/sqlite3-jni.c +++ b/ext/jni/src/c/sqlite3-jni.c @@ -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; diff --git a/ext/jni/src/c/sqlite3-jni.h b/ext/jni/src/c/sqlite3-jni.h index e189df6947..0a8736f2a7 100644 --- a/ext/jni/src/c/sqlite3-jni.h +++ b/ext/jni/src/c/sqlite3-jni.h @@ -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 index 0000000000..c1bc0aab61 --- /dev/null +++ b/ext/jni/src/org/sqlite/jni/SQLLog.java @@ -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 ); +} diff --git a/ext/jni/src/org/sqlite/jni/SQLite3Jni.java b/ext/jni/src/org/sqlite/jni/SQLite3Jni.java index 22178faed6..e64ecf4914 100644 --- a/ext/jni/src/org/sqlite/jni/SQLite3Jni.java +++ b/ext/jni/src/org/sqlite/jni/SQLite3Jni.java @@ -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 diff --git a/ext/jni/src/org/sqlite/jni/Tester1.java b/ext/jni/src/org/sqlite/jni/Tester1.java index c075a2d036..fc350814b4 100644 --- a/ext/jni/src/org/sqlite/jni/Tester1.java +++ b/ext/jni/src/org/sqlite/jni/Tester1.java @@ -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); diff --git a/manifest b/manifest index b7b5f63421..ff7bb357eb 100644 --- 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. diff --git a/manifest.uuid b/manifest.uuid index 15b46f2538..23b760f68b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6c92d884920e4ace54913fc60ceef6e43a4351f45a4cb3c4a0ed3d29d544a31b \ No newline at end of file +fce8ecaf7f2e69a168978e6993e58c452c45f76c39da33f2869c9d947c16cab1 \ No newline at end of file