Просмотр исходного кода

require sync when error occurs during execute

Will 14 лет назад
Родитель
Сommit
817b125810
3 измененных файлов с 32 добавлено и 3 удалено
  1. 7 2
      README
  2. 12 1
      src/pgsql_connection.erl
  3. 13 0
      test_src/pgsql_tests.erl

+ 7 - 2
README

@@ -108,8 +108,13 @@ Erlang PostgreSQL Database Client
 * 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'.
+  see pgsql.hrl for the record definition. epgsql functions may also return
+  {error, What} where What is one of the following:
+
+  {unsupported_auth_method, Method}     - required auth method is unsupported
+  timeout                               - request timed out
+  closed                                - connection was closed
+  sync_required                         - error occured and pgsql:sync must be called
 
 * Asynchronous Messages
 

+ 12 - 1
src/pgsql_connection.erl

@@ -15,6 +15,7 @@
 -export([startup/3, auth/2, initializing/2, ready/2, ready/3]).
 -export([querying/2, parsing/2, binding/2, describing/2]).
 -export([executing/2, closing/2, synchronizing/2, timeout/2]).
+-export([aborted/3]).
 
 -include("pgsql.hrl").
 
@@ -469,7 +470,7 @@ executing(timeout, State) ->
 executing({error, E}, State) ->
     #state{timeout = Timeout} = State,
     notify(State, {error, E}),
-    {next_state, executing, State, Timeout}.
+    {next_state, aborted, State, Timeout}.
 
 %% CloseComplete
 closing({$3, <<>>}, State) ->
@@ -515,6 +516,16 @@ timeout(_Event, State) ->
     #state{timeout = Timeout} = State,
     {next_state, timeout, State, Timeout}.
 
+aborted(sync, From, State) ->
+    #state{timeout = Timeout} = State,
+    send(State, $S, []),
+    State2 = State#state{reply = ok, reply_to = From},
+    {next_state, synchronizing, State2, Timeout};
+
+aborted(_Msg, _From, State) ->
+    #state{timeout = Timeout} = State,
+    {reply, {error, sync_required}, aborted, State, Timeout}.
+
 %% -- internal functions --
 
 %% decode data

+ 13 - 0
test_src/pgsql_tests.erl

@@ -258,6 +258,19 @@ bind_and_close_test() ->
               ok = pgsql:sync(C)
       end).
 
+execute_error_test() ->
+    with_connection(
+      fun(C) ->
+          {ok, S} = pgsql:parse(C, "insert into test_table1 (id, value) values ($1, $2)"),
+          ok = pgsql:bind(C, S, [1, <<"foo">>]),
+          {error, #error{code = <<"23505">>}} = pgsql:execute(C, S, 0),
+          {error, sync_required} = pgsql:bind(C, S, [3, <<"quux">>]),
+          ok = pgsql:sync(C),
+          ok = pgsql:bind(C, S, [3, <<"quux">>]),
+          {ok, _} = pgsql:execute(C, S, 0),
+          {ok, 1} = pgsql:squery(C, "delete from test_table1 where id = 3")
+      end).
+
 describe_test() ->
     with_connection(
       fun(C) ->