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

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

[elpa] externals/triples cd29901fb0 1/4: Allow storage of cons-types


From: ELPA Syncer
Subject: [elpa] externals/triples cd29901fb0 1/4: Allow storage of cons-types
Date: Sun, 16 Apr 2023 00:58:55 -0400 (EDT)

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

    Allow storage of cons-types
    
    This is a form that is a list in lisp, but not stored as in the form where 
each
    element is a row, because it could have inner lists and things like that.  
This
    is meant to store data structures.
---
 triples-test.el | 45 +++++++++++++++++++++++++++++++--------------
 triples.el      | 45 +++++++++++++++++++++++++++++++++------------
 2 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/triples-test.el b/triples-test.el
index 30ae31a6ae..fea404a79e 100644
--- a/triples-test.el
+++ b/triples-test.el
@@ -220,7 +220,9 @@ easily debug into it.")
   (should (triples-test-op-equals
            (triples--set-type-op "Bert" 'named
                                  '(:name "Bertholomew The Second"
-                                         :alias ("Bert" "Berty")))
+                                         :alias ("Bert" "Berty"))
+                                 '((name :base/type string :base/unique t)
+                                   (alias :base/type string :base/unique nil)))
            '(replace-subject-type
              .
              (("Bert" base/type named)
@@ -229,15 +231,18 @@ easily debug into it.")
               ("Bert" named/alias "Berty" (:index 1)))))))
 
 (ert-deftest triples-schema-compliant ()
-  (triples-test-with-temp-db
-    (triples-add-schema db 'named
-                        '(name :base/unique t :base/type string)
-                        'alternate-names)
-    (triples-set-type db "foo" 'named :name "name")
-    (should (triples-verify-schema-compliant db '(("foo" named/name "bar"))))
-    (should-error (triples-verify-schema-compliant db '(("foo" named/name 5))))
-    (should-error (triples-verify-schema-compliant db '(("foo" named/name 
"bar" (:index 0)))))
-    (should (triples-verify-schema-compliant db '(("foo" named/alternate-names 
"bar" (:index 0)))))))
+  (let ((pal '((named/name :base/type string :base/unique t)
+               (named/alternate-names :base/type string :base/unique nil)
+               ;; Alias doesn't specify base/unique or base/type, so anything 
is fine.
+               (named/alias))))
+    (should (triples-verify-schema-compliant '(("foo" named/name "bar")) pal))
+    (should-error (triples-verify-schema-compliant '(("foo" named/name 5)) 
pal))
+    (should-error (triples-verify-schema-compliant '(("foo" named/name "bar" 
(:index 0))) pal))
+    (should (triples-verify-schema-compliant '(("foo" named/alternate-names 
"bar" (:index 0))) pal))
+    (should-error (triples-verify-schema-compliant '(("foo" 
named/alternate-names "bar" nil)) pal))
+    (should (triples-verify-schema-compliant '(("foo" named/alias "bar" nil)) 
pal))
+    (should (triples-verify-schema-compliant '(("foo" named/alias 5 nil)) pal))
+    (should (triples-verify-schema-compliant '(("foo" named/alias 5 (:index 
0))) pal))))
 
 (defun triples-test-plist-sort (plist)
   "Sort PLIST in a standard way, for comparison."
@@ -268,7 +273,7 @@ easily debug into it.")
   (triples-test-with-temp-db
     (triples-add-schema db 'named
                         '(name :base/unique t))
-    (triples-add-schema db 'positioned '(position :/base/unique t))
+    (triples-add-schema db 'positioned '(position :base/unique t))
     (should-not (triples-get-subject db "foo"))
     (triples-set-subject db "foo"
                          '(named :name "bar")
@@ -281,7 +286,7 @@ easily debug into it.")
 (ert-deftest triples-set-types ()
   (triples-test-with-temp-db
     (triples-add-schema db 'named
-                        '(name :/base/unique t)
+                        '(name :base/unique t)
                        'alias)
     (triples-add-schema db 'reachable 'phone)
     (triples-set-type db "foo" 'named :name "Name" :alias '("alias1" "alias2"))
@@ -316,6 +321,18 @@ easily debug into it.")
                   (triples-get-type db "foo" 'embedding)))
    (should-error (triples-set-type db "foo" 'embedding :embedding '(1 2 3)))))
 
+(ert-deftest triples-cons ()
+  (triples-test-with-temp-db
+   (triples-add-schema db 'data '(data :base/unique t :base/type cons))
+   (triples-set-type db "foo" 'data :data '(a (b c)))
+   (should (equal '(:data (a (b c)))
+                  (triples-get-type db "foo" 'data)))
+   (should (= 1 (length (triples-db-select db nil 'data/data))))
+   ;; Let's also make sure if we store it as a straight list triples doesn't 
get
+   ;; confused and try to store it as separate rows in the db.
+   (triples-set-type db "foo" 'data :data '(a b c))
+   (should (= 1 (length (triples-db-select db nil 'data/data))))))
+
 (ert-deftest triples-reversed ()
   (triples-test-with-temp-db
    (triples-add-schema db 'named
@@ -367,8 +384,8 @@ easily debug into it.")
 
 (ert-deftest triples-move-subject ()
   (triples-test-with-temp-db
-   (triples-add-schema db 'named '(name))
-   (triples-add-schema db 'friend '(id))
+   (triples-add-schema db 'named '(name :base/unique t))
+   (triples-add-schema db 'friend '(id :base/unique t))
    (triples-set-subject db 123 '(named :name "Ada Lovelace"))
    (triples-set-subject db 456 '(named :name "Michael Faraday")
                         '(friend :id 123))
diff --git a/triples.el b/triples.el
index aa03450eb7..817d7b6d02 100644
--- a/triples.el
+++ b/triples.el
@@ -379,12 +379,14 @@ merged into NEW-SUBJECT."
   (mapcar #'car
           (triples-db-select db type 'schema/property nil nil '(object))))
 
-(defun triples-verify-schema-compliant (db triples)
-  "Error if TRIPLES is not compliant with schema in DB."
+(defun triples-verify-schema-compliant (triples prop-schema-alist)
+  "Error if TRIPLES is not compliant with schema in PROP-SCHEMA-ALIST.
+PROP-SCHEMA-ALIST is an alist of the relevant properties to the
+data stored, in combined type/property form, and their schema
+definitions."
   (mapc (lambda (triple)
-          (pcase-let ((`(,type . ,prop) (triples-combined-to-type-and-prop 
(nth 1 triple))))
-            (unless (or (eq type 'base)
-                        (triples-db-select db type 'schema/property prop nil))
+          (pcase-let ((`(,type . ,_) (triples-combined-to-type-and-prop (nth 1 
triple))))
+            (unless (or (eq type 'base) (assoc (nth 1 triple) 
prop-schema-alist))
               (error "Property %s not found in schema" (nth 1 triple)))))
         triples)
   (mapc (lambda (triple)
@@ -393,7 +395,7 @@ merged into NEW-SUBJECT."
                                                           (triples--decolon 
pred-prop)))))
                                  (if (fboundp f)
                                      (funcall f val triple))))
-                             (triples-properties-for-predicate db (nth 1 
triple)))) triples))
+                               (cdr (assoc (nth 1 triple) 
prop-schema-alist)))) triples))
 
 (defun triples-add-schema (db type &rest props)
   "Add schema for TYPE and its PROPS to DB."
@@ -424,8 +426,21 @@ them."
 (defun triples-set-type (db subject type &rest properties)
   "Create operation to replace PROPERTIES for TYPE for SUBJECT in DB.
 PROPERTIES is a plist of properties, without TYPE prefixes."
-  (let ((op (triples--set-type-op subject type properties)))
-    (triples-verify-schema-compliant db (cdr op))
+  (let* ((prop-schema-alist
+          (mapcar (lambda (prop)
+                    (cons (triples--decolon prop)
+                          (triples-properties-for-predicate
+                           db
+                           (triples-type-and-prop-to-combined type prop))))
+                  (triples--plist-mapcar (lambda (k _) k) properties)))
+         (op (triples--set-type-op subject type properties prop-schema-alist)))
+    (triples-verify-schema-compliant
+     (cdr op)
+     ;; triples-verify-schema-compliant can act on triples from many types, so
+     ;; we have to include the type information in our schema property alist.
+     (mapcar (lambda (c)
+               (cons (triples-type-and-prop-to-combined type (car c))
+                     (cdr c))) prop-schema-alist))
     (triples--add db op)))
 
 (defmacro triples-with-transaction (db &rest body)
@@ -473,21 +488,27 @@ given in the COMBINED-PROPS will be removed."
       (cl-loop for k being the hash-keys of type-to-plist using (hash-values v)
                do (apply #'triples-set-type db subject k v)))))
 
-(defun triples--set-type-op (subject type properties)
+(defun triples--set-type-op (subject type properties type-schema)
   "Create operation to replace PROPERTIES for TYPE for SUBJECT.
-PROPERTIES is a plist of properties, without TYPE prefixes."
+PROPERTIES is a plist of properties, without TYPE prefixes.
+TYPE-SCHEMA is an alist of property symbols to their schema,
+which is necessary to understand when lists are supposed to be
+broken down into separate rows, and when to leave as is."
   (cons 'replace-subject-type
         (cons (list subject 'base/type type)
               (triples--plist-mapcan
                (lambda (prop v)
-                 (if (listp v)
+                 (let ((prop-schema (cdr (assoc (triples--decolon prop) 
type-schema))))
+                   (if (and
+                        (listp v)
+                        (not (plist-get prop-schema :base/unique)))
                      (cl-loop for e in v for i from 0
                               collect
                               (list subject
                                     (triples-type-and-prop-to-combined type 
prop)
                                     e
                                     (list :index i)))
-                   (list (list subject (triples-type-and-prop-to-combined type 
prop) v))))
+                   (list (list subject (triples-type-and-prop-to-combined type 
prop) v)))))
                properties))))
 
 (defun triples-get-type (db subject type)



reply via email to

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