Explorar o código

fix: validate property values again

caused by property pair revert 5d4ae66d864db228a4bee228a21fcaa49d74f7f4
Gabriel Horner hai 1 ano
pai
achega
670b46f221

+ 2 - 1
deps/db/script/validate_client_db.cljs

@@ -4,6 +4,7 @@
   (:require [logseq.db.sqlite.db :as sqlite-db]
             [logseq.db.frontend.malli-schema :as db-malli-schema]
             [logseq.db.frontend.validate :as db-validate]
+            [logseq.db.frontend.property :as db-property]
             [datascript.core :as d]
             [clojure.string :as string]
             [nbb.core :as nbb]
@@ -83,7 +84,7 @@
                                (count (filter #(contains? (:block/type %) "class") ent-maps)) " classes, "
                                (count (filter #(seq (:block/tags %)) ent-maps)) " objects, "
                                (count (filter #(contains? (:block/type %) "property") ent-maps)) " properties and "
-                               (count (filter :property/pair-property ent-maps)) " property pairs"))
+                               (count (mapcat db-property/properties ent-maps)) " property pairs"))
     (validate-client-db @conn ent-maps options)))
 
 (defn -main [argv]

+ 51 - 52
deps/db/src/logseq/db/frontend/malli_schema.cljs

@@ -88,20 +88,25 @@
   "Prepares properties in entities to be validated by DB schema"
   [db ents]
   (mapv
-   #(if-let [property (some->> (:property/pair-property %) (d/entity db))]
-      (assoc % :property-tuple
-             [(assoc (select-keys property [:db/ident :db/valueType])
-                     :block/schema
-                     (select-keys (:block/schema property) [:type :cardinality :values]))
-              (get % (:db/ident property))])
-      %)
+   (fn [ent]
+     (reduce (fn [m [k v]]
+               (if-let [property (and (db-property/property? k)
+                                      (d/entity db k))]
+                 (update m :block/properties (fnil conj [])
+                         [(assoc (select-keys property [:db/ident :db/valueType])
+                                 :block/schema
+                                 (select-keys (:block/schema property) [:type :cardinality :values]))
+                          v])
+                 (assoc m k v)))
+             {}
+             ent))
    ents))
 
 (defn datoms->entity-maps
   "Returns entity maps for given :eavt datoms indexed by db/id. Optional keys:
    * :entity-fn - Optional fn that given an entity id, returns entity. Defaults
-     to just doing a lookup within entity-maps to be as performant as possible"
-  [datoms & {:keys [_entity-fn]}]
+     to just doing a lookup based on existing entity-maps to be as performant as possible"
+  [datoms & {:keys [entity-fn]}]
   (let [ent-maps
         (reduce (fn [acc {:keys [a e v]}]
                   (if (contains? db-schema/card-many-attributes a)
@@ -114,23 +119,23 @@
                       (update acc e assoc a v))))
                 {}
                 datoms)
-        ;; entity-fn' (or entity-fn #(get ent-maps %))
-        ]
-    ent-maps
-    ;; (-> ent-maps
-    ;;     (update-vals
-    ;;      (fn [v]
-    ;;        (let [pair-ent (when (:property/pair-property v) (entity-fn' (:property/pair-property v)))]
-    ;;          (if-let [prop-value
-    ;;                   (and pair-ent
-    ;;                        (= :db.cardinality/many (:db/cardinality pair-ent))
-    ;;                        (get v (:db/ident pair-ent)))]
-    ;;            (if-not (set? prop-value)
-    ;;              ;; Fix :many property values that only had one value
-    ;;              (assoc v (:db/ident pair-ent) #{prop-value})
-    ;;              v)
-    ;;            v)))))
-    ))
+        entity-fn' (or entity-fn
+                       (let [db-ident-maps (dissoc (into {} (map (juxt :db/ident identity) (vals ent-maps))) nil)]
+                         #(get db-ident-maps %)))]
+    (-> ent-maps
+        (update-vals
+         (fn [m]
+           (->> m
+                (map (fn [[k v]]
+                       (if-let [property (and (db-property/property? k)
+                                              (entity-fn' k))]
+                         (if (and (= :db.cardinality/many (:db/cardinality property))
+                                  (not (set? v)))
+                           ;; Fix :many property values that only had one value
+                           [k #{v}]
+                           [k v])
+                         [k v])))
+                (into {})))))))
 
 (defn datoms->entities
   "Returns a vec of entity maps given :eavt datoms"
@@ -142,12 +147,31 @@
 ;; ==================
 ;; These schemas should be data vars to remain as simple and reusable as possible
 
+(def property-tuple
+  "A tuple of a property map and a property value. This schema
+   has 1 metadata hook which is used to inject a datascript db later"
+  (into
+   [:multi {:dispatch #(-> % first :block/schema :type)}]
+   (map (fn [[prop-type value-schema]]
+          [prop-type
+           (let [schema-fn (if (vector? value-schema) (last value-schema) value-schema)]
+             [:fn (with-meta (fn [db tuple] (validate-property-value db schema-fn tuple)) {:add-db true})])])
+        db-property-type/built-in-validation-schemas)))
+
+(def block-properties
+  "Validates a block's properties as property pairs. Properties are
+  a vector of tuples instead of a map in order to validate each
+  property with its property value that is valid for its type"
+  [:sequential property-tuple])
+
 (def page-or-block-attrs
   "Common attributes for page and normal blocks"
   [[:block/uuid :uuid]
    [:block/created-at :int]
    [:block/updated-at :int]
    [:block/format [:enum :markdown]]
+   ;; Injected by update-properties-in-ents
+   [:block/properties {:optional true} block-properties]
    [:block/refs {:optional true} [:set :int]]
    [:block/tags {:optional true} [:set :int]]
    [:block/collapsed-properties {:optional true} [:set :int]]
@@ -355,28 +379,6 @@
    [:graph/uuid :string]
    [:graph/local-tx :string]])
 
-(def property-tuple
-  "A tuple of a property map and a property value. This schema
-   has 1 metadata hook which is used to inject a datascript db later"
-  (into
-   [:multi {:dispatch #(-> % first :block/schema :type)}]
-   (map (fn [[prop-type value-schema]]
-          [prop-type
-           (let [schema-fn (if (vector? value-schema) (last value-schema) value-schema)]
-             [:fn (with-meta (fn [db tuple] (validate-property-value db schema-fn tuple)) {:add-db true})])])
-        db-property-type/built-in-validation-schemas)))
-
-(def property-pair
-  [:map
-   ;; Not closed because property value key is different with every property
-   {:closed false}
-   [:property/pair-property :int]
-   [:block/created-at :int]
-   [:block/updated-at :int]
-   ;; Injected by update-properties-in-ents
-   [:property-tuple property-tuple]
-   [:block/tx-id {:optional true} :int]])
-
 (def db-ident-key-val
   "A key-val map consists of a :db/ident and a specific key val"
   (into [:or]
@@ -417,8 +419,6 @@
                           :file-block
                           (:block/uuid d)
                           :block
-                          (:property/pair-property d)
-                          :property-pair
                           (:asset/uuid d)
                           :asset-block
                           (= (:db/ident d) :logseq.property/empty-placeholder)
@@ -432,7 +432,6 @@
     :block block
     :file-block file-block
     :db-ident-key-value db-ident-key-val
-    :property-pair property-pair
     :asset-block asset-block
     :property-value-placeholder property-value-placeholder}))
 
@@ -454,7 +453,7 @@
                          (string/join ", " undeclared-ref-attrs))
                     {}))))
 
-(let [malli-one-ref-attrs (->> (concat class-attrs page-attrs block-attrs page-or-block-attrs (rest normal-page) (rest property-pair))
+(let [malli-one-ref-attrs (->> (concat class-attrs page-attrs block-attrs page-or-block-attrs (rest normal-page))
                                (filter #(= (last %) :int))
                                (map first)
                                set)