Skip to content

Instantly share code, notes, and snippets.

@domkm
Created December 16, 2015 07:57
Show Gist options
  • Save domkm/d9e640ae9d04e45af932 to your computer and use it in GitHub Desktop.
Save domkm/d9e640ae9d04e45af932 to your computer and use it in GitHub Desktop.
Datomic EntityMap wrapper for DataScript consistency
;;;; Entity wrapper
#?(:clj (declare ->EntityMap))
#?(:clj (deftype EntityMap [^datomic.query.EntityMap entity ^boolean ident?]
Object
(hashCode [this]
(.hashCode entity))
(equals [this o]
(and (instance? (class this) o)
(.equals entity (.entity o))))
(toString [this]
(.toString entity))
clojure.lang.Associative
(containsKey [this k]
(.containsKey entity k))
(entryAt [this k]
(clojure.lang.MapEntry. k (.get this k)))
;; (assoc [this k v]) ; `datomic.query.EntityMap' does not implement `assoc'
clojure.lang.ILookup
(valAt [this k]
(.get this k))
(valAt [this k default]
(or (.get this k) default))
clojure.lang.IPersistentCollection
(count [this]
(.count entity))
(cons [this o]
(.cons o (.seq this)))
(empty [this]
(->EntityMap (.empty entity) ident?))
(equiv [this o]
(.equals this o))
clojure.lang.Seqable
(seq [this]
(->> (keys entity)
(map #(.entryAt this %))
seq))
datomic.Entity
(db [this]
(.db entity))
(get [this k]
(when-some [v (.get entity k)]
(if (->> (keyword (namespace k) (subs (name k) 1))
(d/attribute (.db entity) )
(or (d/attribute (.db entity) k))
:value-type
(= :db.type/ref))
(letfn [(ent [x]
(if (keyword? x)
(if ident?
x
(->EntityMap (d/entity (.db entity) x) ident?))
(->EntityMap x ident?)))]
(if (set? v)
(into #{} (map ent) v)
(ent v)))
v)))
(keySet [this]
(.keySet entity))
(touch [this]
(->EntityMap (.touch entity) ident?))))
#?(:clj (alter-meta! #'->EntityMap assoc :private true))
#?(:clj (defmethod print-method EntityMap [^EntityMap e ^java.io.Writer w]
(print-method (.entity e) w)))
(s/defn entity
([db eid]
(entity db eid nil))
([db eid {:keys [ident?]
:or {ident? false}}]
#?(:clj
(when-let [e (d/entity db eid)]
(->EntityMap e ident?))
;; DataScript does not yet have idents so ignore this option.
:cljs (d/entity db (if (keyword? eid)
[:db/ident eid]
eid)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment