If sqlite3.oo1.DB.exec()'s callback returns a literal false, stop step()ing over results as if the end of the result set had been reached. Unrelated minor code-adjacent cleanups.

FossilOrigin-Name: 33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30
This commit is contained in:
stephan 2022-12-24 01:59:42 +00:00
parent 027afccdcd
commit 0cdc01d01a
4 changed files with 46 additions and 23 deletions

View 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{

View 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);

View File

@ -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.

View File

@ -1 +1 @@
96ba44946b3e88b6aa305c4363cbbfeab0d9120b3d8c4d2587d68b9293ea7cc6
33a58c8ece3b37a8edc3434af36643e2d489a53a672d778c5b77e66666045c30