diff --git a/.gitignore b/.gitignore index b9def8c..94669c7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ ebin/ *~ deps/ *.config +*.plt diff --git a/rebar.config b/rebar.config index 65f76f4..3a8f8eb 100644 --- a/rebar.config +++ b/rebar.config @@ -1,5 +1,5 @@ {deps, [ - {epgsql, ".*", {git, "git://github.com/epgsql/epgsql.git", {tag, "3.1.0"}}}, + {epgsql, ".*", {git, "git://github.com/epgsql/epgsql.git", "792a93c"}}, {poolboy, ".*", {git, "git://github.com/devinus/poolboy.git", {tag, "1.4.2"}}} ]}. diff --git a/src/pgapp.erl b/src/pgapp.erl index 18baae9..7804658 100644 --- a/src/pgapp.erl +++ b/src/pgapp.erl @@ -9,18 +9,24 @@ -module(pgapp). %% API --export([connect/1, connect/2, - equery/2, equery/3, equery/4, - squery/1, squery/2, squery/3, - with_transaction/1, with_transaction/2, with_transaction/3]). +-export([connect/1, connect/2]). +-export([equery/2, equery/3, equery/4]). +-export([squery/1, squery/2, squery/3]). +-export([with_transaction/1, with_transaction/2, with_transaction/3]). +-export([connected_workers/1]). %%%=================================================================== %%% API %%%=================================================================== +-spec connect(Settings :: list()) -> {ok, WorkerPid} when + WorkerPid :: pid(). connect(Settings) -> connect(epgsql_pool, Settings). +-spec connect(PoolName :: atom(), + Settings :: list()) -> {ok, WorkerPid} when + WorkerPid :: pid(). connect(PoolName, Settings) -> PoolSize = proplists:get_value(size, Settings, 5), MaxOverflow = proplists:get_value(max_overflow, Settings, 5), @@ -89,6 +95,13 @@ with_transaction(PoolName, Fun) when is_function(Fun, 0) -> with_transaction(PoolName, Fun, Timeout) when is_function(Fun, 0) -> pgapp_worker:with_transaction(PoolName, Fun, Timeout). +-spec connected_workers(PoolName :: atom()) -> {ok, ConnectedWorkerPids} when + ConnectedWorkerPids :: list(pid()). +connected_workers(PoolName) -> + WorkerPids = gen_server:call(PoolName, get_avail_workers), + {ok, [WorkerPid || WorkerPid <- WorkerPids, + pgapp_worker:is_connected(WorkerPid)]}. + %%-------------------------------------------------------------------- %% @doc %% @spec diff --git a/src/pgapp_worker.erl b/src/pgapp_worker.erl index 5cfdafd..b9186bc 100644 --- a/src/pgapp_worker.erl +++ b/src/pgapp_worker.erl @@ -8,9 +8,10 @@ -behaviour(gen_server). -behaviour(poolboy_worker). --export([squery/1, squery/2, squery/3, - equery/2, equery/3, equery/4, - with_transaction/2, with_transaction/3]). +-export([squery/1, squery/2, squery/3]). +-export([equery/2, equery/3, equery/4]). +-export([with_transaction/2, with_transaction/3]). +-export([is_connected/1]). -export([start_link/1]). @@ -29,34 +30,37 @@ -define(STATE_VAR, '$pgapp_state'). squery(Sql) -> + squery(Sql, ?TIMEOUT). + +squery(PoolName, Sql) when is_atom(PoolName) -> + squery(PoolName, Sql, ?TIMEOUT); +squery(Sql, Timeout) -> case get(?STATE_VAR) of undefined -> - squery(epgsql_pool, Sql); + squery(epgsql_pool, Sql, Timeout); Conn -> epgsql:squery(Conn, Sql) end. -squery(PoolName, Sql) -> - squery(PoolName, Sql, ?TIMEOUT). - squery(PoolName, Sql, Timeout) -> poolboy:transaction(PoolName, fun (Worker) -> gen_server:call(Worker, {squery, Sql}, Timeout) end, Timeout). - equery(Sql, Params) -> + equery(Sql, Params, ?TIMEOUT). + +equery(PoolName, Sql, Params) when is_atom(PoolName) -> + equery(PoolName, Sql, Params, ?TIMEOUT); +equery(Sql, Params, Timeout) -> case get(?STATE_VAR) of undefined -> - equery(epgsql_pool, Sql, Params); + equery(epgsql_pool, Sql, Params, Timeout); Conn -> epgsql:equery(Conn, Sql, Params) end. -equery(PoolName, Sql, Params) -> - equery(PoolName, Sql, Params, ?TIMEOUT). - equery(PoolName, Sql, Params, Timeout) -> poolboy:transaction(PoolName, fun (Worker) -> @@ -74,6 +78,9 @@ with_transaction(PoolName, Fun, Timeout) -> {transaction, Fun}, Timeout) end, Timeout). +is_connected(WorkerPid) -> + gen_server:call(WorkerPid, {is_connected}, ?TIMEOUT). + start_link(Args) -> gen_server:start_link(?MODULE, Args, []). @@ -81,6 +88,12 @@ init(Args) -> process_flag(trap_exit, true), {ok, connect(#state{start_args = Args, delay = ?INITIAL_DELAY})}. +handle_call({is_connected}, _From, #state{conn = undefined} = State) -> + {reply, false, State}; +handle_call({is_connected}, _From, #state{conn = _Conn} = State) -> + {reply, true, State}; +handle_call(_Query, _From, #state{conn = undefined} = State) -> + {reply, {error, disconnected}, State}; handle_call({squery, Sql}, _From, #state{conn=Conn} = State) when Conn /= undefined -> {reply, epgsql:squery(Conn, Sql), State};