I required something akin to the Rubygem ‘papertrail’ in Elixir. However, in large part because of the ‘do you really need a database’ and ‘how to separate your contexts’ discussions that are going on, I did not want to use a package that was tightly coupled to Ecto or any other single thing (The two existing versioning packages, paper_trail and whatwasit both are).
Revisionair
So, enter Revisionair. At its core it is just a simple behaviour together with a public easy-to-use wrapper, the result of an evening of coding.
An implementation of the Revisionair.Storage
behaviour can easily be created for any kind of persistence layer, including Ecto, ETS, Mnesia, plain old GenServer/Agent type of stores, flat file reading/writing, or wrapping remote API communications. (Or at least I hope so, because that was the idea).
The behaviour thus only explicitly states what it needs from ‘a data storage provider’. A storage provider can be configured application-wide, or explicitly stated in the options parameter of each function call.
As for the public API, you can store a new revision for a structure, read all prior-stored revisions for a certain structure, read the most recent revision for a certain structure, and finally clean everything again. It’s simple, but this is all that I need for my application, so KISS.
To keep it as agnostic as possible, it also does not (necessarily) assume anything from the structures you pass in. That is, by default it assumes that the maps you pass it are structs (maps containing a __struct__
field) who can be uniquely identified by an id
field, but this is also completely configurable when calling the functions of the module.
So, version 0.9 is now released! it is simple, but then again it now is 01:30, so I might also miss some crucial details. The perils of midnight programming …
Any and all questions and feedback is greatly appreciated.