Bläddra i källkod

enhance: allow user properties with other namespaces

to allow for imported properties to have a different namespace than the
one the editor generates. Update schema example graph which now imports
properties as :schema.property/X
Gabriel Horner 1 år sedan
förälder
incheckning
8f411fad42

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

@@ -23,9 +23,9 @@
   [:or logseq-property-ident db-attribute-ident])
 
 (defn- user-property?
-  "Determines if keyword is a user property"
+  "Determines if keyword/ident is a user property"
   [kw]
-  (contains? db-property/user-property-namespaces (namespace kw)))
+  (db-property/user-property-namespace? (namespace kw)))
 
 (def user-property-ident
   [:and :keyword [:fn
@@ -357,7 +357,7 @@
    (map (fn [[prop-type value-schema]]
           [prop-type
            (let [schema-fn (if (vector? value-schema) (last value-schema) value-schema)]
-             [:fn (with-meta #(validate-property-value %1 schema-fn %2) {:add-db true})])])
+             [: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

+ 16 - 9
deps/db/src/logseq/db/frontend/property.cljs

@@ -216,8 +216,10 @@
   [kw]
   (contains? logseq-property-namespaces (namespace kw)))
 
-(def user-property-namespaces
-  #{"user.property"})
+(defn user-property-namespace?
+  "Determines if namespace string is a user property"
+  [s]
+  (string/includes? s ".property"))
 
 (defn property?
   "Determines if ident kw is a property"
@@ -225,7 +227,7 @@
   (let [k-name (namespace k)]
     (and k-name
          (or (contains? logseq-property-namespaces k-name)
-             (contains? user-property-namespaces k-name)
+             (user-property-namespace? k-name)
              (and (keyword? k) (contains? db-attribute-properties k))))))
 
 ;; Helper fns
@@ -282,13 +284,13 @@
                 e))) values)))
 
 ;; TODO: db ident should obey clojure's rules for keywords
-(defn create-user-property-ident-from-name
-  "Creates a user property :db/ident from a name by sanitizing the given name.
+(defn create-db-ident-from-name
+  "Creates a :db/ident by sanitizing the given name.
 
-   NOTE: Only use this when creating a db-ident for a property name. Using this
+   NOTE: Only use this when creating a db-ident for a string name. Using this
    in read-only contexts like querying can result in db-ident conflicts"
-  [property-name]
-  (let [n (-> property-name
+  [user-namespace name-string]
+  (let [n (-> name-string
               (string/replace #"(^:\s*|\s*:$)" "")
               (string/replace #"\s*:\s*$" "")
               (string/replace-first #"^\d+" "")
@@ -296,7 +298,12 @@
               (string/replace "#" "")
               (string/trim))]
     (assert (seq n) "name is not empty")
-    (keyword "user.property" n)))
+    (keyword user-namespace n)))
+
+(defn create-user-property-ident-from-name
+  "Creates a property :db/ident for a default user namespace"
+  [property-name]
+  (create-db-ident-from-name "user.property" property-name))
 
 (defn get-class-ordered-properties
   [class-entity]

+ 11 - 6
scripts/src/logseq/tasks/db_graph/create_graph.cljs

@@ -138,7 +138,7 @@
                                     {:db/id (or (property-db-ids (name prop-name))
                                                 (throw (ex-info "No :db/id for property" {:property prop-name})))}}))
                                 [(merge
-                                  (sqlite-util/build-new-property prop-name
+                                  (sqlite-util/build-new-property (get-ident all-idents prop-name)
                                                                   (:block/schema prop-m)
                                                                   {:block-uuid (:block/uuid prop-m)})
                                   {:db/id (or (property-db-ids (name prop-name))
@@ -185,14 +185,15 @@
      and the values are maps of datascript attributes e.g. `{:block/schema {:type :checkbox}}`.
      An additional key `:closed-values` is available to define closed values. The key takes
      a vec of maps containing keys :uuid, :value and :icon.
+  * :graph-namespace - namespace to use for db-ident creation. Useful when importing an ontology
 
-   The :properties for :pages-and-blocks is a map of property names to property
+   The :properties in :pages-and-blocks is a map of property names to property
    values.  Multiple property values for a many cardinality property are defined
    as a set. The following property types are supported: :default, :url,
    :checkbox, :number, :page and :date. :checkbox and :number values are written
-   as booleans and integers. :page and :block are references that are written as
-   vectors e.g. `[:page \"PAGE NAME\"]` and `[:block \"block content\"]`"
-  [{:keys [pages-and-blocks properties] :as options}]
+   as booleans and integers/floats. :page references are written as
+   vectors e.g. `[:page \"PAGE NAME\"]`"
+  [{:keys [pages-and-blocks properties graph-namespace] :as options}]
   (let [_ (validate-options options)
         ;; add uuids before tx for refs in :properties
         pages-and-blocks' (mapv (fn [{:keys [page blocks]}]
@@ -203,7 +204,11 @@
         uuid-maps (create-uuid-maps pages-and-blocks')
         ;; TODO: How to detect these idents don't conflict with existing? :db/add?
         all-idents (->> (keys properties)
-                        (map #(vector % (db-property/create-user-property-ident-from-name (name %))))
+                        (map #(vector %
+                                      (if graph-namespace
+                                        (db-property/create-db-ident-from-name (str (name graph-namespace) ".property")
+                                                                               (name %))
+                                        (db-property/create-user-property-ident-from-name (name %)))))
                         (into {}))
         _ (assert (= (count (set (vals all-idents))) (count properties))
                   "All db-idents must be unique")

+ 2 - 1
scripts/src/logseq/tasks/db_graph/create_graph_with_schema_org.cljs

@@ -345,7 +345,8 @@
         pages (generate-pages
                (map #(class-map %) select-class-ids)
                class-uuids class-to-properties property-uuids options')]
-    {:pages-and-blocks pages
+    {:graph-namespace :schema
+     :pages-and-blocks pages
      :properties properties}))
 
 (def spec

+ 1 - 1
src/main/frontend/components/property/value.cljs

@@ -713,7 +713,7 @@
       :on-click (fn []
                   (when (and (= type :default) (nil? value))
                     (<create-new-block! block property ""))
-                  (when (and (= type :string))
+                  (when (= type :string)
                     (set-editing! block property editor-id dom-id value opts)))}
      (if (and (string/blank? value) template?)
        (let [id (first (:classes schema))