README.md

# exodus

A library for managing schema migrations.

## Usage

Here is an example using the exodus_sqlite3 driver along with the esqlite3 library.

Make your migration modules like this:

    -module(exodus_create_todos).
    -behvaiour(exodus_migration).

    -export([up/0, down/0]).

    up() ->
        [<<"CREATE TABLE IF NOT EXISTS todos ">>,
         <<"  id INTEGER PRIMARY KEY AUTOINCREMENT, ">>,
         <<"  body TEXT NOT NULL ">>,
         <<")">>].

    down() ->
        <<"DROP TABLE IF EXISTS todos">>.

Once we have made our migration modules we can setup our exodus configuration.
A configuration consists of a list of migrations, a driver, and a connection.

The migration list is in the format [{Module, Timestamp}]. The ascending order
of timestamps determines the order that the migrations will be run in.
While it is best practice to keep these migrations sorted, exodus will sort them
before executing commands regardless.

Exodus provides a convenient function to get a timestamp:

    exodus:timestamp().

The driver implements the exodus_driver behavior for a given database.
You can use an existing driver, or make your own. It's just a module that implements a handful of functions.

Here is a list of drivers for common relational databases:

- [exodus_sqlite3](https://git.sr.ht/~fancycade/exodus_sqlite3)
- [exodus_postgres](https://git.sr.ht/~fancycade/exodus_postgres)
- [exodus_mysql](https://git.sr.ht/~fancycade/exodus_mysql)

That Connection is the last part. Some db libraries like pgo configure the connection statically so the connection is optional.

    {ok, Conn} = esqlite3:open("test.db").

    Migrations = [{exodus_create_todos, 1234},
                  {exodus_create_tags, 12345}].

    Config = exodus:config(Migrations, exodus_sqlite3, Conn).

To run the migrations simply use the run function with the config.

    exodus:run(Config).

Now you can list all the migrations that have been run:

    exodus:list(Config).

If you want to revert the last migration use revert:

    exodus:revert(Config).

If you want to test that your latest migration's up and down methods are correct you can do this:

    exodus:redo(Config).

This will run the down, and then the up.

## Build

    rebar3 compile

## Test

    rebar3 eunit
    rebar3 ct