-module(erupt_sqlite3). -behaviour(erupt_driver). -export([up/1, down/1, list/1, add/3, last/1, delete/2, exec/2]). -spec exec(any(), iodata()) -> ok | {error, any()}. exec(Conn, Query) -> case esqlite3:q(Conn, Query, []) of {error, _Err} = E -> E; _ -> ok end. -spec up(any()) -> ok | {error, any()}. up(Conn) -> case esqlite3:q(Conn, [<<"CREATE TABLE IF NOT EXISTS __erupt_migrations ( ">>, <<" id INTEGER PRIMARY KEY AUTOINCREMENT, ">>, <<" name TEXT NOT NULL, ">>, <<" timestamp INTEGER NOT NULL ">>, <<")">>], []) of {error, _Err} = E -> E; _ -> ok end. -spec down(any()) -> ok | {error, any()}. down(Conn) -> case esqlite3:q(Conn, <<"DROP TABLE __erupt_migrations">>, []) of {error, _Err} = E -> E; _ -> ok end. -spec list(any()) -> {ok, list()} | {error, any()}. list(Conn) -> case esqlite3:q(Conn, [<<"SELECT id, name, timestamp ">>, <<"FROM __erupt_migrations ">>, <<"ORDER BY timestamp ASC">>], []) of {error, _Err} = E -> E; Rows -> {ok, format_rows(Rows)} end. -spec format_rows(list()) -> list() | {error, invalid_row}. format_rows(Rows) -> lists:map(fun format_row/1, Rows). -spec format_row(list() | any()) -> {integer(), module(), integer()} | {error, invalid_row}. format_row([Id, Name, Timestamp]) -> {Id, binary_to_atom(Name), Timestamp}; format_row(_) -> {error, invalid_row}. -spec add(any(), binary(), integer()) -> ok | {error, any()}. add(Conn, Name, Timestamp) -> case esqlite3:q(Conn, <<"INSERT INTO __erupt_migrations (name, timestamp) VALUES (?, ?)">>, [Name, Timestamp]) of {error, _Err} = E -> E; _ -> ok end. -spec last(any()) -> {error, any()} | {ok, {integer(), module(), integer()}}. last(Conn) -> case esqlite3:q(Conn, [<<"SELECT id, name, timestamp ">>, <<"FROM __erupt_migrations ">>, <<"ORDER BY timestamp DESC ">>, <<"LIMIT 1">>], []) of {error, _Err} = E -> E; [[Id, Name, Timestamp]] -> {ok, {Id, binary_to_atom(Name), Timestamp}} end. -spec delete(any(), integer()) -> ok | {error, any()}. delete(Conn, Id) -> case esqlite3:q(Conn, <<"DELETE FROM __erupt_migrations WHERE id = ?">>, [Id]) of {error, _Err} = E -> E; _ -> ok end.