Vern, a Library For Database Fixtures

04 December 2014

At work, I've been using
yesql and wanted a way to
compactly describe some seed data. My first attempt was an utter
abomination, but I think I've worked out something pleasant that could
be useful to other
people. vern is a 54-line
project that I'd love to get feedback on before publishing. It's named
after one of my cats, this guy:

First, we assign the fixture the colorful name data, then create a
"database", which in this case is just an atom holding an empty
vector.

do-named is where the real action happens. processed is a map of
all the named entities that have been processed so far. For example,
after processing the first two entities, the value of processed will
be

{:endpoints{:wallace1:gromit2}}

Most likely you won't need it but it's there in case you
do. group-name will be :endpoints and then :permissions in this
example. In real life, I use this to determine which table I need to
insert the entity's data into. entity will be something like

{:name:wallace:data{:name"wallace":id1}}

In the example, you're just using conjing (:data entity) onto the
entities atom's vector. Here's what I do in real life, though:

This uses yesql's functionality to insert a row in a database and
return the value of the key that was generated for every entity in the
fixture. The reason you want to return the generated key is so that
you can refer to this record in later entities. If a subsequent entity
is defined as

{:name"belongs-to-wallace":endpoint-id[:endpoints:wallace]}

then do-named uses the corresponding value in the processed
map. When do-named sends the first "permission" entity to its
function, the entity looks like this:

{:name:wallace-read:data{:name"read":id10:endpoint1}}

The last feature is that you can group common attributes together in a
vector. You can see this in the permissions:

[:entity-group-key[:entity-1-key;; entity keys are optional{:name"zip"};; using a sequential structure allows you to reference;; another entity{:parent-id[:entity-group-key:entity-1-key]:name"zip's child 1"};; you can define common associations by grouping entities in a;; sequential; the first element contains the common associations[{:parent-id[:entity-group-key:entity-1-key]}{:name"zip's child 2"}{:name"zip's child 3"}]]:entity-group-2[{:entity-group-1-id[:entity-group-key:entity-1-key]}]]

Request for Feedback

This is a
tiny library,
and I hope it might yield a couple fun rounds of code golf. In
particular, I have the sneaking suspicion that I'm neglecting some
useful functions from Clojure's standard library. I considered using
zip but that seemed too heavyweight. Also, I think I could just pass
the entity's data to the do-named function.

I'm also curious if there's a name for this kind of pattern, where you
aren't solely processing one sequence item at a time but care about
what you last processed as well (this is how names get assigned to
entities).