{"id":27389239,"url":"https://github.com/vvvvalvalval/datomock","last_synced_at":"2025-10-07T23:45:31.669Z","repository":{"id":62435180,"uuid":"51711890","full_name":"vvvvalvalval/datomock","owner":"vvvvalvalval","description":"Mocking and forking Datomic Peer connections in-memory.","archived":false,"fork":false,"pushed_at":"2023-01-06T22:24:04.000Z","size":36,"stargazers_count":131,"open_issues_count":5,"forks_count":6,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-04T12:52:29.249Z","etag":null,"topics":["database","datomic","mocking"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vvvvalvalval.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-14T20:26:25.000Z","updated_at":"2025-01-19T14:01:16.000Z","dependencies_parsed_at":"2023-02-06T09:46:28.924Z","dependency_job_id":null,"html_url":"https://github.com/vvvvalvalval/datomock","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fdatomock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fdatomock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fdatomock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vvvvalvalval%2Fdatomock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vvvvalvalval","download_url":"https://codeload.github.com/vvvvalvalval/datomock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248766747,"owners_count":21158301,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","datomic","mocking"],"created_at":"2025-04-13T19:13:25.392Z","updated_at":"2025-10-07T23:45:26.635Z","avatar_url":"https://github.com/vvvvalvalval.png","language":"Clojure","funding_links":[],"categories":["Libraries"],"sub_categories":[],"readme":"# datomock\n\nMocking and forking Datomic connections in-memory.\n\n[![Clojars Project](https://img.shields.io/clojars/v/vvvvalvalval/datomock.svg)](https://clojars.org/vvvvalvalval/datomock)\n\n**Notes:** \n\n* This library is _not_ an in-memory re-implementation of Datomic - just a thin wrapper on top of the Datomic Peer Library. All the heavy lifting is done by Datomic's 'speculative writes' (a.k.a [`db.with(tx)`](https://docs.datomic.com/on-prem/javadoc/datomic/Database.html#with-java.util.List-)) and Clojure's managed references ([atoms](https://clojure.org/reference/atoms))\n* Only for Peers, not Clients.\n\n**Project maturity:** beta quality. Note that you will probably not need to use this library in production.\n\n## Usage\n\n```clojure \n(require '[datomic.api :as d])\n(require '[datomock.core :as dm])\n\n(def my-conn (d/connect \"datomic:mem://hello-world\"))\n\n;; ... create a mock connection from a Database value:\n(def starting-point-db (d/db my-conn))\n(def mocked-conn (dm/mock-conn starting-point-db))\n\n;; which is essentially the same as: \n(def mocked-conn (dm/fork-conn my-conn))\n\n;; dm/fork-conn is likely what you'll use most.\n```\n\n## Rationale and semantics\n\nMocked connections use Datomic's speculative writes (`db.with()`) and Clojure's managed references to emulate a Datomic connection locally.\n\nThe main benefit is the ability to 'fork' Datomic connections. \nMore precisely, if `conn1` is *forked* from `conn2`:\n* at the time of forking, `conn1` and `conn2` hold the same database value;\n* subsequent writes to `conn1` will leave `conn2` unaffected\n* subsequent writes to `conn2` will leave `conn1` unaffected\n\nBecause Datomic database values are persistent data structures, forking is extremely cheap in both space and time.\n\n## Applications\n\n* **Write expressive tests:** write tests as a tree of scenarios exploring various alternatives. In particular, this makes it very easy to write _system-level_ tests that run fast. Forget about setup and teardown phases: they are respectively replaced by forking and garbage-collection.\n* **Cheap, safe debugging:** instantly reproduce your production environment on your local machine. Save and re-use as many checkpoints of your state as you need as you debug. Dry-run data patches and migrations safely before committing them to production.\n* **Explore new database schemas:** in particular, you can experiment with changes to your database schema without committing to them. \n* **Staging environments / QA / CI:** want one staging environment (Peer) for each pull-request on your app? Just have each of them use an in-memory fork of a shared database (or even your production database).\n* **Ephemeral demos:** want to let people experiment with your app without accumulating their manual changes? Just have them work on a fork, and discard it afterwards.\n* **Ephemeral dev environments:** similarly, it's usually better to always work on the same data when developing, and have the manual changes you've made while experimented be discarded at the end of the session.\n\n### Useful links:\n\n* _[Application architecture with Datomic: branching reality](http://vvvvalvalval.github.io/posts/2016-01-03-architecture-datomic-branching-reality.html):_ a blog post providing a more in-depth analysis of forkability and its applications.\n* [_Full Stack Teleport Testing with Om Next \u0026 Datomic:_](https://youtu.be/qijWBPYkRAQ) a Clojure/West 2017 talk about how Ladder implement system-level testing using Om and Datomic.\n\n\n## How it works\n\nEssentially, 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.\n\n_That's it, you now know how to re-implement Datomock yourself!_\n\nActually, there are a few additional complications to make this work smoothly:\n\n* Log: the reference needs to hold not only a Database Value, but also a Log Value (for some strange reason, in Datomic, Log Values are not part of Database values).\n* Futures-based API: to match the interface of Datomic Connections, the library needs to provide a Futures-based API, which requires some additional work on top of Clojure references.\n* txReportQueue: the library needs to provide an implementation of that as well.\n\n## Mocked connections vs `datomic:mem`\n\n\u003e How is this different than using Datomic memory databases, as in `(d/connect \"datomic:mem://my-db\")` ?\n\nMocked connections differ from Datomic's memory connections in several ways:\n\n* you create a memory connection from scratch, whereas you create a mocked connection from a starting-point database value\n* a mocked connection is not accessible via a global URI\n\n\n## Compatibility notes\n\nThis library requires Datomic 0.9.4470 or higher, in order to provide an implementation of the most recent methods of `datomic.Connection`.\n\nHowever, 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.\n\nThis library works with Datomic 1.0.6527, but mock connections do not support\n[transaction io-stats](https://docs.datomic.com/on-prem/api/io-stats.html#transactions).\nA call like `(d/transact mock-conn :io-context true)` will not include an\n`:io-stats` key in the result.\n[Query io-stats](https://docs.datomic.com/on-prem/api/io-stats.html#query)\nare supported insofar as return value shapes will be correct,\nbut the underlying Datomic mem database doesn't provide any useful\ninformation in `:io-stats` `:reads`.\n\n## License\n\nCopyright © 2016 Valentin Waeselynck and contributors.\n\nDistributed under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvvvalvalval%2Fdatomock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvvvvalvalval%2Fdatomock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvvvvalvalval%2Fdatomock/lists"}