]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If sqlite3.oo1.DB.exec()'s callback returns a literal false, stop step()ing over...
authorstephan <stephan@noemail.net>
Sat, 24 Dec 2022 01:59:42 +0000 (01:59 +0000)
committerstephan <stephan@noemail.net>
Sat, 24 Dec 2022 01:59:42 +0000 (01:59 +0000)
FossilOrigin-Name: 33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30

ext/wasm/api/sqlite3-api-oo1.js
ext/wasm/tester1.c-pp.js
manifest
manifest.uuid

index ddb346e5457ee5d52a4181b761a0d493f3301849..10f0ebc1814d8facb1ea0c69495a5563db27f15e 100644 (file)
@@ -447,7 +447,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
               if('$'===opt.rowMode[0]){
                 out.cbArg = function(stmt){
                   const rc = stmt.get(this.obj)[this.colName];
-                  return (undefined===rc) ? toss3("exec(): unknown result column:",this.colName) : rc;
+                  return (undefined===rc)
+                    ? toss3("exec(): unknown result column:",this.colName)
+                    : rc;
                 }.bind({
                   obj:Object.create(null),
                   colName: opt.rowMode.substr(1)
@@ -608,7 +610,7 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         try{ rc = wasm.cstrToJs(v.$zName) }
         finally { v.dispose() }
       }
-      return rc;        
+      return rc;
     },
     /**
        Compiles the given SQL and returns a prepared Stmt. This is
@@ -697,21 +699,27 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
        unchanged. Achtung: an SQL result may have multiple columns
        with identical names.
 
-       - `callback` = a function which gets called for each row of
-       the result set, but only if that statement has any result
+       - `callback` = a function which gets called for each row of the
+       result set, but only if that statement has any result
        _rows_. The callback's "this" is the options object, noting
        that this function synthesizes one if the caller does not pass
        one to exec(). The second argument passed to the callback is
        always the current Stmt object, as it's needed if the caller
        wants to fetch the column names or some such (noting that they
        could also be fetched via `this.columnNames`, if the client
-       provides the `columnNames` option).
+       provides the `columnNames` option). If the callback returns a
+       literal `false` (as opposed to any other falsy value, e.g.  an
+       implicit `undefined` return), any ongoing statement-`step()`
+       iteration stops without an error. The return value of the
+       callback is otherwise ignored.
 
        ACHTUNG: The callback MUST NOT modify the Stmt object. Calling
        any of the Stmt.get() variants, Stmt.getColumnName(), or
        similar, is legal, but calling step() or finalize() is
        not. Member methods which are illegal in this context will
-       trigger an exception.
+       trigger an exception, but clients must also refrain from using
+       any lower-level (C-style) APIs which might modify the
+       statement.
 
        The first argument passed to the callback defaults to an array of
        values from the current result row but may be changed with ...
@@ -799,7 +807,9 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             Array.isArray(opt.resultRows) ? opt.resultRows : undefined;
       let stmt;
       let bind = opt.bind;
-      let evalFirstResult = !!(arg.cbArg || opt.columnNames) /* true to evaluate the first result-returning query */;
+      let evalFirstResult = !!(
+        arg.cbArg || opt.columnNames || resultRows
+      ) /* true to step through the first result-returning statement */;
       const stack = wasm.scopedAllocPush();
       const saveSql = Array.isArray(opt.saveSql) ? opt.saveSql : undefined;
       try{
@@ -810,9 +820,10 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
            space for the SQL (pSql). When prepare_v2() returns, pzTail
            will point to somewhere in pSql. */
         let sqlByteLen = isTA ? arg.sql.byteLength : wasm.jstrlen(arg.sql);
-        const ppStmt  = wasm.scopedAlloc(/* output (sqlite3_stmt**) arg and pzTail */
-          (2 * wasm.ptrSizeof)
-          + (sqlByteLen + 1/* SQL + NUL */));
+        const ppStmt  = wasm.scopedAlloc(
+          /* output (sqlite3_stmt**) arg and pzTail */
+          (2 * wasm.ptrSizeof) + (sqlByteLen + 1/* SQL + NUL */)
+        );
         const pzTail = ppStmt + wasm.ptrSizeof /* final arg to sqlite3_prepare_v2() */;
         let pSql = pzTail + wasm.ptrSizeof;
         const pSqlEnd = pSql + sqlByteLen;
@@ -848,11 +859,15 @@ self.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
             if(Array.isArray(opt.columnNames)){
               stmt.getColumnNames(opt.columnNames);
             }
-            while(!!arg.cbArg && stmt.step()){
-              stmt._isLocked = true;
-              const row = arg.cbArg(stmt);
-              if(resultRows) resultRows.push(row);
-              if(callback) callback.call(opt, row, stmt);
+            if(arg.cbArg || resultRows){
+              for(; stmt.step(); stmt._isLocked = false){
+                stmt._isLocked = true;
+                const row = arg.cbArg(stmt);
+                if(resultRows) resultRows.push(row);
+                if(callback && false === callback.call(opt, row, stmt)){
+                  break;
+                }
+              }
               stmt._isLocked = false;
             }
           }else{
index 5411c064ce1feda0b1710ddc1adc604ef8f8cec0..82dd73e23bb790fbb031f591ad04a0b182cd4ade 100644 (file)
@@ -1391,6 +1391,14 @@ self.sqlite3InitModule = sqlite3InitModule;
                db.selectValue("SELECT "+Number.MIN_SAFE_INTEGER)).
         assert(Number.MAX_SAFE_INTEGER ===
                db.selectValue("SELECT "+Number.MAX_SAFE_INTEGER));
+
+      counter = 0;
+      db.exec({
+        sql: "SELECT a FROM t",
+        callback: ()=>(1===++counter),
+      });
+      T.assert(2===counter,
+               "Expecting exec step() loop to stop if callback returns false.");
       if(wasm.bigIntEnabled && haveWasmCTests()){
         const mI = wasm.xCall('sqlite3_wasm_test_int64_max');
         const b = BigInt(Number.MAX_SAFE_INTEGER * 2);
index 9fa7ef3ea993e70d8e18f44df5ecfd98628d8e8c..63b0ff62c9bc4770d8a63483f97ebe1e28e15c93 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Reimplement\sJS's\ssqlite3_bind_text/blob()\swith\shand-written\sbindings\sto\spermit\smore\sflexible\sinputs.\sAdd\sautomated\sJS-to-C\sfunction\sconversion\sto\ssqlite3_busy_handler().\ssqlite3.wasm.xWrap()'s\s'*'\sargument\sconversion\sno\slonger\streats\sJS\sstrings\sas\sC-strings:\sthose\sconversions\srequire\sexplicit\sopt-in\svia\sthe\s'string'\sconverter\s(or\sequivalent).
-D 2022-12-23T23:46:33.608
+C If\ssqlite3.oo1.DB.exec()'s\scallback\sreturns\sa\sliteral\sfalse,\sstop\sstep()ing\sover\sresults\sas\sif\sthe\send\sof\sthe\sresult\sset\shad\sbeen\sreached.\sUnrelated\sminor\scode-adjacent\scleanups.
+D 2022-12-24T01:59:42.190
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -504,7 +504,7 @@ F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b
 F ext/wasm/api/pre-js.c-pp.js b88499dc303c21fc3f55f2c364a0f814f587b60a95784303881169f9e91c1d5f
 F ext/wasm/api/sqlite3-api-cleanup.js 680d5ccfff54459db136a49b2199d9f879c8405d9c99af1dda0cc5e7c29056f4
 F ext/wasm/api/sqlite3-api-glue.js f0651048a2601bf79f7f39c2c855f6417e65548417f5019ac9ac2ffb2463f2b9
-F ext/wasm/api/sqlite3-api-oo1.js c2a3e310f993a632b6c5da0c49b0635863a73df60c4f9fc0a30648f25e4ec32a
+F ext/wasm/api/sqlite3-api-oo1.js 06fcaf4007b68b39db20c83b2620d5c04322bcbe2abb9bde7941b191257b6d43
 F ext/wasm/api/sqlite3-api-prologue.js 683956ea6ab5e0132db48bb693a6bb9dd92f36c8c0902af36572e9b29006ac6d
 F ext/wasm/api/sqlite3-api-worker1.js e94ba98e44afccfa482874cd9acb325883ade50ed1f9f9526beb9de1711f182f
 F ext/wasm/api/sqlite3-license-version-header.js a661182fc93fc2cf212dfd0b987f8e138a3ac98f850b1112e29b5fbdaecc87c3
@@ -555,7 +555,7 @@ F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555
 F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b
 F ext/wasm/tester1-worker.html d43f3c131d88f10d00aff3e328fed13c858d674ea2ff1ff90225506137f85aa9
 F ext/wasm/tester1.c-pp.html d34bef3d48e5cbc1c7c06882ad240fec49bf88f5f65696cc2c72c416933aa406
-F ext/wasm/tester1.c-pp.js 50b51af2b5466de0cba8ebc97b86bc886c32f937d8f4b36d3b3936ef9748e534
+F ext/wasm/tester1.c-pp.js 99d6dc920d0c379c78053edb89a870666cfb9d4d4548b31c94427f9135a1c0a2
 F ext/wasm/tests/opfs/concurrency/index.html 86d8ac435074d1e7007b91105f4897f368c165e8cecb6a9aa3d81f5cf5dcbe70
 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d
 F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2
@@ -2067,8 +2067,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 1dfc03ab1e0269807beef27bf884ab9ead7553d4a5f6ed213f812d7fa052045f
-R 0557f08bf576b7be78ec588d2742348d
+P 96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6
+R 7ef916e9c75ca3398704313fbddc267b
 U stephan
-Z 4e12d5aedea06f895991428eb871a6d7
+Z c6e787d4dc5ffd60ed702bf77e978ab3
 # Remove this line to create a well-formed Fossil manifest.
index 83020f5c61a6816dde5d491fb665175c7f795a06..4cbd4b8876d824f8b571ecd3351f5e2a29c9fe1e 100644 (file)
@@ -1 +1 @@
-96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6
\ No newline at end of file
+33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30
\ No newline at end of file