From e388909f0c53bace1affec46652f1d6e55d15f27 Mon Sep 17 00:00:00 2001 From: Dimitri Fontaine Date: Mon, 27 Jul 2020 21:11:28 +0200 Subject: [PATCH] Implement a retry loop when SQLite database is "BUSY". It turns our that you can't do some operations on SQLite from several concurrent connections, such as a "pgrama encoding" query. Fixes #1193. --- src/sources/sqlite/sqlite-schema.lisp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/sources/sqlite/sqlite-schema.lisp b/src/sources/sqlite/sqlite-schema.lisp index acc7348..39f3930 100644 --- a/src/sources/sqlite/sqlite-schema.lisp +++ b/src/sources/sqlite/sqlite-schema.lisp @@ -10,9 +10,21 @@ ;;; ;;; SQLite schema introspection facilities ;;; +(defun sqlite-pragma-encoding (db) + (handler-case + (sqlite:execute-single db "pragma encoding;") + (sqlite:sqlite-error (e) + (if (eq :busy (sqlite:sqlite-error-code e)) + ;; retry when "database is locked" for being BUSY + (progn + (sleep 0.1) + (sqlite-pragma-encoding db)) + ;; fail by re-signaling the error + (error e))))) + (defun sqlite-encoding (db) "Return a BABEL suitable encoding for the SQLite db handle." - (let ((encoding-string (sqlite:execute-single db "pragma encoding;"))) + (let ((encoding-string (sqlite-pragma-encoding db))) (cond ((string-equal encoding-string "UTF-8") :utf-8) ((string-equal encoding-string "UTF-16") :utf-16) ((string-equal encoding-string "UTF-16le") :utf-16le)