guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

01/04: database: work around guile-sqlite3 bug preventing statement rese


From: guix-commits
Subject: 01/04: database: work around guile-sqlite3 bug preventing statement reset
Date: Wed, 10 Jun 2020 23:23:45 -0400 (EDT)

reepca pushed a commit to branch master
in repository guix.

commit 3cd92a855e8f6768a4470cd5522749a39d5f9047
Author: Caleb Ristvedt <caleb.ristvedt@cune.org>
AuthorDate: Mon Jun 1 18:50:07 2020 -0500

    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 https://notabug.org/guile-sqlite3/guile-sqlite3/issues/12).  
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).
---
 guix/store/database.scm | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/guix/store/database.scm b/guix/store/database.scm
index ef52036..ae7e96d 100644
--- a/guix/store/database.scm
+++ b/guix/store/database.scm
@@ -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
+  ;; https://notabug.org/guile-sqlite3/guile-sqlite3/issues/12).  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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]