Skip to content

Instantly share code, notes, and snippets.

@n2o
Last active May 26, 2017 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n2o/3e76598769386c47d2d3ed2b925f24e2 to your computer and use it in GitHub Desktop.
Save n2o/3e76598769386c47d2d3ed2b925f24e2 to your computer and use it in GitHub Desktop.
Basic datomic scheme, some transactions and queries

There are only few tutorials showing a step-by-step guide for datomic. This Gist might give you some exemplary code to get started with this interesting type of database.


Require the datomic api from [com.datomic/datomic-pro "0.9.5561"]:

(require '[datomic.api :refer [q transact] :as d])

Establish a connection to a local datomic database:

(def db-uri "datomic:mem://hello")
(d/create-database db-uri)
(def conn (d/connect db-uri))

Definitions

Definining some schemes for our database:

(def title {:db/ident :statement/title
            :db/valueType :db.type/string
            :db/cardinality :db.cardinality/one
            :db/doc "The title of the statement"})
(def author {:db/ident :statement/author
             :db/valueType :db.type/ref
             :db/cardinality :db.cardinality/one
             :db/doc "Original author of this statement"})
(def origin {:db/ident :statement/origin
             :db/valueType :db.type/string
             :db/cardinality :db.cardinality/one
             :db/doc "Where does this statement come from?"})

(def statement-schema [title author origin])

(def author-name {:db/ident :author/name
                  :db/valueType :db.type/string
                  :db/cardinality :db.cardinality/one
                  :db/doc "The author's name"})
(def author-mail {:db/ident :author/mail
                  :db/valueType :db.type/string
                  :db/cardinality :db.cardinality/one
                  :db/doc "The author's email address"})

(def author-schema [author-name author-mail])

Now transact them:

@(transact conn statement-schema)
@(transact conn author-schema)

Seed

Fill database with some data:

(def authors [{:author/name "Christian"
               :author/mail "i@mgro.ot"}
              {:author/name "Mario"
               :author/mail "your@preten.do"}])
@(transact conn authors)

(def statements [{:statement/title "Häschen sin' schwach"
                  :statement/author (author-id-by-name "Christian")
                  :statement/origin "hhu.de"}
                 {:statement/title "Flauschige Tiere sind schwach"
                  :statement/author (author-id-by-name "Christian")
                  :statement/origin "hhu.de"}])
@(transact conn statements)

@(transact conn [{:statement/title "Raubkatzen sind auch flauschig"
                  :statement/author (author-id-by-name "Mario")
                  :statement/origin "hhu.de"}])

Query functions

Get current view on the database:

(def db (d/db conn))

And define some query functions working on our sample data:

(defn author-id-by-name [author-name]
  (ffirst (q '[:find ?e
               :in $ ?author
               :where [?e :author/name ?author]]
             db, author-name)))
;; (author-id-by-name "Christian")
;; => 17592186045442

(defn author-name-by-id [id]
  (ffirst (q '[:find ?name
               :in $ ?id
               :where [?id author/name ?name]]
             db, id)))
;; (author-name-by-id (author-id-by-name "Christian"))
;; => Christian

(defn statement-id-by-title [title]
  (q '[:find ?e
       :in $ ?title
       :where [?e :statement/title ?title]]
     db, title))
;; (statement-id-by-title "Häschen sin' schwach")
;; => #{[17592186045426]}

(defn statements-with-authors []
  (q '[:find (pull ?e [:statement/title :statement/origin {:statement/author [:author/name :author/mail]}])
       :where [?e :statement/author]]
     db))
;; (statements-with-authors)
;; => [[[#:statement{:title "Häschen sin' schwach",
;;                   :origin "hhu.de",
;;                   :author #:author{:name "Christian", :mail "i@mgro.ot"}}]
;;      [#:statement{:title "Flauschige Tiere sind schwach",
;;                   :origin "hhu.de",
;;                   :author #:author{:name "Christian", :mail "i@mgro.ot"}}]
;;      [#:statement{:title "Raubkatzen sind auch flauschig",
;;                   :origin "hhu.de",
;;                   :author #:author{:name "Mario", :mail "your@preten.do"}}]]

(defn statements-by-author-name [author-name]
  (q '[:find ?e ?title
       :in $ ?author
       :where
       [?a :author/name ?author]
       [?e :statement/author ?a]
       [?e :statement/title ?title]]
     db, author-name))
;; (statements-by-author-name "Christian")
;; #{[17592186045427 "Flauschige Tiere sind schwach"] [17592186045446 "Häschen sin' schwach"]}

Everything can act as a database!

(q '[:find ?v
     :in [[?k ?v]]
     :where [(.endsWith ?k "path")]]
   (System/getProperties))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment