stephencelis / SQLite.swift

A type-safe, Swift-language layer over SQLite3.
MIT License
9.57k stars 1.54k forks source link

Adding public method to reset a prepared statement #1145

Closed adamwulf closed 1 year ago

adamwulf commented 1 year ago

For context, the sqlite docs: https://www.sqlite.org/lang_transaction.html#implicit_versus_explicit_transactions

An implicit transaction (a transaction that is started automatically, not a transaction started by BEGIN) is committed automatically when the last active statement finishes. A statement finishes when its last cursor closes, which is guaranteed to happen when the prepared statement is reset or finalized. Some statements might "finish" for the purpose of transaction control prior to being reset or finalized, but there is no guarantee of this. The only way to ensure that a statement has "finished" is to invoke sqlite3_reset() or sqlite3_finalize() on that statement.

For clients that keep and reuse prepared statements, that statement prevents transactions from fully closing (even after a COMMIT). This, in turn, prevents a wal checkpoint (both explicitly requested checkpoint and auto checkpoints) from succeeding. Since reset is only currently called when starting a new query or in deinit, this means for any long-lived prepared statement will prevent a wal checkpoint, causing the wal file to grow unbounded.

Instead, allowing clients to explicitly reset their prepared statements allows them to control when the transaction closes, which allows wal checkpoints to succeed.

adamwulf commented 1 year ago

Just pushed up changes to the test, as well as a documentation mention and context for its use.

adamwulf commented 1 year ago

ok - new changes pushed up with the test cleanup