Sfoglia il codice sorgente

fix: add back properties validation

and fix closed validation. Also temporarily comment out properties graph parts
that are still invalid
Gabriel Horner 1 anno fa
parent
commit
608d627544

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

@@ -16,8 +16,9 @@
 
 (defn validate-client-db
   "Validate datascript db as a vec of entity maps"
-  [db ent-maps {:keys [verbose group-errors closed-maps]}]
-  (let [schema (db-validate/update-schema db-malli-schema/DB db {:closed-schema? closed-maps})]
+  [db ent-maps* {:keys [verbose group-errors closed-maps]}]
+  (let [ent-maps (db-malli-schema/update-properties-in-ents ent-maps*)
+        schema (db-validate/update-schema db-malli-schema/DB db {:closed-schema? closed-maps})]
     (if-let [errors (->> ent-maps
                          (m/explain schema)
                          :errors)]

+ 35 - 3
deps/db/src/logseq/db/frontend/malli_schema.cljs

@@ -3,7 +3,9 @@
   (:require [clojure.walk :as walk]
             [clojure.string :as string]
             [logseq.db.frontend.schema :as db-schema]
-            [logseq.db.frontend.property.type :as db-property-type]))
+            [logseq.db.frontend.property.type :as db-property-type]
+            [datascript.core :as d]
+            [logseq.db.frontend.property :as db-property]))
 
 ;; Helper fns
 ;; ==========
@@ -28,11 +30,25 @@
                        (let [[property-type schema-fn] e
                              schema-fn' (if (db-property-type/property-types-with-db property-type) (partial schema-fn db) schema-fn)
                              validation-fn #(validate-property-value property-type schema-fn' %)]
-                         [property-type [:tuple :entity [:fn validation-fn]]])
+                         ;; TODO: Be more specific about :keyword
+                         [property-type [:tuple :keyword [:fn validation-fn]]])
                        :else
                        e)))
                  db-schema))
 
+(defn update-properties-in-ents
+  "Prepares properties in entities to be validated by DB schema"
+  [ents]
+  (mapv
+   (fn [ent]
+     (reduce (fn [m [k v]]
+               (if (db-property/property? k)
+                 (update m :block/properties (fnil conj []) [k v])
+                 (assoc m k v)))
+             {}
+             ent))
+   ents))
+
 (defn datoms->entity-maps
   "Returns entity maps for given :eavt datoms"
   [datoms]
@@ -46,14 +62,30 @@
 ;; Malli schemas
 ;; =============
 ;; These schemas should be data vars to remain as simple and reusable as possible
+(def property-tuple
+  "Represents a tuple of a property and its property value. This schema
+   has 2 metadata hooks which are used to inject a datascript db later"
+  (into
+   [:multi {:dispatch ^:add-db (fn [db property-tuple]
+                                 (get-in (d/entity db (first property-tuple))
+                                         [:block/schema :type]))}]
+   (map (fn [[prop-type value-schema]]
+          ^:property-value [prop-type (if (vector? value-schema) (last value-schema) value-schema)])
+        db-property-type/built-in-validation-schemas)))
+
+(def block-properties
+  "Validates a slightly modified version of :block/properties. Properties are
+  expected to be 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])
 
-;; FIXME: validate properties
 (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]]
+   [: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]]

+ 3 - 4
deps/db/src/logseq/db/frontend/validate.cljs

@@ -23,7 +23,7 @@
   [{:keys [db-after tx-data tx-meta]} validate-options]
   (let [changed-ids (->> tx-data (map :e) distinct)
         ent-maps* (->> changed-ids (mapcat #(d/datoms db-after :eavt %)) db-malli-schema/datoms->entity-maps vals)
-        ent-maps (vec ent-maps*)
+        ent-maps (db-malli-schema/update-properties-in-ents ent-maps*)
         db-schema (update-schema db-malli-schema/DB db-after validate-options)
         explain-result (m/explain db-schema ent-maps)]
     (js/console.log "changed eids:" changed-ids tx-meta)
@@ -68,9 +68,8 @@
   [db]
   (let [datoms (d/datoms db :eavt)
         ent-maps* (db-malli-schema/datoms->entity-maps datoms)
-        ent-maps (vec (vals ent-maps*))
-        ;; FIXME: Fix validation for closed-schema? true
-        schema (update-schema db-malli-schema/DB db {:closed-schema? false})
+        ent-maps (db-malli-schema/update-properties-in-ents (vals ent-maps*))
+        schema (update-schema db-malli-schema/DB db {:closed-schema? true})
         errors (->> ent-maps (m/explain schema) :errors)]
     (cond-> {:datom-count (count datoms)
              :entities ent-maps}

+ 6 - 4
scripts/src/logseq/tasks/db_graph/create_graph_with_properties.cljs

@@ -60,7 +60,8 @@
         random-page-closed-value #(let [val (-> closed-values-config % rand-nth :value)]
                                     (swap! closed-values assoc % (second val))
                                     val)
-        get-closed-value #(get @closed-values %)]
+        ;; TODO: Remove default when page-closed/date-closed re-enabled
+        get-closed-value #(get @closed-values % "")]
     {:pages-and-blocks
      ;; Journals
      [{:page
@@ -88,11 +89,12 @@
         {:block/content "number-closed property block" :properties {:number-closed (random-closed-value :number-closed)}}
         {:block/content "page property block" :properties {:page [:page "page 1"]}}
         {:block/content "page-many property block" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}}
-        {:block/content "page-closed property block" :properties {:page-closed (random-page-closed-value :page-closed)}}
+        ;; TODO: Fix page-closed and date-closed
+        #_{:block/content "page-closed property block" :properties {:page-closed (random-page-closed-value :page-closed)}}
         {:block/content "date property block" :properties {:date [:page (date-journal-title today)]}}
         {:block/content "date-many property block" :properties {:date-many #{[:page (date-journal-title today)]
                                                                              [:page (date-journal-title yesterday)]}}}
-        {:block/content "date-closed property block" :properties {:date-closed (random-page-closed-value :date-closed)}}]}
+        #_{:block/content "date-closed property block" :properties {:date-closed (random-page-closed-value :date-closed)}}]}
       {:page {:block/original-name "Block Property Queries"}
        :blocks
        [{:block/content "{{query (property :default \"haha\")}}"}
@@ -132,7 +134,7 @@
       {:page {:block/name "number-closed page" :properties {:number-closed (random-closed-value :number-closed)}}}
       {:page {:block/name "page page" :properties {:page [:page "page 1"]}}}
       {:page {:block/name "page-many page" :properties {:page-many #{[:page "page 1"] [:page "page 2"]}}}}
-      {:page {:block/name "page-closed page" :properties {:page-closed (random-page-closed-value :page-closed)}}}
+      #_{:page {:block/name "page-closed page" :properties {:page-closed (random-page-closed-value :page-closed)}}}
       {:page {:block/name "date page" :properties {:date [:page (date-journal-title today)]}}}
       {:page {:block/name "date-many page" :properties {:date-many #{[:page (date-journal-title today)]
                                                                      [:page (date-journal-title yesterday)]}}}}