emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[elpa] externals/triples 2dae3d49b9 18/19: Various fixes for emacsql cod


From: ELPA Syncer
Subject: [elpa] externals/triples 2dae3d49b9 18/19: Various fixes for emacsql code, which wasn't being tested correctly.
Date: Sat, 5 Nov 2022 11:58:17 -0400 (EDT)

branch: externals/triples
commit 2dae3d49b9e0846f63a64eae19a5fe0facd7a3aa
Author: Andrew Hyatt <ahyatt@gmail.com>
Commit: Andrew Hyatt <ahyatt@gmail.com>

    Various fixes for emacsql code, which wasn't being tested correctly.
---
 triples-test.el | 52 ++++++++++++++++++--------------
 triples.el      | 92 ++++++++++++++++++++++++++++++++-------------------------
 2 files changed, 81 insertions(+), 63 deletions(-)

diff --git a/triples-test.el b/triples-test.el
index a9c635218c..04217193e9 100644
--- a/triples-test.el
+++ b/triples-test.el
@@ -30,11 +30,11 @@ easily debug into it.")
     (sql-sqlite (format "*schema test db SQL %s*" triples-test-db-file))))
 
 (defun triples-test-insert (mode)
-  (let ((triples--sqlite-interface mode))
+  (let ((triples-sqlite-interface mode))
     (triples-test-with-temp-db
       (triples--insert db "sub" 'pred "obj")
-      (should (equal (triples--select db)
-                     '(("sub" pred "obj" nil))))
+      (should (equal (mapcar (lambda (row) (seq-take row 3)) (triples--select 
db))
+                     '(("sub" pred "obj"))))
       ;; Test that we actually are storing with builtin something compatible
       ;; with emacsql.
       (when (eq mode 'builtin)
@@ -50,11 +50,15 @@ easily debug into it.")
       (should-error (triples--insert db "sub" "pred" "obj"))
       (should-error (triples--insert db "sub" 'pred "obj" '(ordinary-list)))
       (should-error (triples--insert db "sub" 'pred "obj" "string"))
-      ;; Test that we can have symbol subject and objects
+      ;; Test that we can have symbol subject and objects.
       (triples--insert db 'sub 'pred 'obj)
       (should (equal
-               (triples--select db 'sub)
-               '((sub pred obj nil)))))))
+               (mapcar (lambda (row) (seq-take row 3)) (triples--select db 
'sub))               
+               '((sub pred obj))))
+      ;; Test that properties aren't strings. They happen to be stored
+      ;; differently for each system due to differences in how the inserting
+      ;; interface works.
+      (should (plistp (nth 3 (car (triples--select db 'sub))))))))
 
 (ert-deftest triples-test-insert-builtin ()
   (skip-unless (and (fboundp 'sqlite-available-p) (sqlite-available-p)))
@@ -65,7 +69,7 @@ easily debug into it.")
   (triples-test-insert 'emacsql))
 
 (defun triples-test-delete (mode)
-  (let ((triples--sqlite-interface mode))
+  (let ((triples-sqlite-interface mode))
     (triples-test-with-temp-db
      (triples--insert db 1 'pred 2)
      (triples--insert db 2 'pred 1)
@@ -88,7 +92,7 @@ easily debug into it.")
   (triples-test-delete 'emacsql))
 
 (defun triples-test-delete-subject-predicate-prefix (mode)
-  (let ((triples--sqlite-interface mode))
+  (let ((triples-sqlite-interface mode))
     (triples-test-with-temp-db
      (triples--insert db 1 'test/foo 2)
      (triples--insert db 1 'bar/bar 1)
@@ -107,17 +111,19 @@ easily debug into it.")
   (triples-test-delete-subject-predicate-prefix 'emacsql))
 
 (defun triples-test-select (mode)
-  (let ((triples--sqlite-interface mode))
+  (let ((triples-sqlite-interface mode))
     (triples-test-with-temp-db
-     (triples--insert db 1 'pred 2 '(:a 1))
-     (let ((expected '((1 pred 2 (:a 1)))))
-       (should (equal (triples--select db 1) expected))
-       (should (equal (triples--select db nil 'pred) expected))
-       (should (equal (triples--select db nil nil 2) expected))
-       (should (equal (triples--select db 1 nil 2) expected))
-       (should (equal (triples--select db 1 'pred 2) expected))
-       (should (equal '((1)) (triples--select db 1 nil nil nil '(subject))))
-       (should (equal '((1 pred)) (triples--select db 1 nil nil nil '(subject 
predicate))))))))
+      (when (eq mode 'emacsql)
+          (emacsql-enable-debugging db))
+      (triples--insert db 1 'pred 2 '(:a 1))
+      (let ((expected '((1 pred 2 (:a 1)))))
+        (should (equal (triples--select db 1) expected))
+        (should (equal (triples--select db nil 'pred) expected))
+        (should (equal (triples--select db nil nil 2) expected))
+        (should (equal (triples--select db 1 nil 2) expected))
+        (should (equal (triples--select db 1 'pred 2) expected))
+        (should (equal '((1)) (triples--select db 1 nil nil nil '(subject))))
+        (should (equal '((1 pred)) (triples--select db 1 nil nil nil '(subject 
predicate))))))))
 
 (ert-deftest triples-test-select-builtin ()
   (skip-unless (and (fboundp 'sqlite-available-p) (sqlite-available-p)))
@@ -128,7 +134,7 @@ easily debug into it.")
   (triples-test-select 'emacsql))
 
 (defun triples-test-select-with-pred-prefix (mode)
-  (let ((triples--sqlite-interface mode))
+  (let ((triples-sqlite-interface mode))
     (triples-test-with-temp-db
      (triples--insert db 'sub1 'pred/foo 'obj)
      (triples--insert db 'sub1 'pred/bar 'obj)
@@ -146,11 +152,13 @@ easily debug into it.")
   (triples-test-select 'emacsql))
 
 (defun triples-test-select-predicate-object-fragment (mode)
-  (let ((triples--sqlite-interface mode))
+  (let ((triples-sqlite-interface mode))
     (triples-test-with-temp-db
      (triples--insert db 'sub1 'pred/foo "a whole phrase")
-     (should (equal (triples--select-predicate-object-fragment db 'pred/foo 
"whole")
-                    '((sub1 pred/foo "a whole phrase" nil)))))))
+     (should (equal
+              (mapcar (lambda (row) (seq-take row 3))
+                      (triples--select-predicate-object-fragment db 'pred/foo 
"whole"))
+              '((sub1 pred/foo "a whole phrase")))))))
 
 (ert-deftest triples-test-select-predicate-object-fragment-builtin ()
   (skip-unless (and (fboundp 'sqlite-available-p) (sqlite-available-p)))
diff --git a/triples.el b/triples.el
index b005ce381e..ce0c920b08 100644
--- a/triples.el
+++ b/triples.el
@@ -55,7 +55,7 @@ installed.")
     (error "The triples package requires either Emacs 29 or the emacsql 
package to be installed."))
   (pcase triples-sqlite-interface
     ('builtin (let* ((db (sqlite-open file)))
-                (sqlite-execute db "CREATE TABLE IF NOT EXISTS triples(subject 
TEXT NOT NULL, predicate TEXT NOT NULL, object TEXT, properties TEXT NOT NULL)")
+                (sqlite-execute db "CREATE TABLE IF NOT EXISTS triples(subject 
TEXT NOT NULL, predicate TEXT NOT NULL, object NOT NULL, properties TEXT NOT 
NULL)")
                 (sqlite-execute db "CREATE INDEX IF NOT EXISTS subject_idx ON 
triples (subject)")
                 (sqlite-execute db "CREATE INDEX IF NOT EXISTS 
subject_predicate_idx ON triples (subject, predicate)")
                 (sqlite-execute db "CREATE INDEX IF NOT EXISTS 
predicate_object_idx ON triples (predicate, object)")
@@ -66,13 +66,13 @@ installed.")
      (let* ((db (emacsql-sqlite file))
             (triple-table-exists
              (emacsql db [:select name
-                                  :from sqlite_master
-                                  :where (= type table) :and (= name 
'triples)])))
+                          :from sqlite_master
+                          :where (= type table) :and (= name 'triples)])))
        (unless triple-table-exists
-         (emacsql db [:create-table triples ([(subject text :not-null)
+         (emacsql db [:create-table triples ([(subject :not-null)
                                               (predicate text :not-null)
                                               (object :not-null)
-                                              (properties)])])
+                                              (properties text :not-null)])])
          (emacsql db [:create-index subject_idx :on triples [subject]])
          (emacsql db [:create-index subject_predicate_idx :on triples [subject 
predicate]])
          (emacsql db [:create-index predicate_object_idx :on triples 
[predicate object]])
@@ -139,8 +139,11 @@ normal schema checks, so should not be called from client 
programs."
                            ;; duplicate triples each with null properties.
                            (triples-standardize-val properties))))
     ('emacsql
+     ;; We use a simple small plist '(:t t). Unlike sqlite, we can't insert 
this
+     ;; as a string, or else it will store as something that would come out as 
a
+     ;; string.  And if we use nil, it will actually store a NULL in the cell.
      (emacsql db [:replace :into triples :values $v1]
-              [subject predicate object (triples-standardize-val 
properties)]))))
+              (vector subject (triples--decolon predicate) object (or 
properties '(:t t)))))))
 
 (defun triples--emacsql-andify (wc)
   "In emacsql where clause WC, insert `:and' between query elements.
@@ -174,18 +177,21 @@ all to nil, everything will be deleted, so be careful!"
                                                     (when properties 
"PROPERTIES = ?")))
                                   " AND "))))
                (mapcar #'triples-standardize-val (seq-filter #'identity (list 
subject predicate object properties)))))
-    ('emacsql (emacsql db
-                       (apply #'vector
-                              (append '(:delete :from triples)
-                                      (when (or subject predicate object 
properties)
-                                        (triples--emacsql-andify 
-                                         (append
-                                          '(:where)
-                                          (when subject '((= subject $s1)))
-                                          (when predicate '((= predicate $r2)))
-                                          (when object '((= object $s3)))
-                                          (when properties '((= properties 
$r4))))))))
-                       (seq-filter #'identity (list subject predicate object 
properties))))))
+    ('emacsql
+     (let ((n 0))
+       (apply #'emacsql
+              db
+              (apply #'vector
+                     (append '(:delete :from triples)
+                             (when (or subject predicate object properties)
+                               (triples--emacsql-andify 
+                                (append
+                                 '(:where)
+                                 (when subject `((= subject ,(intern (format 
"$s%d" (cl-incf n))))))
+                                 (when predicate `((= predicate ,(intern 
(format "$s%d" (cl-incf n))))))
+                                 (when object `((= object ,(intern (format 
"$s%d" (cl-incf n))))))
+                                 (when properties `((= properties ,(intern 
(format "$s%d" (cl-incf n)))))))))))
+              (seq-filter #'identity (list subject predicate object 
properties)))))))
 
 (defun triples--delete-subject-predicate-prefix (db subject pred-prefix)
   "Delete triples matching SUBJECT and predicates with PRED-PREFIX."
@@ -215,7 +221,7 @@ all to nil, everything will be deleted, so be careful!"
                       (sqlite-select db "SELECT * from triples WHERE predicate 
= ? AND object LIKE ?"
                                      (list (triples-standardize-val predicate)
                                            (format "%%%s%%" 
object-fragment)))))
-    ('emacsql (emacsql db [:select * :from triples :where (= predicate $r1) 
:and (like object $s2)]
+    ('emacsql (emacsql db [:select * :from triples :where (= predicate $s1) 
:and (like object $s2)]
                        predicate (format "%%%s%%" object-fragment)))))
 
 (defun triples--select (db &optional subject predicate object properties 
selector)
@@ -240,21 +246,23 @@ object, properties to retrieve or nil for *."
                                                                           
(when properties "PROPERTIES = ?")))
                                                         " AND "))))
                                      (mapcar #'triples-standardize-val 
(seq-filter #'identity (list subject predicate object properties))))))
-    ('emacsql (emacsql db (apply #'vector
-                                 (append `(:select
-                                           ,(if selector
-                                                (mapconcat (lambda (e) (format 
"%s" e)) selector ", ")
-                                              '*)
-                                           :from triples)
-                                         (when (or subject predicate object 
properties)
-                                           (triples--emacsql-andify 
-                                            (append
-                                             '(:where)
-                                             (when subject '((= subject $s1)))
-                                             (when predicate '((= predicate 
$r2)))
-                                             (when object '((= object $s3)))
-                                             (when properties '((= properties 
$r4))))))))
-                       (seq-filter #'identity (list subject predicate object 
properties))))))
+    ('emacsql
+     (let ((n 0))
+       (apply #'emacsql
+              db
+              (apply #'vector
+                     (append `(:select
+                               ,(if selector (apply #'vector selector) '*)
+                               :from triples)
+                             (when (or subject predicate object properties)
+                               (triples--emacsql-andify 
+                                (append
+                                 '(:where)
+                                 (when subject `((= subject ,(intern (format 
"$s%d" (cl-incf n))))))
+                                 (when predicate `((= predicate ,(intern 
(format "$s%d" (cl-incf n))))))
+                                 (when object `((= object ,(intern (format 
"$s%d" (cl-incf n))))))
+                                 (when properties `((= properties ,(intern 
(format "$s%d" (cl-incf n)))))))))))
+              (seq-filter #'identity (list subject predicate object 
properties)))))))
 
 ;; Code after this point should not call sqlite or emacsql directly. If any 
more
 ;; calls are needed, put them in a defun, make it work for sqlite and emacsql,
@@ -361,13 +369,15 @@ PROPERTIES is a plist of properties, without TYPE 
prefixes."
 The transaction will abort if an error is thrown."
   (declare (indent 0) (debug t))
   (let ((db-var (gensym "db")))
-    `(let ((,db-var ,db))
-       (condition-case nil
-           (progn
-             (sqlite-transaction ,db-var)
-             ,@body
-             (sqlite-commit ,db-var))  
-         (error (sqlite-rollback ,db-var))))))
+    (pcase triples-sqlite-interface
+      ('builtin  `(let ((,db-var ,db))
+                    (condition-case nil
+                        (progn
+                          (sqlite-transaction ,db-var)
+                          ,@body
+                          (sqlite-commit ,db-var))  
+                      (error (sqlite-rollback ,db-var)))))
+      ('emacsql `(emacsql-with-transaction ,db ,@body)))))
 
 (defun triples-set-types (db subject &rest combined-props)
   "Set all data for types in COMBINED-PROPS in DB for SUBJECT.



reply via email to

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