Created
April 10, 2024 13:41
-
-
Save tiensonqin/929b6affb8fd6a07723c53a8d0c9678f to your computer and use it in GitHub Desktop.
Property key-value pairs as entities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(def conn (d/create-conn {:db/ident {:db/unique :db.unique/identity} | |
:block/uuid {:db/unique :db.unique/identity} | |
:block/content {} | |
:block/properties {:db/valueType :db.type/ref | |
:db/cardinality :db.cardinality/many | |
:db/isComponent true} | |
:property-value/property {:db/valueType :db.type/ref}})) | |
;; Add internal properties | |
(d/transact! conn [{:db/ident :logseq.property/created-by | |
:db/cardinality :db.cardinality/one | |
:db/index true}]) | |
(d/transact! conn [{:db/ident :logseq.property/order | |
:db/cardinality :db.cardinality/one | |
:db/index true}]) | |
;; Add user properties | |
(d/transact! conn [{:db/ident :user.property/foo | |
:db/cardinality :db.cardinality/one | |
:db/index true}]) | |
(d/transact! conn [{:db/ident :user.property/bar | |
:db/cardinality :db.cardinality/one | |
:db/index true}]) | |
;; set :user.property/foo for a block | |
(d/transact! conn [{:db/id 10 | |
:block/uuid (random-uuid) | |
:block/content "block 1" | |
:block/properties {:property-value/property :user.property/foo | |
:user.property/foo "block-1-foo-value" | |
:logseq.property/created-by "user-1-ref" | |
:logseq.property/order 1}}]) | |
(d/transact! conn [{:db/id 10 | |
:block/properties {:property-value/property :user.property/bar | |
:user.property/bar "block-1-bar-value" | |
:logseq.property/created-by "user-1-ref" | |
:logseq.property/order 2}}]) | |
;; add another block | |
(d/transact! conn [{:db/id 100 | |
:block/uuid (random-uuid) | |
:block/content "block 2" | |
:block/properties {:property-value/property :user.property/foo | |
:user.property/foo "block-2-foo-value" | |
:logseq.property/created-by "user-1-ref" | |
:logseq.property/order 1}}]) | |
(d/transact! conn [{:db/id 100 | |
:block/properties {:property-value/property :user.property/bar | |
:user.property/bar "block-2-bar-value" | |
:logseq.property/created-by "user-1-ref" | |
:logseq.property/order 2}}]) | |
(def block-1 (d/entity @conn 10)) | |
(def block-2 (d/entity @conn 100)) | |
;; get property keys from block 1 | |
(map (comp :db/ident :property-value/property) (:block/properties block-1)) | |
;; => (:user.property/foo :user.property/bar) | |
;; query block-1's value for :user.property/foo | |
(->> (:block/properties block-1) | |
(filter #(some? (:user.property/foo %))) | |
(map :user.property/foo)) | |
;; => ("block-1-foo-value") | |
;; Get all the blocks' values for :user.property/foo | |
(map :v (d/datoms @conn :avet :user.property/foo)) | |
;; ("block-1-foo-value" "block-2-foo-value") | |
;; Delete :user.property/foo from block-1 | |
(let [values (->> (:block/properties block-1) | |
(keep (fn [e] (when (some? (:user.property/foo e)) (:db/id e)))))] | |
(d/transact! conn (map (fn [id] [:db/retractEntity id]) values))) | |
(assert (= 1 (count (:block/properties (d/entity @conn 10))))) | |
;; Delete :user.property/bar globally | |
(let [property-value-entities (map :e (d/datoms @conn :avet :user.property/bar))] | |
;; Delete property value entities first | |
(d/transact! conn (map (fn [id] [:db/retractEntity id]) property-value-entities)) | |
;; Delete property itself | |
(d/transact! conn [[:db/retractEntity :user.property/bar]]) | |
;; TODO: also need to handle [:block/schema :properties] for classes | |
) | |
(assert (= 0 (count (:block/properties (d/entity @conn 10))))) | |
;; Delete a block should remove all of its :block/properties entities because of defined `:db/isComponent` | |
(:tx-data (d/transact! conn [[:db/retractEntity 100]])) | |
(assert (empty? (d/datoms @conn :avet :user.property/foo))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment