]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix multisession.el when SQLite becomes unavailable
authorEli Zaretskii <eliz@gnu.org>
Sat, 7 Sep 2024 07:42:01 +0000 (10:42 +0300)
committerEshel Yaron <me@eshelyaron.com>
Sun, 8 Sep 2024 11:24:03 +0000 (13:24 +0200)
This is for the case when the user customizes multisession
to use SQLite, but then built-in SQLite support becomes
unavailable for some reason (e.g., upgrade the OS).
* lisp/emacs-lisp/multisession.el (multisession-backend-value)
(multisession--backend-set-value, multisession--backend-values)
(multisession--backend-delete): Call next method if built-in
SQLite support is not available.  Suggested by Stefan Monnier
<monnier@iro.umontreal.ca>.  (Bug#72788)

(cherry picked from commit e2154c63761add6063a719ba6253c8e6e8133814)

lisp/emacs-lisp/multisession.el

index b7bc5536f7820fc96bbb046aca783544d2b3494b..c923c29bbf7857c6d790850b80e5d6b543eece3c 100644 (file)
@@ -170,56 +170,60 @@ DOC should be a doc string, and ARGS are keywords as applicable to
          "create unique index multisession_idx on multisession (package, key)")))))
 
 (cl-defmethod multisession-backend-value ((_type (eql 'sqlite)) object)
-  (multisession--ensure-db)
-  (let ((id (list (multisession--package object)
-                  (multisession--key object))))
-    (cond
-     ;; We have no value yet; check the database.
-     ((eq (multisession--cached-value object) multisession--unbound)
-      (let ((stored
-             (car
-              (sqlite-select
-               multisession--db
-               "select value, sequence from multisession where package = ? and key = ?"
-               id))))
-        (if stored
-            (let ((value (car (read-from-string (car stored)))))
-              (setf (multisession--cached-value object) value
-                    (multisession--cached-sequence object) (cadr stored))
-              value)
-          ;; Nothing; return the initial value.
-          (multisession--initial-value object))))
-     ;; We have a value, but we want to update in case some other
-     ;; Emacs instance has updated.
-     ((multisession--synchronized object)
-      (let ((stored
-             (car
-              (sqlite-select
-               multisession--db
-               "select value, sequence from multisession where sequence > ? and package = ? and key = ?"
-               (cons (multisession--cached-sequence object) id)))))
-        (if stored
-            (let ((value (car (read-from-string (car stored)))))
-              (setf (multisession--cached-value object) value
-                    (multisession--cached-sequence object) (cadr stored))
-              value)
-          ;; Nothing, return the cached value.
-          (multisession--cached-value object))))
-     ;; Just return the cached value.
-     (t
-      (multisession--cached-value object)))))
+  (if (not (sqlite-available-p))
+      (cl-call-next-method)
+    (multisession--ensure-db)
+    (let ((id (list (multisession--package object)
+                    (multisession--key object))))
+      (cond
+       ;; We have no value yet; check the database.
+       ((eq (multisession--cached-value object) multisession--unbound)
+        (let ((stored
+               (car
+                (sqlite-select
+                 multisession--db
+                 "select value, sequence from multisession where package = ? and key = ?"
+                 id))))
+          (if stored
+              (let ((value (car (read-from-string (car stored)))))
+                (setf (multisession--cached-value object) value
+                      (multisession--cached-sequence object) (cadr stored))
+                value)
+            ;; Nothing; return the initial value.
+            (multisession--initial-value object))))
+       ;; We have a value, but we want to update in case some other
+       ;; Emacs instance has updated.
+       ((multisession--synchronized object)
+        (let ((stored
+               (car
+                (sqlite-select
+                 multisession--db
+                 "select value, sequence from multisession where sequence > ? and package = ? and key = ?"
+                 (cons (multisession--cached-sequence object) id)))))
+          (if stored
+              (let ((value (car (read-from-string (car stored)))))
+                (setf (multisession--cached-value object) value
+                      (multisession--cached-sequence object) (cadr stored))
+                value)
+            ;; Nothing, return the cached value.
+            (multisession--cached-value object))))
+       ;; Just return the cached value.
+       (t
+        (multisession--cached-value object))))))
 
 (cl-defmethod multisession--backend-set-value ((_type (eql 'sqlite))
                                                object value)
-  (catch 'done
-    (let ((i 0))
-      (while (< i 10)
-        (condition-case nil
-            (throw 'done (multisession--set-value-sqlite object value))
-          (sqlite-locked-error
-           (setq i (1+ i))
-           (sleep-for (+ 0.1 (/ (float (random 10)) 10))))))
-      (signal 'sqlite-locked-error "Database is locked"))))
+  (if (not (sqlite-available-p))
+      (cl-call-next-method)
+    (catch 'done
+      (let ((i 0))
+        (while (< i 10)
+          (condition-case nil
+              (throw 'done (multisession--set-value-sqlite object value))
+            (sqlite-locked-error
+             (setq i (1+ i))
+             (sleep-for (+ 0.1 (/ (float (random 10)) 10))))))
+        (signal 'sqlite-locked-error "Database is locked")))))
 
 (defun multisession--set-value-sqlite (object value)
   (multisession--ensure-db)
@@ -245,16 +249,20 @@ DOC should be a doc string, and ARGS are keywords as applicable to
       (setf (multisession--cached-value object) value))))
 
 (cl-defmethod multisession--backend-values ((_type (eql 'sqlite)))
-  (multisession--ensure-db)
-  (sqlite-select
-   multisession--db
-   "select package, key, value from multisession order by package, key"))
+      (if (not (sqlite-available-p))
+          (cl-call-next-method)
+        (multisession--ensure-db)
+        (sqlite-select
+         multisession--db
+         "select package, key, value from multisession order by package, key")))
 
 (cl-defmethod multisession--backend-delete ((_type (eql 'sqlite)) object)
-  (sqlite-execute multisession--db
-                  "delete from multisession where package = ? and key = ?"
-                  (list (multisession--package object)
-                        (multisession--key object))))
+      (if (not (sqlite-available-p))
+          (cl-call-next-method)
+        (sqlite-execute multisession--db
+                        "delete from multisession where package = ? and key = ?"
+                        (list (multisession--package object)
+                              (multisession--key object)))))
 
 ;; Files Backend