Current section
Files
Jump to
Current section
Files
src/dbi_mysql.erl
-module(dbi_mysql).
-author('manuel@altenwald.com').
-behaviour(dbi).
-export([
start_link/1,
init/8,
terminate/1,
do_query/3,
check_migration/1,
get_migrations/1,
add_migration/3,
rem_migration/2
]).
-include_lib("dbi/include/dbi.hrl").
-define(DEFAULT_POOLSIZE, 10).
-define(DEFAULT_MAX_OVERFLOW, 10).
-define(DEFAULT_PORT, 3306).
-spec start_link([term()]) -> {ok, pid()}.
start_link(ConnData) ->
{ok, _} = apply(p1_mysql_conn, start_link, ConnData).
-spec init(
Host :: string(), Port :: integer(), User :: string(),
Pass :: string(), Database :: string(), Poolname :: atom(),
Poolsize :: integer(), Extra :: [term()]) -> ok.
init(Host, Port, User, Pass, Database, Poolname, Poolsize, Extra) ->
MaxOverflow = proplists:get_value(max_overflow, Extra, ?DEFAULT_MAX_OVERFLOW),
ConnData = [Host, dbi_query:default(Port, ?DEFAULT_PORT),
User, Pass, Database, undefined],
PoolArgs = [{name, {local, Poolname}}, {worker_module, ?MODULE},
{size, dbi_query:default(Poolsize, ?DEFAULT_POOLSIZE)},
{max_overflow, MaxOverflow}],
ChildSpec = poolboy:child_spec(Poolname, PoolArgs, ConnData),
supervisor:start_child(?DBI_SUP, ChildSpec),
ok.
-spec terminate(Poolname :: atom()) -> ok.
terminate(_Poolname) ->
ok.
-spec do_query(
PoolDB :: atom(),
SQL :: binary() | string(),
[Params :: any()]) ->
{ok, integer(), [term()]} | {error, any()}.
do_query(PoolDB, SQL, Params) when is_list(SQL) ->
do_query(PoolDB, list_to_binary(SQL), Params);
do_query(PoolDB, RawSQL, Params) when is_binary(RawSQL) ->
SQL = dbi_query:resolve(RawSQL),
poolboy:transaction(PoolDB, fun(PID) ->
case p1_mysql_conn:squery(PID, SQL, self(), Params) of
{data, Result} ->
Rows = p1_mysql:get_result_rows(Result),
{ok, length(Rows), [ list_to_tuple(Row) || Row <- Rows ]};
{updated, Result} ->
Count = p1_mysql:get_result_affected_rows(Result),
{ok, Count, []};
{error, Result} ->
Error = p1_mysql:get_result_reason(Result),
{error, Error}
end
end).
-spec check_migration(PoolDB :: atom()) ->
{ok, integer(), [binary()]}.
check_migration(PoolDB) ->
Create = <<"CREATE TABLE IF NOT EXISTS schema_migrations("
"id integer primary key auto_increment, "
"code varchar(1024), "
"filename varchar(1024));">>,
{ok, _, _} = do_query(PoolDB, Create, []),
ok.
-spec get_migrations(Poolname :: atom()) ->
{ok, Count :: integer(), [{binary()}]}.
get_migrations(Poolname) ->
SQL = <<"SELECT code, filename "
"FROM schema_migrations "
"ORDER BY id ASC">>,
do_query(Poolname, SQL, []).
-spec add_migration(Poolname :: atom(), Code :: binary(), File :: binary()) ->
ok | {error, Reason :: any()}.
add_migration(Poolname, Code, File) ->
Insert = <<"INSERT INTO schema_migrations(code, filename) "
"VALUES ($1, $2)">>,
case do_query(Poolname, Insert, [Code, File]) of
{ok, 1, []} ->
ok;
Error ->
Error
end.
-spec rem_migration(Poolname :: atom(), Code :: binary()) ->
ok | {error, Reason :: any()}.
rem_migration(Poolname, Code) ->
Delete = <<"DELETE FROM schema_migrations "
"WHERE code = $1">>,
case do_query(Poolname, Delete, [Code]) of
{ok, _, _} -> ok;
Error -> Error
end.