]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
JNI: reimplement Tester2.execSql() using the high-level API.
authorstephan <stephan@noemail.net>
Tue, 14 Nov 2023 14:59:41 +0000 (14:59 +0000)
committerstephan <stephan@noemail.net>
Tue, 14 Nov 2023 14:59:41 +0000 (14:59 +0000)
FossilOrigin-Name: 3a69679e41d23a760df349b2471a1ed306c087f9a7a7a2e2cba3723071dee6b2

ext/jni/src/org/sqlite/jni/capi/ValueHolder.java
ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java
ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java
ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java
manifest
manifest.uuid

index 6d5db3f669ce4f1b34078e1b953f9d7365427c2d..0a469fea9a1d025b67425a57d051ce2a60852089 100644 (file)
@@ -9,7 +9,8 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file holds utility code for the sqlite3 JNI bindings.
+** This file contains the ValueHolder utility class for the sqlite3
+** JNI bindings.
 */
 package org.sqlite.jni.capi;
 
index acd232a4ce2ecd4d78e8ef03168e3ee87049ee7e..90b2de0ca158d5e94d2271c0b1fd9c1c93bfd22e 100644 (file)
@@ -627,6 +627,11 @@ public final class Sqlite implements AutoCloseable  {
 
      PrepareMultiFinalize offers a proxy which finalizes each
      statement after it is passed to another client-defined visitor.
+
+     Be aware that certain legal SQL constructs may fail in the
+     preparation phase, before the corresponding statement can be
+     stepped. Most notably, authorizer checks which disallow access to
+     something in a statement behave that way.
   */
   public void prepareMulti(byte sqlUtf8[], int prepFlags, PrepareMulti visitor){
     int pos = 0, n = 1;
index b279b9c4453e83777867772d6caf947ca294b9cb..e6b665fcc856890c7e902250b78130518b58a604 100644 (file)
@@ -133,49 +133,29 @@ public class Tester2 implements Runnable {
      Executes all SQL statements in the given string. If throwOnError
      is true then it will throw for any prepare/step errors, else it
      will return the corresponding non-0 result code.
-
-     TODO: reimplement this in the high-level API once it has the
-     multi-prepare capability.
   */
   public static int execSql(Sqlite dbw, boolean throwOnError, String sql){
-    final sqlite3 db = dbw.nativeHandle();
-    OutputPointer.Int32 oTail = new OutputPointer.Int32();
-    final byte[] sqlUtf8 = sql.getBytes(StandardCharsets.UTF_8);
-    int pos = 0, n = 1;
-    byte[] sqlChunk = sqlUtf8;
-    int rc = 0;
-    sqlite3_stmt stmt = null;
-    final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt();
-    while(pos < sqlChunk.length){
-      if(pos > 0){
-        sqlChunk = Arrays.copyOfRange(sqlChunk, pos,
-                                      sqlChunk.length);
-      }
-      if( 0==sqlChunk.length ) break;
-      rc = CApi.sqlite3_prepare_v2(db, sqlChunk, outStmt, oTail);
-      if( throwOnError ) affirm(0 == rc);
-      else if( 0!=rc ) break;
-      pos = oTail.value;
-      stmt = outStmt.take();
-      if( null == stmt ){
-        // empty statement was parsed.
-        continue;
-      }
-      affirm(0 != stmt.getNativePointer());
-      while( CApi.SQLITE_ROW == (rc = CApi.sqlite3_step(stmt)) ){
-      }
-      CApi.sqlite3_finalize(stmt);
-      affirm(0 == stmt.getNativePointer());
-      if(Sqlite.DONE!=rc){
-        break;
+    final ValueHolder<Integer> rv = new ValueHolder<>(0);
+    final Sqlite.PrepareMulti pm = new Sqlite.PrepareMulti(){
+        @Override public void call(Sqlite.Stmt stmt){
+          try{
+            while( Sqlite.ROW == (rv.value = stmt.step(throwOnError)) ){}
+          }
+          finally{ stmt.finalizeStmt(); }
+        }
+      };
+    try {
+      dbw.prepareMulti(sql, pm);
+    }catch(SqliteException se){
+      if( throwOnError ){
+        throw se;
+      }else{
+        /* This error (likely) happened in the prepare() phase and we
+           need to preempt it. */
+        rv.value = se.errcode();
       }
     }
-    CApi.sqlite3_finalize(stmt);
-    if(CApi.SQLITE_ROW==rc || CApi.SQLITE_DONE==rc) rc = 0;
-    if( 0!=rc && throwOnError){
-      throw new SqliteException(db);
-    }
-    return rc;
+    return (rv.value==Sqlite.DONE) ? 0 : rv.value;
   }
 
   static void execSql(Sqlite db, String sql){
index 009936a43e1bfb8bdf971fcaa17b6c75a8a65e06..7549bb97b28e2a1fd350a40988c3dbc492cfad12 100644 (file)
@@ -9,13 +9,13 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file contains a set of tests for the sqlite3 JNI bindings.
+** This file contains the ValueHolder utility class.
 */
 package org.sqlite.jni.wrapper1;
 
 /**
    A helper class which simply holds a single value. Its primary use
-   is for communicating values out of anonymous classes, as doing so
+   is for communicating values out of anonymous callbacks, as doing so
    requires a "final" reference.
 */
 public class ValueHolder<T> {
index 24b7677c8619e61b00f6d8b816757eaee6a178e9..c3cb199a168bbab73940a555079a62f106f4f0e6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sanother\sobscure\sproblem\swith\snested\saggregates.\sdbsqlfuzz\s04408efc51.
-D 2023-11-14T14:50:34.938
+C JNI:\sreimplement\sTester2.execSql()\susing\sthe\shigh-level\sAPI.
+D 2023-11-14T14:59:41.697
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -272,7 +272,7 @@ F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff22
 F ext/jni/src/org/sqlite/jni/capi/Tester1.java dcaa283a27aecb25dfd8f1a610885fb95d24945235b51ea13a1143585922de04
 F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723
 F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java c8bdf7848e6599115d601bcc9427ff902cb33129b9be32870ac6808e04b6ae56
-F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 22d365746a78c5cd7ae10c39444eb7bbf1a819aad4bb7eb77b1edc47773a3950
+F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 2ce069f3e007fdbbe1f4e507a5a407fc9679da31a0aa40985e6317ed4d5ec7b5
 F ext/jni/src/org/sqlite/jni/capi/WindowFunction.java caf4396f91b2567904cf94bc538a069fd62260d975bd037d15a02a890ed1ef9e
 F ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java f3abb8dd7381f53ebba909437090caf68200f06717b8a7d6aa96fa3e8133117d
 F ext/jni/src/org/sqlite/jni/capi/package-info.java 08ff986a65d2be9162442c82d28a65ce431d826f188520717c2ecb1484d0a50e
@@ -296,10 +296,10 @@ F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe
 F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java d5c108b02afd3c63c9e5e53f71f85273c1bfdc461ae526e0a0bb2b25e4df6483
 F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 43c43adfb7866098aadaaca1620028a6ec82d5193149970019b1cce9eb59fb03
 F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 27b141f5914c7cb0e40e90a301d5e05b77f3bd42236834a68031b7086381fafd
-F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java 408f3a2170a483a49443b21d9bd65c3be0c393c8bbdee432c615f9e37e05b466
+F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java 1d8ee109710fd41ba05c17b584f89fe6fcbb53ec1c305dc9686fc7a81fadd6f2
 F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 982538ddb4c0719ef87dfa664cd137b09890b546029a7477810bd64d4c47ee35
-F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 952d9b8707d3d1d7adb548fff18ceff81d5fe2a20d6470c4cf7c359a2b047d60
-F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 7b89a7391f771692c5b83b0a5b86266abe8d59f1c77d7a0eccc9b79f259d79af
+F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java a9235aa3695e5ad2fca47d43d35a77220b1244d77e43dab1fa3f56555bfc3733
+F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java a84e90c43724a69c2ecebd601bc8e5139f869b7d08cb705c77ef757dacdd0593
 F ext/jni/src/org/sqlite/jni/wrapper1/WindowFunction.java c7d1452f9ff26175b3c19bbf273116cc2846610af68e01756d755f037fe7319f
 F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745
 F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70
@@ -2139,8 +2139,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 f4f1cc201a7dc618a66617778ecf58ba60461ae700cb41f5c4abfa26dd0c0ed4
-R 94985542eb4157d1c2f915c1f903ad50
-U dan
-Z 2996a0d39c504eb56fd5f0fd9881439a
+P 6f9eed826f5b3d1cb08402925b406a7fe9b54259af1ba5eba92d4d37fbad628a
+R feb9a566cf38692cf88b194dedd844a6
+U stephan
+Z 3ab4c39a2f231e26a5c50b57bdfcf5f5
 # Remove this line to create a well-formed Fossil manifest.
index 03c7017710a1bcb3ef9f1a0a7eed94cee0d500e4..25e87b27f5cf4d0e6b365d61e6f78dfe6dce88ed 100644 (file)
@@ -1 +1 @@
-6f9eed826f5b3d1cb08402925b406a7fe9b54259af1ba5eba92d4d37fbad628a
\ No newline at end of file
+3a69679e41d23a760df349b2471a1ed306c087f9a7a7a2e2cba3723071dee6b2
\ No newline at end of file