https://github.com/vvvvalvalval/datomock.git
git clone 'https://github.com/vvvvalvalval/datomock.git'
(ql:quickload :vvvvalvalval.datomock)
Mocking and forking Datomic connections in-memory.
Notes:
db.with(tx)
) and Clojure's managed references (atoms)Project maturity: beta quality. Note that you will probably not need to use this library in production.
(require '[datomic.api :as d])
(require '[datomock.core :as dm])
(def my-conn (d/connect "datomic:mem://hello-world"))
;; ... create a mock connection from a Database value:
(def starting-point-db (d/db my-conn))
(def mocked-conn (dm/mock-conn starting-point-db))
;; which is essentially the same as:
(def mocked-conn (dm/fork-conn my-conn))
;; dm/fork-conn is likely what you'll use most.
Mocked connections use Datomic's speculative writes (db.with()
) and Clojure's managed references to emulate a Datomic connection locally.
The main benefit is the ability to ‘fork’ Datomic connections.
More precisely, if conn1
is forked from conn2
:
* at the time of forking, conn1
and conn2
hold the same database value;
* subsequent writes to conn1
will leave conn2
unaffected
* subsequent writes to conn2
will leave conn1
unaffected
Because Datomic database values are persistent data structures, forking is extremely cheap in both space and time.
Essentially, by putting a Datomic Database value in a Clojure Managed Reference (currently an Atom, may evolve to use an Agent instead) and using db.with()
to update the state of that reference.
That's it, you now know how to re-implement Datomock yourself!
Actually, there are a few additional complications to make this work smoothly:
datomic:mem
How is this different than using Datomic memory databases, as in
(d/connect "datomic:mem://my-db")
?
Mocked connections differ from Datomic's memory connections in several ways:
This library requires Datomic 0.9.4470 or higher, in order to provide an implementation of the most recent methods of datomic.Connection
.
However, if you need to work with a lower version, forking this library and removing the implementation of the syncSchema()
, syncExcise()
and syncIndex()
should work just fine.
Copyright © 2016 Valentin Waeselynck and contributors.
Distributed under the MIT License.