xitdb-clj is a new immutable database for Clojure. It can time travel like Datomic, and store data in a single file like SQLite. On its own, though, it has no query language. Enter Datascript...
Datascript is normally an in-memory database, but it lets you use anything as backing storage. What if we combined them?
Datascript's storage feature doesn't tell us exactly what changed, so I added one more trick: Editscript, the diffing library. I use it to figure out how to update the database with the minimal number of changes.
The end result is a sort of mini Datomic that writes to a single file. And yet, this setup can do something Datomic can't: it can branch off of any old copy of the database. The example below reverts to an older copy of the database.
Keep in mind that all reads and writes are incremental. The database is not being loaded into memory at once, so you can use it to work with larger-than-memory data.
To run this example:
git clone https://gist.github.com/663116fcd204f3f89a7e43f52fa676ef.git datascript+xitdb
cd datascript+xitdb
clj -M db.clj
...which will print this on the first run:
The old copy of the db, before retracting Alice:
#{[1 Alice 24] [2 Bob 45]}
The latest copy of the db:
#{[2 Bob 45]}
The latest copy of the db after reverting:
#{[1 Alice 24] [2 Bob 45]}