Browse Source

database: work around guile-sqlite3 bug preventing statement reset

guile-sqlite3 provides statement caching, making it unnecessary for sqlite to
keep re-preparing statements that are frequently used.  Unfortunately it
doesn't quite emulate the semantics of sqlite_finalize properly, because it
doesn't cause a commit if the statement being finalized is the last "active"
statement (see  We
work around this by wrapping sqlite-finalize with our own version that ensures
sqlite-reset is called, which does The Right Thing™.

* guix/store/database.scm (sqlite-finalize): new procedure that shadows the
  sqlite-finalize from (sqlite3).
Caleb Ristvedt 2 years ago
No known key found for this signature in database GPG Key ID: C166AA495F7F189C
  1. 11


@ -130,6 +130,17 @@ transaction after it finishes."
If FILE doesn't exist, create it and initialize it as a new database."
(call-with-database file (lambda (db) exp ...)))
(define (sqlite-finalize stmt)
;; As of guile-sqlite3 0.1.0, cached statements aren't reset when
;; sqlite-finalize is invoked on them (see
;; This can
;; cause problems with automatically-started transactions, so we work around
;; it by wrapping sqlite-finalize so that sqlite-reset is always called.
;; This always works, because resetting a statement twice has no adverse
;; effects. We can remove this once the fixed guile-sqlite3 is widespread.
(sqlite-reset stmt)
((@ (sqlite3) sqlite-finalize) stmt))
(define (last-insert-row-id db)
;; XXX: (sqlite3) currently lacks bindings for 'sqlite3_last_insert_rowid'.
;; Work around that.