Teach `java.time.Instant` to Datomic (Cloud) `transact` and `pull`

Since the java.time package is well-designed and built-in to Java 8+ and it’s quite convenient to work with, via juxt/tick, I really wanted to use it with Datomic transparently.

Here is my 1st, seemingly successful attempt, which advises the d/pull and d/transact functions, using the Richelieu library:

(ns xxx.datomic.client
  "Conveniences for working with the `datomic.client.api`."
  (:require
    [datomic.client.api :as d]
    [richelieu.core :refer :all]
    [tick.alpha.api :as t]
    [clojure.walk :as walk]))

(defn- maybe-instant->inst [i] (if (t/instant? i) (t/inst i) i))

(defadvice ^:private transact-instants [transact conn arg-map]
  (transact conn
            (update arg-map :tx-data
                    (partial walk/postwalk maybe-instant->inst))))

(defonce _transact-instants (advise-var #'d/transact #'transact-instants))

(defn- maybe-inst->instant [i] (if (inst? i) (t/instant i) i))

(defadvice ^:private pull-instants
  ([pull db arg-map]
   (->> (pull db arg-map)
        (walk/postwalk maybe-inst->instant)))
  ([pull db selector eid]
   (->> (pull db selector eid)
        (walk/postwalk maybe-inst->instant))))

(defonce _pull-instants (advise-var #'d/pull #'pull-instants))

Here is an example of a java.time.Instant roundtrip to a Datomic DB:

(comment
  (let [client (d/client {:server-type :dev-local
                          :storage-dir :mem
                          :system      "tick"})
        db-ref {:db-name "demo"}
        _ (d/create-database client db-ref)
        conn (d/connect client db-ref)]
    
    (->> [[{:db/ident      :timestamp
            :db/valueType   :db.type/instant
            :db/cardinality :db.cardinality/one}]
          
          [{:db/ident :t1 
            :timestamp (t/now)}]]
         (reduce (fn [c tx] (d/transact c {:tx-data tx}) c) conn))
    
    (d/pull (d/db conn) [:timestamp] :t1))
  )

Please share your thoughts and opinions!

(I’ve seen the GitHub - magnars/java-time-dte: Datomic type extensions for java.time classes library, but that was made for Datomic On-Prem and relied on the internals of Datomic.)

2 Likes

Since I meant to post this on the Datomic forum originally, I dropped a backlink there in this comment on the existing java.time topic: Java.time - #4 by onetom - General - Datomic Developers

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.