Skip to content

Instantly share code, notes, and snippets.

@a2ndrade
Last active March 1, 2023 09:31
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save a2ndrade/5655005 to your computer and use it in GitHub Desktop.
Save a2ndrade/5655005 to your computer and use it in GitHub Desktop.
Datomic: containment relationships i.e. db/isComponent
(require '[datomic.api :as d])
(def uri "datomic:mem://test")
(d/create-database uri)
(def conn (d/connect uri))
(d/transact conn [;; Article
{:db/id #db/id [:db.part/db]
:db/ident :article/title
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "This article's title"
:db.install/_attribute :db.part/db}
{:db/id #db/id [:db.part/db]
:db/ident :article/comments
:db/valueType :db.type/ref
:db/cardinality :db.cardinality/many
:db/isComponent true
:db/doc "This article's comments"
:db.install/_attribute :db.part/db}
;; Comment
{:db/id #db/id [:db.part/db]
:db/ident :comment/body
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db/doc "This comment's body"
:db.install/_attribute :db.part/db}])
(d/transact conn
[;; A user writing an article
{:db/id #db/id [:db.part/user -100]
:article/title "Monads in Pictures"
{:db/id #db/id [:db.part/user -200]
:comment/body "Great article!"
:article/_comments #db/id [:db.part/user -100]}
{:db/id #db/id [:db.part/user -200]
:comment/body "I like the pictures"
:article/_comments #db/id [:db.part/user -100]}])
;; Find article's comments
(defn find-comments [db article-title]
(d/q '[:find ?c
:in $ ?a
:where
[?aid :article/title ?a]
[?aid :article/comments ?cid]
[?cid :comment/body ?c]]
db article-title))
(defn get-eid [db attr-name attr-value]
(ffirst (d/q '[:find ?e
:in $ ?an ?av
:where
[?e ?an ?av]]
db attr-name attr-value)))
(def article-title "Monads in Pictures")
(find-comments (d/db conn) article-title)
;; > #{["I like the pictures"] ["Great article!"]}
(let [article-id (get-eid (d/db conn) :article/title article-title)]
(d/transact conn [[:db.fn/retractEntity article-id]]))
;; NO comments are left after deleting the article because the
;; :article/comments attribute is defined as a containment
;; relationship i.e. db/isComponent true
(find-comments (d/db conn) article-title)
;; > #{}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment