diff options
author | stephan <stephan@noemail.net> | 2023-05-19 15:54:41 +0000 |
---|---|---|
committer | stephan <stephan@noemail.net> | 2023-05-19 15:54:41 +0000 |
commit | 2492b6c0fb56d55dd8f27dcde3c35a22b644f183 (patch) | |
tree | 3e55e93588df5efff9cd5e4dbbde6c19b972c167 /ext/wasm/api/sqlite3-api-oo1.js | |
parent | 8e2fd6eae315b321e41344326fd77305f8679819 (diff) | |
download | sqlite-2492b6c0fb56d55dd8f27dcde3c35a22b644f183.tar.gz sqlite-2492b6c0fb56d55dd8f27dcde3c35a22b644f183.zip |
sqlite3.oo1.Stmt.finalize() now throws if sqlite3_finalize() returns non-zero. This is intended to address the INSERT RETURNING case covered in [forum:36f7a2e7494897df|forum post 36f7a2e7494897df].
FossilOrigin-Name: f23eb5c6d36546ee1e181a03660e0b2dc8005bba24bee8bae594b0c78bd152cd
Diffstat (limited to 'ext/wasm/api/sqlite3-api-oo1.js')
-rw-r--r-- | ext/wasm/api/sqlite3-api-oo1.js | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/ext/wasm/api/sqlite3-api-oo1.js b/ext/wasm/api/sqlite3-api-oo1.js index 1f244a7c5..e9f4e27ff 100644 --- a/ext/wasm/api/sqlite3-api-oo1.js +++ b/ext/wasm/api/sqlite3-api-oo1.js @@ -55,6 +55,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(sqliteResultCode){ if(dbPtr instanceof DB) dbPtr = dbPtr.pointer; toss3( + sqliteResultCode, "sqlite3 result code",sqliteResultCode+":", (dbPtr ? capi.sqlite3_errmsg(dbPtr) @@ -503,6 +504,9 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ "Not an error." The various non-0 non-error codes need to be checked for in client code where they are expected. + The thrown exception's `resultCode` property will be the value of + the second argument to this function. + If it does not throw, it returns its first argument. */ DB.checkRc = (db,resultCode)=>checkSqlite3Rc(db,resultCode); @@ -899,11 +903,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ sqlite3.config.warn("DB.exec() is propagating exception",opt,e); throw e; }*/finally{ + wasm.scopedAllocPop(stack); if(stmt){ delete stmt._isLocked; stmt.finalize(); } - wasm.scopedAllocPop(stack); } return arg.returnVal(); }/*exec()*/, @@ -1256,7 +1260,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ not throw, it returns this object. */ checkRc: function(resultCode){ - return DB.checkRc(this, resultCode); + return checkSqlite3Rc(this, resultCode); } }/*DB.prototype*/; @@ -1420,24 +1424,40 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ Stmt.prototype = { /** "Finalizes" this statement. This is a no-op if the - statement has already been finalizes. Returns + statement has already been finalized. Returns undefined. Most methods in this class will throw if called after this is. + + This method always throws if called when it is illegal to do + so, e.g. from a per-row callback handler of a DB.exec() call. + + As of version 3.43, this method will throw if + sqlite3_finalize() returns an error code, which can happen in + certain unusual cases involving locking. When it throws for + this reason, throwing is delayed until after all resources are + cleaned up. That is, the finalization still runs to + completion. */ finalize: function(){ if(this.pointer){ affirmUnlocked(this,'finalize()'); - delete __stmtMap.get(this.db)[this.pointer]; - capi.sqlite3_finalize(this.pointer); + const rc = capi.sqlite3_finalize(this.pointer), + db = this.db; + delete __stmtMap.get(db)[this.pointer]; __ptrMap.delete(this); delete this._mayGet; delete this.parameterCount; - delete this.db; delete this._isLocked; + delete this.db; + checkSqlite3Rc(db, rc); } }, - /** Clears all bound values. Returns this object. - Throws if this statement has been finalized. */ + /** + Clears all bound values. Returns this object. Throws if this + statement has been finalized or if modification of the + statement is currently illegal (e.g. in the per-row callback of + a DB.exec() call). + */ clearBindings: function(){ affirmUnlocked(affirmStmtOpen(this), 'clearBindings()') capi.sqlite3_clear_bindings(this.pointer); |