Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Datomic Database Functions
;; Install boot.
;; In the same folder as this file, run:
;; boot -d com.datomic/datomic-free:0.9.5404 -r $PWD repl
(ns scratch
(:require [datomic.api :as d]))
(d/create-database "datomic:mem://scratch")
(def conn (d/connect "datomic:mem://scratch"))
(def schema
[{:db/id #db/id [:db.part/db]
:db/ident :user/email
:db/valueType :db.type/string
:db/unique :db.unique/identity
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id [:db.part/db]
:db/ident :user/crypted-password
:db/valueType :db.type/string
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}
{:db/id #db/id [:db.part/db]
:db/ident :user/single-use-token
:db/valueType :db.type/string
:db/unique :db.unique/value
:db/cardinality :db.cardinality/one
:db.install/_attribute :db.part/db}])
(d/transact conn schema)
(def crypt identity)
(defn generate-secure-random []
(str (java.util.UUID/randomUUID)))
(d/transact conn [{:db/id (d/tempid :db.part/user)
:user/email "jim@example.com"
:user/crypted-password (crypt "jello4stapler")}
{:db/id (d/tempid :db.part/user)
:user/email "pam@example.com"
:user/crypted-password (crypt "art4evah")}])
(d/transact conn [{:db/id (d/tempid :db.part/user)
:user/email "jim@example.com"
:user/single-use-token (generate-secure-random)}])
(def stale-db (d/db conn))
(def params
{:new-password "newpass"
:token (:user/single-use-token (d/entity stale-db [:user/email "jim@example.com"]))})
(let [{:keys [token new-password]} params
db stale-db
e (d/q '[:find ?e .
:in $ ?token
:where [?e :user/single-use-token ?token]]
db token)]
(if e
(d/transact conn [[:db/add e :user/crypted-password new-password]
[:db/retract e :user/single-use-token token]])))
(let [{:keys [token new-password]} params
db stale-db
e (d/q '[:find ?e .
:in $ ?token
:where [?e :user/single-use-token ?token]]
db token)]
(d/transact conn [[:db/add e :user/crypted-password "somethingelse"]
[:db/retract e :user/single-use-token "WJLKJALK"]]))
(def new-schema
[{:db/id #db/id [:db.part/db]
:db/ident :db.fn/set-with-token
:db/doc "Look up entity by token, set attr and value, and retract token"
:db/fn #db/fn {:lang "clojure"
:params [db token-attr token-value attr value]
:code (let [e (datomic.api/q '[:find ?e .
:in $ ?ta ?tv
:where
[?e ?ta ?tv]]
db token-attr token-value)]
(if e
[[:db/add e attr value]
[:db/retract e token-attr token-value]]
(throw (ex-info "No entity with that token exists"
{token-attr token-value}))))}}
])
(d/transact conn new-schema)
(let [f (:db/fn (d/entity stale-db :db.fn/set-with-token))
{:keys [token new-password]} params]
(f stale-db :user/single-use-token token
:user/crypted-password new-password))
(let [{:keys [token new-password]} params]
@(d/transact conn [[:db.fn/set-with-token :user/single-use-token token
:user/crypted-password new-password]]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment