Last active
April 27, 2018 15:10
-
-
Save robert-stuttaford/39d43c011e498542bcf8 to your computer and use it in GitHub Desktop.
Handy protocols for working with Datomic
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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Connection | |
(defprotocol DatomicConnection | |
(as-conn [_])) | |
(extend-protocol DatomicConnection | |
datomic.Connection | |
(as-conn [c] c) | |
datomic.db.Db | |
(as-conn ([db] (-> db :id str as-conn))) | |
java.lang.String | |
(as-conn [db-uri] (d/connect db-uri))) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Transaction Log | |
(defprotocol DatomicTransactionLog | |
(as-tx-log [_])) | |
(extend-protocol DatomicTransactionLog | |
datomic.Connection | |
(as-tx-log [c] (d/log c)) | |
datomic.db.Db | |
(as-tx-log [db] (-> db as-conn as-tx-log)) | |
java.lang.String | |
(as-tx-log [s] (-> s as-conn as-tx-log))) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Database | |
(defprotocol DatabaseReference | |
(as-db [_] [_ _])) | |
(def sync-timeout-ms (* 10 1000)) | |
(extend-protocol DatabaseReference | |
datomic.db.Db | |
(as-db | |
([db] db)) | |
datomic.Connection | |
(as-db | |
([conn] (d/db conn)) | |
([conn t] (let [db-value-or-timeout (-> (d/sync conn t) | |
(deref sync-timeout-ms :timeout))] | |
(cond | |
(= (type db-value-or-timeout) datomic.db.Db) | |
db-value-or-timeout | |
(= db-value-or-timeout :timeout) | |
(throw | |
(ex-info "Datomic timed out during sync attempt." | |
{:waited-ms sync-timeout-ms})) | |
:else | |
(throw | |
(ex-info "An unknown error occured while Datomic was trying to sync." | |
{})))))) | |
java.lang.String | |
(as-db | |
([db-uri] (as-db (as-conn db-uri))) | |
([db-uri t] (as-db (as-conn db-uri) t)))) | |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |
;;; Entity | |
(defprotocol EntityReference | |
(id [_]) | |
(entity [_ db])) | |
(extend-protocol EntityReference | |
datomic.query.EntityMap | |
(id [e] (:db/id e)) | |
(entity [e db] e) | |
java.lang.Long | |
(id [id] id) | |
(entity [id db] (d/entity (as-db db) id)) | |
;; these two are for working with maps composed for a transaction | |
clojure.lang.PersistentArrayMap | |
(id [m] (:db/id m)) | |
(entity [m db] (entity (id m) (as-db db))) | |
clojure.lang.PersistentHashMap | |
(id [m] (:db/id m)) | |
(entity [m db] (entity (id m) (as-db db))) | |
;; nice for when working with the output of d/datoms and d/seek-datoms | |
datomic.db.Datum | |
(id [[e]] e) | |
(entity [[e] db] (entity e (as-db db))) | |
;; nice for reaching schema or enum entities quickly, | |
;; however doesn't return a numeral for id like the rest do | |
clojure.lang.Keyword | |
(id [kw] kw) | |
(entity [kw db] (let [db (as-db db)] | |
(entity (d/entid db kw) (as-db db)))) | |
;; these two are when you have a naked entity (or schema entity) id | |
java.lang.Long | |
(id [id] id) | |
(entity [id db] (d/entity (as-db db) id)) | |
java.lang.Integer | |
(id [id] id) | |
(entity [id db] (d/entity (as-db db) id)) | |
;; lookup refs. doesn't work with id, because we don't get the db there. | |
clojure.lang.PersistentVector | |
(id [lookup] (throw "Can't infer id for lookup.")) | |
(entity [lookup db] (d/entity (as-db db) lookup))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment