vvvvalvalval / datomock

Mocking and forking Datomic Peer connections in-memory.
MIT License
130 stars 6 forks source link
database datomic mocking

datomock

Mocking and forking Datomic connections in-memory.

Clojars Project

Notes:

Project maturity: beta quality. Note that you will probably not need to use this library in production.

Usage

(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.

Rationale and semantics

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:

Because Datomic database values are persistent data structures, forking is extremely cheap in both space and time.

Applications

Useful links:

How it works

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:

Mocked connections vs 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:

Compatibility notes

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.

This library works with Datomic 1.0.6527, but mock connections do not support transaction io-stats. A call like (d/transact mock-conn :io-context true) will not include an :io-stats key in the result. Query io-stats are supported insofar as return value shapes will be correct, but the underlying Datomic mem database doesn't provide any useful information in :io-stats :reads.

License

Copyright © 2016 Valentin Waeselynck and contributors.

Distributed under the MIT License.