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).
This commit is contained in:
		
							parent
							
								
									a4620c019b
								
							
						
					
					
						commit
						3cd92a855e
					
				
					 1 changed files with 11 additions and 0 deletions
				
			
		| 
						 | 
					@ -130,6 +130,17 @@ transaction after it finishes."
 | 
				
			||||||
If FILE doesn't exist, create it and initialize it as a new database."
 | 
					If FILE doesn't exist, create it and initialize it as a new database."
 | 
				
			||||||
  (call-with-database file (lambda (db) exp ...)))
 | 
					  (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)
 | 
					(define (last-insert-row-id db)
 | 
				
			||||||
  ;; XXX: (sqlite3) currently lacks bindings for 'sqlite3_last_insert_rowid'.
 | 
					  ;; XXX: (sqlite3) currently lacks bindings for 'sqlite3_last_insert_rowid'.
 | 
				
			||||||
  ;; Work around that.
 | 
					  ;; Work around that.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Reference in a new issue