Fork me on GitHub
#datomic
<
2022-09-25
>
Dustin Getz18:09:52

(extend-protocol ccp/Datafiable
  Datum
  (datafy [^Datum [e a v tx op]] [e a v tx op]))
Has anyone done this work already, a contrib library for Datomic and Datomic Cloud to integrate obvious stuff?

onetom17:10:00

i also have a similar utility for testing purposes:

;; FIXME this should be supported more directly by matcher combinators
(defn datum->map [datum]
  (into {} (map #(vector % (% datum))) [:e :a :v :tx :added]))

Dustin Getz18:09:07

I'm developing a web-based tool that lets Datomic users (both Cloud and Onprem) browse their database. Is there a standard or contributed set of specs to capture Datomic connection strings and configuration data that feels something like shadow-cljs.edn?

onetom16:10:53

i'd be interested in such a tool too... i've also started to develop some puget pretty-printing conveniences for datoms and transaction results, but it's quite clunky, because there are differences between the client configs, eg:

(defn basis-t
  "Return the basis T of a db-val, regardless of its concrete implementation."
  [db-val]
  (or (-> db-val :basisT)               ;; (d/client {:server-type :dev-local})
      (-> db-val :t)                    ;; (d/client {:server-type :cloud}) or :ion
      ))

onetom17:10:27

or

(defn database-id
  "Return the database ID of a db-val, regardless of its concrete
   implementation."
  [db-val]
  (let [db-uuid-or-name
        (or
          ;; (d/client {:server-type :dev-local :storage-dir :mem})
          (-> db-val :id)

          ;; (d/client {:server-type :cloud}) or :ion
          (-> db-val :database-id))]

    (try (medley/uuid db-uuid-or-name)
         db-uuid-or-name
         (catch Exception _ex
           ;; (d/client {:server-type :dev-local :storage-dir "/some/path"})
           ;; Such mode of operation doesn't seem to assign a UUID to databases,
           ;; so we hard-wire some, based on the name of possible databases.
           (-> {"db1" "25f0edda-69ae-4f52-b1b0-3c9ce83ac84e"
                "db2" "0f2aa132-c388-4ed7-ba92-3a2710e16965"}
               (get db-uuid-or-name))))))
which database-id we are using to detect db reconstructions, because we store references to db values at a certain point in time in other datomic dbs...

Dustin Getz17:10:12

how far would this get you

(extend-protocol ccp/Datafiable
  Datum
  (datafy [^Datum [e a v tx op]] [e a v tx op]))

Dustin Getz17:10:37

etc for various internal types and protocols

onetom01:10:29

I still hasn't grasped the essence of datafy & nav, so it hasn't occurred to me to utilize those, but probably quite far. can u recommend any datafy & nav tutorials, besides https://corfield.org/blog/2018/12/03/datafy-nav/ ?

Dustin Getz01:10:15

i posted a next journal notebook on reddit showing datafy on java io file

Dustin Getz01:10:21

it's quite simple - it's like implementing pr-str on a reference type but instead of printing as a string you're printing as a value

onetom01:10:56

thx, i will dig it up! im mostly confused by how nav behaves:

(let [x (datafy {:a 1})]
    [(nav x :a 1)
     (nav x :a 2)
     (nav x :b 1)
     (nav x :b 3)
     (nav x nil 1)
     (nav x nil 2)])

onetom02:10:23

these all navs all return the same value i passed in, eg. [1 2 1 3 1 2]

onetom02:10:41

though i should probably do, if i understand nav correctly:

(let [x (datafy {:a 1})]
    [(nav x :a (get x :a))
     (nav x :a (get x :a))
     (nav x :b (get x :b))
     (nav x :b (get x :b))
     (nav x nil (get x nil))
     (nav x nil (get x nil))])

onetom02:10:58

which yields [1 1 nil nil nil nil]

Dustin Getz02:10:54

nav is unintuitive bc datafy already gave you the k and v, nav is an opportunity to undo the datafy and return the underlying reference. if there is no underlying reference then nav is just weird identity

👍 1
Dustin Getz02:10:38

you're meant to thus bounce between datafy and nav like in the last test in that notebook