diff --git a/README.md b/README.md index 756fe4a..51f694c 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,10 @@ API use: application:ensure_all_started(pgapp). pgapp:connect([{size, 10}, {database, "mydb"}, {username, "foo"}, {password, "bar"}]). pgapp:equery("select current_date", []), - pgapp:with_transaction(fun() -> - pgapp:squery("update ..."), - pgapp:squery("delete from ..."), - pgapp:equery("select ? from ?", ["*", Table]) + pgapp:with_transaction(fun(Conn) -> + pgapp:squery(Conn, "update ..."), + pgapp:squery(Conn, "delete from ..."), + pgapp:equery(Conn, "select ? from ?", ["*", Table]) end). - Multi pool: diff --git a/src/pgapp.erl b/src/pgapp.erl index 04234e0..265226a 100644 --- a/src/pgapp.erl +++ b/src/pgapp.erl @@ -42,6 +42,10 @@ equery(Sql, Params) -> (PoolName :: atom(), Sql::epgsql:sql_query(), Params :: list(epgsql:bind_param())) + -> epgsql:reply(epgsql:equery_row()) | {error, Reason :: any()}; + (Conn :: pid(), + Sql::epgsql:sql_query(), + Params :: list(epgsql:bind_param())) -> epgsql:reply(epgsql:equery_row()) | {error, Reason :: any()}. equery(P1, P2, P3) -> pgapp_worker:equery(P1, P2, P3). @@ -66,12 +70,14 @@ squery(Sql) -> [epgsql:reply(epgsql:squery_row())] | {error, Reason :: any()}; (PoolName :: atom(), Sql::epgsql:sql_query()) + -> epgsql:reply(epgsql:squery_row()) | + [epgsql:reply(epgsql:squery_row())] | {error, Reason :: any()}; + (Conn :: pid(), + Sql::epgsql:sql_query()) -> epgsql:reply(epgsql:squery_row()) | [epgsql:reply(epgsql:squery_row())] | {error, Reason :: any()}. -squery(PoolName, Sql) when is_atom(PoolName) -> - pgapp_worker:squery(PoolName, Sql); -squery(Sql, Timeout) -> - pgapp_worker:squery(Sql, Timeout). +squery(P1, P2) -> + pgapp_worker:squery(P1, P2). -spec squery(PoolName :: atom(), Sql :: epgsql:sql_query(), @@ -81,29 +87,35 @@ squery(Sql, Timeout) -> squery(PoolName, Sql, Timeout) -> pgapp_worker:squery(PoolName, Sql, Timeout). --spec with_transaction(Function :: fun(() -> Reply)) +-spec with_transaction(Function :: fun((pid()) -> Reply)) -> Reply | {rollback | error, any()} when Reply :: any(). -with_transaction(Fun) when is_function(Fun, 0) -> +with_transaction(Fun) when is_function(Fun, 1) -> with_transaction(epgsql_pool, Fun). -spec with_transaction(PoolName :: atom(), - Function :: fun(() -> Reply)) + Function :: fun((pid()) -> Reply)) + -> Reply | {rollback | error, any()} when Reply :: any(); + (Conn :: pid(), + Function :: fun((pid()) -> Reply)) -> Reply | {rollback | error, any()} when Reply :: any(); - (Function :: fun(() -> Reply), + (Function :: fun((pid()) -> Reply), Timeout :: timeout()) -> Reply | {rollback | error, any()} when Reply :: any(). -with_transaction(PoolName, Fun) when is_function(Fun, 0); - is_atom(PoolName) -> - pgapp_worker:with_transaction(PoolName, Fun); -with_transaction(Fun, Timeout) when is_function(Fun, 0) -> +with_transaction(P1, Fun) when is_function(Fun, 1) -> + pgapp_worker:with_transaction(P1, Fun); +with_transaction(Fun, Timeout) when is_function(Fun, 1) -> pgapp_worker:with_transaction(epgsql_pool, Fun, Timeout). -spec with_transaction(PoolName :: atom(), - Function :: fun(() -> Reply), + Function :: fun((pid()) -> Reply), + Timeout :: atom() | non_neg_integer()) + -> Reply | {rollback | error, any()} when Reply :: any(); + (Conn :: pid(), + Function :: fun((pid()) -> Reply), Timeout :: atom() | non_neg_integer()) -> Reply | {rollback | error, any()} when Reply :: any(). -with_transaction(PoolName, Fun, Timeout) when is_function(Fun, 0) -> - pgapp_worker:with_transaction(PoolName, Fun, Timeout). +with_transaction(P1, Fun, Timeout) when is_function(Fun, 1) -> + pgapp_worker:with_transaction(P1, Fun, Timeout). %%-------------------------------------------------------------------- %% @doc diff --git a/src/pgapp_worker.erl b/src/pgapp_worker.erl index 5684498..3b2524f 100644 --- a/src/pgapp_worker.erl +++ b/src/pgapp_worker.erl @@ -26,18 +26,13 @@ -define(MAXIMUM_DELAY, 5 * 60 * 1000). % Five minutes -define(TIMEOUT, 5 * 1000). --define(STATE_VAR, '$pgapp_state'). - squery(Sql) -> - case get(?STATE_VAR) of - undefined -> - squery(epgsql_pool, Sql); - Conn -> - epgsql:squery(Conn, Sql) - end. + squery(epgsql_pool, Sql). squery(PoolName, Sql) when is_atom(PoolName) -> squery(PoolName, Sql, ?TIMEOUT); +squery(Conn, Sql) when is_pid(Conn) -> + epgsql:squery(Conn, Sql); squery(Sql, Timeout) -> squery(epgsql_pool, Sql, Timeout). @@ -48,15 +43,12 @@ squery(PoolName, Sql, Timeout) -> end, Timeout). equery(Sql, Params) -> - case get(?STATE_VAR) of - undefined -> - equery(epgsql_pool, Sql, Params); - Conn -> - epgsql:equery(Conn, Sql, Params) - end. + equery(epgsql_pool, Sql, Params). equery(PoolName, Sql, Params) when is_atom(PoolName) -> equery(PoolName, Sql, Params, ?TIMEOUT); +equery(Conn, Sql, Params) when is_pid(Conn) -> + epgsql:equery(Conn, Sql, Params); equery(Sql, Params, Timeout) -> equery(epgsql_pool, Sql, Params, Timeout). @@ -70,12 +62,14 @@ equery(PoolName, Sql, Params, Timeout) -> with_transaction(PoolName, Fun) -> with_transaction(PoolName, Fun, ?TIMEOUT). -with_transaction(PoolName, Fun, Timeout) -> +with_transaction(PoolName, Fun, Timeout) when is_atom(PoolName) -> middle_man_transaction(PoolName, fun (W) -> gen_server:call(W, {transaction, Fun}, Timeout) - end, Timeout). + end, Timeout); +with_transaction(Conn, Fun, _Timeout) when is_pid(Conn) -> + epgsql:with_transaction(Conn, Fun). middle_man_transaction(Pool, Fun, Timeout) -> Tag = make_ref(), @@ -112,9 +106,7 @@ handle_call({equery, Sql, Params}, _From, {reply, epgsql:equery(Conn, Sql, Params), State}; handle_call({transaction, Fun}, _From, #state{conn = Conn} = State) -> - put(?STATE_VAR, Conn), - Result = epgsql:with_transaction(Conn, fun(_) -> Fun() end), - erase(?STATE_VAR), + Result = epgsql:with_transaction(Conn, Fun), {reply, Result, State}. handle_cast(reconnect, State) ->