Skip to content

Commit

Permalink
return error tuple when an EXIT message is received
Browse files Browse the repository at this point in the history
  • Loading branch information
wg committed May 6, 2009
1 parent 4960cec commit 7fd23f9
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 9 deletions.
12 changes: 9 additions & 3 deletions README
Expand Up @@ -24,7 +24,7 @@ Erlang PostgreSQL Database Client
* Simple Query

{ok, Columns, Rows} = pgsql:squery(C, Sql).
{error, #error{}} = pgsql:squery(C, InvalidSql).
{error, Error} = pgsql:squery(C, InvalidSql).

Columns - list of column records, see pgsql.hrl for definition.
Rows - list of tuples, one for each row.
Expand All @@ -38,7 +38,7 @@ Erlang PostgreSQL Database Client
{ok, Count} = pgsql:equery(C, "update ...", [Parameters]).
{ok, Count, Columns, Rows} = pgsql:equery(C, "insert ... returning ...", [Parameters]).

{error, #error{}} = pgsql:equery(C, "invalid SQL", [Parameters]).
{error, Error} = pgsql:equery(C, "invalid SQL", [Parameters]).

Parameters - optional list of values to be bound to $1, $2, $3, etc.

Expand Down Expand Up @@ -79,7 +79,7 @@ Erlang PostgreSQL Database Client
ok = pgsql:close(C, statement | portal, Name).
ok = pgsql:sync(C).

All functions return {error, #error{}} when an error occurs.
All functions return {error, Error} when an error occurs.

* Data Representation

Expand All @@ -99,3 +99,9 @@ Erlang PostgreSQL Database Client
bytea = <<1, 2>>

record = {int2, time, text, ...} (decode only)

* Errors

Errors originating from the PostgreSQL backend are returned as {error, #error{}},
see pgsql.hrl for the record definition. epgsql may also return {error, Atom}
where Atom is 'timeout' or 'closed'.
18 changes: 12 additions & 6 deletions src/pgsql.erl
Expand Up @@ -112,17 +112,19 @@ with_transaction(C, F) ->
%% -- internal functions --

receive_result(C, Result) ->
case receive_result(C, [], []) of
try receive_result(C, [], []) of
done -> Result;
timeout -> {error, timeout};
R -> receive_result(C, R)
catch
throw:E -> E
end.

receive_results(C, Results) ->
case receive_result(C, [], []) of
try receive_result(C, [], []) of
done -> lists:reverse(Results);
timeout -> lists:reverse([{error, timeout} | Results]);
R -> receive_results(C, [R | Results])
catch
throw:E -> E
end.

receive_result(C, Cols, Rows) ->
Expand All @@ -145,7 +147,9 @@ receive_result(C, Cols, Rows) ->
{pgsql, C, done} ->
done;
{pgsql, C, timeout} ->
timeout
throw({error, timeout});
{'EXIT', C, _Reason} ->
throw({error, closed})
end.

receive_extended_result(C)->
Expand All @@ -169,5 +173,7 @@ receive_extended_result(C, Rows) ->
{pgsql, C, {notice, _N}} ->
receive_extended_result(C, Rows);
{pgsql, C, timeout} ->
{error, timeout}
{error, timeout};
{'EXIT', C, _Reason} ->
{error, closed}
end.
37 changes: 37 additions & 0 deletions test_src/pgsql_tests.erl
Expand Up @@ -431,6 +431,43 @@ execute_timeout_test() ->
end,
[{timeout, 10}]).

connection_closed_test() ->
P = self(),
F = fun() ->
process_flag(trap_exit, true),
{ok, C} = pgsql:connect(?host, [{port, ?port}]),
P ! {connected, C},
receive
Any -> P ! Any
end
end,
spawn_link(F),
receive
{connected, C} ->
timer:sleep(100),
pgsql:close(C),
{'EXIT', C, _} = receive R -> R end
end,
flush().

active_connection_closed_test() ->
P = self(),
F = fun() ->
process_flag(trap_exit, true),
{ok, C} = pgsql:connect(?host, [{port, ?port}]),
P ! {connected, C},
R = pgsql:squery(C, "select pg_sleep(10)"),
P ! R
end,
spawn_link(F),
receive
{connected, C} ->
timer:sleep(100),
pgsql:close(C),
{error, closed} = receive R -> R end
end,
flush().

%% -- run all tests --

run_tests() ->
Expand Down

0 comments on commit 7fd23f9

Please sign in to comment.