Skip to content

Instantly share code, notes, and snippets.

@CraZySacX
Created November 11, 2014 20:09
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 CraZySacX/3819a9dc06d7c06b5d79 to your computer and use it in GitHub Desktop.
Save CraZySacX/3819a9dc06d7c06b5d79 to your computer and use it in GitHub Desktop.
Datomic query demo
(comment
; Pull the datomic api into this namespace
(require '[datomic.api :as d])
(require '[glitter.entity.util :refer :all])
; Setup a connection to the transactor
(def conn (d/connect uri))
; Get a database value
(def db-now (d/db conn))
; Find all accounts
(d/q '[:find ?e
:where [?e :account/user]]
db-now)
; The large integers are entity ids. Entity ids are auto-assigned,
; so you may not see the same values on your system. There are several things to note here:
; As query is the most commonly used function in Datomic, it has the terse name d/q.
; The first argument is a query expression. The :where clause indicates what you want to find,
; "those entities ?e that have a :user/email attribute."
; The :find clause tells which variables to return.
; The second argument is the database value we obtained in the previous step.
; Find a specific account
(d/q '[:find ?e
:in $ ?user
:where [?e :account/user ?user]]
db-now
"root")
; Notice that there are now three arguments to the query:
; the query expression plus the two inputs.
; Also, since there are two inputs, there is now an :in clause to name the inputs,
; in the order they appear, e.g. $ binds the database, and ?email binds "editor@example.com".
; Names starting with $ name databases, and names starting with ? name variables.
; Getting an entity
(def user-id (->> (d/q '[:find ?e
:in $ ?user
:where [?e :account/user ?user]]
db-now
"root")
ffirst))
user-id
(def user (d/entity db-now user-id))
; They are lazy
user
; Requesting an attribute from an entity
(:account/user user)
(:account/role user)
(:account/password user)
; If you are feeling more eager, you can touch an entity to immediately realize all of its attributes:
(d/touch user)
; Querying across all time
(def hist (d/history db-now))
(->> (d/q '[:find ?tx ?v ?op
:in $ ?e ?attr
:where [?e ?attr ?v ?tx ?op]]
hist
user-id
:account/user)
(sort-by first))
; Retract an attribute from an entity
(txn [[:db/retract user-id :account/user "root"]])
; Query history.....wait nothing changed.
(->> (d/q '[:find ?tx ?v ?op
:in $ ?e ?attr
:where [?e ?attr ?v ?tx ?op]]
hist
user-id
:account/user)
(sort-by first))
; Need to update hist to use most recent db
(def hist (d/history (d/db conn)))
; There we go. true in op represent and add, false represents a retract
(->> (d/q '[:find ?tx ?v ?op
:in $ ?e ?attr
:where [?e ?attr ?v ?tx ?op]]
hist
user-id
:account/user)
(sort-by first))
; Add back in the attribute with a different value.
(txn [[:db/add user-id :account/user "toor"]])
; Grab the latest db
(def hist (d/history (d/db conn)))
; Now I have 3 transactions on this attribute
(->> (d/q '[:find ?tx ?v ?op
:in $ ?e ?attr
:where [?e ?attr ?v ?tx ?op]]
hist
user-id
:account/user)
(sort-by first))
; Get the entity
(def newuser (d/entity (d/db conn) user-id))
; Touch the entity
(d/touch newuser)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment