branch: elpa/gnosis
commit 218324738447749cdb405b01def7385f1bd2adc7
Author: Thanos Apollo <[email protected]>
Commit: Thanos Apollo <[email protected]>

    [Refactor] deduplicate add-thema helper functions.
---
 gnosis.el | 211 ++++++++++++++++++--------------------------------------------
 1 file changed, 60 insertions(+), 151 deletions(-)

diff --git a/gnosis.el b/gnosis.el
index a470d291f9..cb4ba991c4 100644
--- a/gnosis.el
+++ b/gnosis.el
@@ -958,8 +958,9 @@ LINKS: List of id links."
 If gnosis ID does not exist, create it anew.
 When `gnosis--id-cache' is bound, uses hash table for existence check."
   (let* ((id (if (stringp id) (string-to-number id) id))
-        (current-type (gnosis-get 'type 'themata `(= id ,id)))
-        (current-deck (gnosis-get 'deck-id 'themata `(= id ,id))))
+        (current (car (gnosis-select '[type deck-id] 'themata `(= id ,id))))
+        (current-type (nth 0 current))
+        (current-deck (nth 1 current)))
     (if (if gnosis--id-cache
            (gethash id gnosis--id-cache)
          (member id (gnosis-select 'id 'themata nil t)))
@@ -988,56 +989,44 @@ When `gnosis--id-cache' is bound, uses hash table for 
existence check."
 ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-(defun gnosis-add-thema--basic (id deck-id type keimenon hypothesis
-                                  answer parathema tags suspend links)
-  "Default format for adding a thema.
-
-ID: Thema ID.
-DECK-ID: Integer value of deck-id.
-TYPE: String representing the type of thema.
-KEIMENON: String for the thema text.
-HYPOTHESIS: List of a single string.
-ANSWER: List of a single string.
-PARATHEMA: String for the parathema text.
-TAGS: List of thema tags.
-SUSPEND: Integer value of 0 for nil and 1 for true (suspended).
-LINKS: List of id links in PARATHEMA."
+(defun gnosis-add-thema--assert-common (deck-id keimenon tags suspend links)
+  "Assert common fields shared by all thema types.
+DECK-ID, KEIMENON, TAGS, SUSPEND, and LINKS are validated."
   (cl-assert (integerp deck-id) nil "Deck-id value must be an integer.")
-  (cl-assert (stringp type) nil "Type must be a string.")
   (cl-assert (stringp keimenon) nil "Keimenon must be a string.")
-  (cl-assert (or (null hypothesis)
-                (and (listp hypothesis)
-                     (= (length hypothesis) 1)))
-            nil "Hypothesis value must be a list of a single item or nil.")
-  (cl-assert (and (listp answer)
-                 (= (length answer) 1))
-            nil "Answer value must be a list of a single item")
-  (cl-assert (listp tags) nil "Tags must be a list.")
-  (cl-assert (or (= suspend 0)
-                (= suspend 1))
-            nil "Suspend value must either 0 or 1")
-  (cl-assert (listp links) nil "Links must be a list")
+  (cl-assert (and (listp tags) (cl-every #'stringp tags)) nil "Tags must be a 
list of strings.")
+  (cl-assert (memq suspend '(0 1)) nil "Suspend value must be 0 or 1.")
+  (cl-assert (and (listp links) (cl-every #'stringp links)) nil "Links must be 
a list of strings."))
+
+(defun gnosis-add-thema--dispatch (id deck-id type keimenon hypothesis
+                                     answer parathema tags suspend links)
+  "Dispatch thema creation or update for ID.
+When ID is \"NEW\", create via `gnosis-add-thema-fields'.
+Otherwise, update via `gnosis-update-thema'."
   (if (equal id "NEW")
       (gnosis-add-thema-fields deck-id type keimenon (or hypothesis (list ""))
                               answer parathema tags suspend links)
     (gnosis-update-thema id keimenon hypothesis answer parathema tags links 
deck-id type)))
 
+(defun gnosis-add-thema--basic (id deck-id type keimenon hypothesis
+                                  answer parathema tags suspend links)
+  "Add or update a basic thema."
+  (gnosis-add-thema--assert-common deck-id keimenon tags suspend links)
+  (cl-assert (or (null hypothesis)
+                (and (listp hypothesis) (= (length hypothesis) 1)))
+            nil "Hypothesis must be a list of a single item or nil.")
+  (cl-assert (and (listp answer) (= (length answer) 1))
+            nil "Answer must be a list of a single item.")
+  (gnosis-add-thema--dispatch id deck-id type keimenon hypothesis
+                             answer parathema tags suspend links))
+
 (defun gnosis-add-thema--double (id deck-id type keimenon hypothesis
                                    answer parathema tags suspend links)
-  "Double thema format.
-
-Changes TYPE to basic & inserts a second basic thema with ANSWER
-and KEIMENON reversed."
-  (cl-assert (integerp deck-id) nil "Deck-id value must be an integer.")
-  (cl-assert (stringp type) nil "Type must be a string.")
-  (cl-assert (stringp keimenon) nil "Keimenon must be a string.")
-  (cl-assert (listp hypothesis) nil "Hypothesis value must be a list.")
+  "Add a double thema (two basic themata with reversed Q/A)."
+  (gnosis-add-thema--assert-common deck-id keimenon tags suspend links)
+  (cl-assert (listp hypothesis) nil "Hypothesis must be a list.")
   (cl-assert (and (listp answer) (= (length answer) 1))
-            nil "Answer value must be a list of a single item")
-  (cl-assert (listp tags) nil "Tags must be a list.")
-  (cl-assert (or (= suspend 0) (= suspend 1)) nil "Suspend value must either 0 
or 1")
-  (cl-assert (listp links) nil "Links must be a list")
-  ;; Change type to basic
+            nil "Answer must be a list of a single item.")
   (let ((type "basic")
        (hypothesis (or hypothesis (list ""))))
     (if (equal id "NEW")
@@ -1046,142 +1035,60 @@ and KEIMENON reversed."
                                   answer parathema tags suspend links)
          (gnosis-add-thema-fields deck-id type (car answer) hypothesis
                                   (list keimenon) parathema tags suspend 
links))
-      ;; There should not be a double type thema in database to
-      ;; update.  This is used for testing purposes.
       (gnosis-update-thema id keimenon hypothesis answer parathema tags links 
deck-id type))))
 
 (defun gnosis-add-thema--mcq (id deck-id type keimenon hypothesis
                                answer parathema tags suspend links)
-  "Helper function for MCQ thema type.
-
-Provide assertions for MCQ type themata.
-
-DECK-ID: ID for deck.
-ID: Integer for thema ID.
-TYPE: String for type, must be \"mcq\".
-HYPOTHESIS: List of strings or nil, hypothesis in MCQ thema types
-serve as choices to select from.
-ANSWER: List of one time, the right answer.  Must be member of
-HYPOTHESIS.
-TAGS: List of tags.
-PARATHEMA: Parathema for THEMA.
-SUSPEND: integer value, 1 or 0.
-LINKS: list of strings."
-  (cl-assert (integerp deck-id) nil "Deck-id value must be an integer.")
-  (cl-assert (string= type "mcq") nil "TYPE value must be \"mcq\".")
-  (cl-assert (stringp keimenon) nil "Keimenon must be a string.")
-  (cl-assert (and (listp hypothesis)
-                 (> (length hypothesis) 1))
-            nil "Hypothesis value must be a list greater than 1 item.")
-  (cl-assert (and (listp answer)
-                 (= (length answer) 1)
+  "Add or update an MCQ thema."
+  (gnosis-add-thema--assert-common deck-id keimenon tags suspend links)
+  (cl-assert (string= type "mcq") nil "TYPE must be \"mcq\".")
+  (cl-assert (and (listp hypothesis) (> (length hypothesis) 1))
+            nil "Hypothesis must be a list of more than 1 item.")
+  (cl-assert (and (listp answer) (= (length answer) 1)
                  (member (car answer) hypothesis))
-            nil "Answer value must be a single item, member of the Hypothesis")
-  (cl-assert (and (listp tags)
-                 (cl-every 'stringp tags))
-            nil "Tags must be a list.")
-  (cl-assert (or (= suspend 0)
-                (= suspend 1))
-            nil "Suspend value must either 0 or 1")
-  (cl-assert (and (listp links)
-                 (cl-every 'stringp links))
-            nil "Links must be a list")
-  (if (equal id "NEW")
-      (gnosis-add-thema-fields deck-id type keimenon (or hypothesis (list ""))
-                             answer parathema tags suspend links)
-    (gnosis-update-thema id keimenon hypothesis answer parathema tags links 
deck-id type)))
+            nil "Answer must be a single item, member of hypothesis.")
+  (gnosis-add-thema--dispatch id deck-id type keimenon hypothesis
+                             answer parathema tags suspend links))
 
 (defun gnosis-add-thema--cloze (id deck-id type keimenon hypothesis
                                  answer parathema tags suspend links)
-  "Helper for cloze type themata.
-
-Provide assertions for cloze type themata.
-
-DECK-ID: ID for deck.
-ID: Integer for thema ID.
-TYPE: String for type, must be \"cloze\".
-HYPOTHESIS: List of strings or nil, hypothesis in cloze thema types
-serve as hints.
-ANSWER: List of answers for clozes.
-TAGS: List of tags.
-PARATHEMA: Parathema for thema.
-SUSPEND: integer value, 1 or 0.
-LINKS: list of strings."
-  (cl-assert (integerp deck-id) nil "Deck-id value must be an integer.")
-  (cl-assert (string= type "cloze") nil "Type for cloze type must be 
\"cloze\".")
-  (cl-assert (stringp keimenon) nil "Keimenon must be a string.")
-  (cl-assert (or (>= (length answer) (length hypothesis))
-                (null hypothesis))
-            nil
-            "Hypothesis value must be a list or nil, less or equal in length 
of Answer.")
-  (cl-assert (listp answer) nil "Answer value must be a list.")
-  (cl-assert (and (listp tags)
-                 (cl-every 'stringp tags))
-            nil "Tags must be a list of strings..")
-  (cl-assert (or (= suspend 0)
-                (= suspend 1))
-            nil "Suspend value must either 0 or 1")
-  (cl-assert (and (listp links)
-                 (cl-every 'stringp links))
-            nil "Links must be a list")
+  "Add or update a cloze thema."
+  (gnosis-add-thema--assert-common deck-id keimenon tags suspend links)
+  (cl-assert (string= type "cloze") nil "TYPE must be \"cloze\".")
+  (cl-assert (or (null hypothesis) (>= (length answer) (length hypothesis)))
+            nil "Hypothesis length must not exceed answer length.")
+  (cl-assert (listp answer) nil "Answer must be a list.")
   (cl-assert (gnosis-cloze-check keimenon answer) nil
-            "Clozes (answer) values are not part of keimenon")
+            "Cloze answers are not part of keimenon.")
   (let ((keimenon-clean (gnosis-cloze-remove-tags keimenon)))
     (if (equal id "NEW")
        (if (null answer)
-           ;; if answer is left null, extract all contents from keimenon.
            (let* ((contents (gnosis-cloze-extract-contents keimenon))
                   (clozes (gnosis-cloze-extract-answers contents))
                   (hints (gnosis-cloze-extract-hints contents)))
              (cl-loop for cloze in clozes
                       for hint in hints
-                      do
-                      (gnosis-add-thema-fields deck-id type keimenon-clean 
hint cloze parathema
-                                               tags suspend links)))
+                      do (gnosis-add-thema-fields deck-id type keimenon-clean 
hint cloze
+                                                  parathema tags suspend 
links)))
          (gnosis-add-thema-fields deck-id type keimenon-clean (or hypothesis 
(list ""))
                                   answer parathema tags suspend links))
       (gnosis-update-thema id keimenon-clean hypothesis answer parathema tags 
links deck-id type))))
 
 (defun gnosis-add-thema--mc-cloze (id deck-id type keimenon hypothesis
                                  answer parathema tags suspend links)
-  "Helper for mc-cloze type themata.
-
-Provide assertions for mc-cloze type themata.
-
-DECK-ID: ID for deck.
-ID: Integer for thema ID.
-TYPE: String for type, must be \"mc-cloze\".
-HYPOTHESIS: List of strings or nil, hypothesis in mc-cloze thema types
-serve as answer options.
-ANSWER: List of answers for mc-clozes.
-TAGS: List of tags.
-PARATHEMA: Parathema for thema.
-SUSPEND: integer value, 1 or 0.
-LINKS: list of strings."
-  (cl-assert (integerp deck-id) nil "Deck-id value must be an integer.")
-  (cl-assert (string= type "mc-cloze") nil "TYPE value must be \"mc-cloze\" .")
-  (cl-assert (stringp keimenon) nil "Keimenon must be a string.")
-  (cl-assert (and (listp hypothesis)
-                 (> (length hypothesis) (length answer)))
-            nil "Hypothesis value must be a list, greater in length of 
ANSWER.")
+  "Add or update an mc-cloze thema."
+  (gnosis-add-thema--assert-common deck-id keimenon tags suspend links)
+  (cl-assert (string= type "mc-cloze") nil "TYPE must be \"mc-cloze\".")
+  (cl-assert (and (listp hypothesis) (> (length hypothesis) (length answer)))
+            nil "Hypothesis must be a list, longer than answer.")
   (cl-assert (and (listp answer) (length= answer 1)
                  (member (car answer) hypothesis))
-            nil
-            "ANSWER value must be a list of one item.")
-  (cl-assert (and (listp tags)
-                 (cl-every 'stringp tags))
-            nil "Tags must be a list of strings.")
-  (cl-assert (or (= suspend 0)
-                (= suspend 1))
-            nil "Suspend value must either 0 or 1")
-  (cl-assert (listp links) nil "Links must be a list")
+            nil "Answer must be a list of one item, member of hypothesis.")
   (cl-assert (gnosis-cloze-check keimenon answer) nil
-            "Clozes (answer) values are not part of keimenon")
+            "Cloze answers are not part of keimenon.")
   (let ((keimenon-clean (gnosis-cloze-remove-tags keimenon)))
-    (if (equal id "NEW")
-       (gnosis-add-thema-fields deck-id type keimenon-clean (or hypothesis 
(list ""))
-                                answer parathema tags suspend links)
-      (gnosis-update-thema id keimenon-clean hypothesis answer parathema tags 
links deck-id type))))
+    (gnosis-add-thema--dispatch id deck-id type keimenon-clean hypothesis
+                               answer parathema tags suspend links)))
 
 ;;;###autoload
 (defun gnosis-add-thema (deck type &optional keimenon hypothesis
@@ -1705,6 +1612,8 @@ Reopens the gnosis database after successful pull."
          (when (zerop (process-exit-status proc))
           (condition-case err
               (progn
+                (when (and gnosis-db (emacsql-live-p gnosis-db))
+                  (emacsql-close gnosis-db))
                 (setf gnosis-db
                        (emacsql-sqlite-open (expand-file-name "gnosis.db" 
gnosis-dir)))
                 (gnosis-db-init)

Reply via email to