Browse Source

Add 'squery' API

Sergey Prokhorov 9 years ago
parent
commit
ffccac538e
2 changed files with 39 additions and 7 deletions
  1. 20 6
      src/epgsql_pool.erl
  2. 19 1
      test/epgsql_pool_SUITE.erl

+ 20 - 6
src/epgsql_pool.erl

@@ -3,6 +3,7 @@
 -export([start/4, stop/1,
 -export([start/4, stop/1,
          validate_connection_params/1,
          validate_connection_params/1,
          query/2, query/3, query/4,
          query/2, query/3, query/4,
+         squery/2, squery/3,
          transaction/2,
          transaction/2,
          get_settings/0, set_settings/1,
          get_settings/0, set_settings/1,
          test_run/0
          test_run/0
@@ -85,27 +86,40 @@ query(PoolNameOrWorker, Stmt, Params) ->
 
 
 
 
 -spec query(pool_name() | pid(), epgsql:sql_query(), [epgsql:bind_param()], [proplists:option()]) -> epgsql:reply().
 -spec query(pool_name() | pid(), epgsql:sql_query(), [epgsql:bind_param()], [proplists:option()]) -> epgsql:reply().
-query(Worker, Stmt, Params, Options) when is_pid(Worker) ->
+query(PoolNameOrWorker, Stmt, Params, Options) ->
+    do_query(PoolNameOrWorker, {equery, Stmt, Params}, Options).
+
+
+-spec squery(pool_name() | pid(), epgsql:sql_query()) -> epgsql:reply(epgsql:squery_row()) | {error, timeout}.
+squery(PoolNameOrWorker, Stmt) ->
+    squery(PoolNameOrWorker, Stmt, []).
+
+-spec squery(pool_name() | pid(), epgsql:sql_query(), [proplists:option()]) ->
+                    epgsql:reply(epgsql:squery_row()) | {error, timeout}.
+squery(PoolNameOrWorker, Stmt, Options) ->
+    do_query(PoolNameOrWorker, {squery, Stmt}, Options).
+
+
+do_query(Worker, QueryTuple, Options) when is_pid(Worker) ->
     Timeout = case proplists:get_value(timeout, Options) of
     Timeout = case proplists:get_value(timeout, Options) of
                   undefined -> element(2, application:get_env(epgsql_pool, query_timeout));
                   undefined -> element(2, application:get_env(epgsql_pool, query_timeout));
                   V -> V
                   V -> V
               end,
               end,
     Sock = gen_server:call(Worker, get_sock),
     Sock = gen_server:call(Worker, get_sock),
     try
     try
-        gen_server:call(Worker, {equery, Stmt, Params}, Timeout)
+        gen_server:call(Worker, QueryTuple, Timeout)
     catch
     catch
         exit:{timeout, _} ->
         exit:{timeout, _} ->
-            error_logger:error_msg("query timeout ~p ~p", [Stmt, Params]),
+            error_logger:error_msg("query timeout ~p", [QueryTuple]),
             epgsql_sock:cancel(Sock),
             epgsql_sock:cancel(Sock),
             {error, timeout}
             {error, timeout}
     end;
     end;
-
+do_query(PoolName0, QueryTuple, Options) ->
-query(PoolName0, Stmt, Params, Options) ->
     PoolName = epgsql_pool_utils:pool_name_to_atom(PoolName0),
     PoolName = epgsql_pool_utils:pool_name_to_atom(PoolName0),
     case get_worker(PoolName) of
     case get_worker(PoolName) of
         {ok, Worker} ->
         {ok, Worker} ->
             try
             try
-                query(Worker, Stmt, Params, Options)
+                do_query(Worker, QueryTuple, Options)
             catch
             catch
                 Err:Reason ->
                 Err:Reason ->
                     erlang:raise(Err, Reason, erlang:get_stacktrace())
                     erlang:raise(Err, Reason, erlang:get_stacktrace())

+ 19 - 1
test/epgsql_pool_SUITE.erl

@@ -11,7 +11,7 @@
 
 
 -export([all/0,
 -export([all/0,
          init_per_suite/1, end_per_suite/1, init_per_testcase/2, end_per_testcase/2,
          init_per_suite/1, end_per_suite/1, init_per_testcase/2, end_per_testcase/2,
-         query_test/1, transaction_test/1, reconnect_test/1, timeout_test/1,
+         query_test/1, squery_test/1, transaction_test/1, reconnect_test/1, timeout_test/1,
          validate_connection_params_test/1
          validate_connection_params_test/1
         ]).
         ]).
 
 
@@ -20,6 +20,7 @@
 
 
 all() ->
 all() ->
     [query_test,
     [query_test,
+     squery_test,
      transaction_test,
      transaction_test,
      reconnect_test,
      reconnect_test,
      timeout_test,
      timeout_test,
@@ -71,6 +72,23 @@ query_test(Config) ->
     ?assertMatch(#error{severity = error, message = <<"relation \"some_table\" does not exist">>}, Error),
     ?assertMatch(#error{severity = error, message = <<"relation \"some_table\" does not exist">>}, Error),
     ok.
     ok.
 
 
+squery_test(Config) ->
+    {ok, 3, _, Ids} = epgsql_pool:squery(my_pool,
+                                         "INSERT INTO category (title) "
+                                         "VALUES ('cat 1'), ('cat 2'), ('cat 3') "
+                                         "RETURNING id"),
+    WaitForRows = lists:map(fun({{Id}, Title}) -> {Id, Title} end,
+                            lists:zip(Ids, [<<"cat 1">>, <<"cat 2">>, <<"cat 3">>])),
+    {ok, _, Rows} = epgsql_pool:squery(my_pool, "SELECT id, title FROM category ORDER by id ASC"),
+    ct:pal("Rows ~p", [Rows]),
+    ?assertEqual(WaitForRows, Rows),
+
+    ?assertMatch([{ok, _, [{<<"1">>}]}, {ok, _, [{<<"2">>}]}],
+                 epgsql_pool:squery(my_pool, "SELECT 1; SELECT 2;")),
+
+    ?assertMatch({error, #error{severity = error, message = <<"relation \"some_table\" does not exist">>}},
+                 epgsql_pool:squery(my_pool, "SELECT * FROM some_table")),
+    Config.
 
 
 transaction_test(Config) ->
 transaction_test(Config) ->
     {FirstCatId, CatIds2, ItemIds2} =
     {FirstCatId, CatIds2, ItemIds2} =