1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-27 20:41:58 +03:00

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{