Skip to content

Commit 6c3d35c

Browse files
committed
Further remove duplication in DBConnection
1 parent e2f2582 commit 6c3d35c

File tree

1 file changed

+60
-124
lines changed

1 file changed

+60
-124
lines changed

lib/db_connection.ex

Lines changed: 60 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ defmodule DBConnection do
880880
{:ok, result} | {:error, Exception.t()}
881881
def close(conn, query, opts \\ []) do
882882
conn
883-
|> run_cleanup(&run_close/4, [query], meter(opts), opts)
883+
|> run(&run_close(&1, query, &2, &3), meter(opts), opts)
884884
|> log(:close, query, nil)
885885
end
886886

@@ -948,27 +948,22 @@ defmodule DBConnection do
948948
end
949949

950950
def run(pool, fun, opts) do
951-
case checkout(pool, nil, opts) do
952-
{:ok, conn, _} ->
953-
old_status = status(conn, opts)
954-
951+
case checkout(pool, &run_status/3, nil, opts) do
952+
{:ok, conn, old_status, _} ->
955953
try do
956954
result = fun.(conn)
957-
{result, run(conn, &run_status/3, nil, opts)}
955+
{:ok, new_status, _meter} = run_status(conn, nil, opts)
956+
{result, new_status}
958957
catch
959958
kind, error ->
960959
checkin(conn)
961960
:erlang.raise(kind, error, __STACKTRACE__)
962961
else
963-
{result, {:error, _, _}} ->
962+
{result, new_status} when new_status == :error or old_status == new_status ->
964963
checkin(conn)
965964
result
966965

967-
{result, {^old_status, _meter}} ->
968-
checkin(conn)
969-
result
970-
971-
{_result, {new_status, _meter}} ->
966+
{_result, new_status} ->
972967
err =
973968
DBConnection.ConnectionError.exception(
974969
"connection was checked out with status #{inspect(old_status)} " <>
@@ -977,9 +972,6 @@ defmodule DBConnection do
977972

978973
disconnect(conn, err)
979974
raise err
980-
981-
{_result, {kind, reason, stack, _meter}} ->
982-
:erlang.raise(kind, reason, stack)
983975
end
984976

985977
{:error, err, _} ->
@@ -1065,11 +1057,8 @@ defmodule DBConnection do
10651057
{:ok, _} ->
10661058
run_transaction(conn, fun, &run/4, opts)
10671059

1068-
{:error, %DBConnection.TransactionError{}} ->
1069-
{:error, :rollback}
1070-
1071-
{:error, err} ->
1072-
raise err
1060+
{:error, error} ->
1061+
rollback_or_raise(error)
10731062
end
10741063
end
10751064

@@ -1078,14 +1067,14 @@ defmodule DBConnection do
10781067
{:ok, conn, _} ->
10791068
run_transaction(conn, fun, &checkin/4, opts)
10801069

1081-
{:error, %DBConnection.TransactionError{}} ->
1082-
{:error, :rollback}
1083-
1084-
{:error, err} ->
1085-
raise err
1070+
{:error, error} ->
1071+
rollback_or_raise(error)
10861072
end
10871073
end
10881074

1075+
defp rollback_or_raise(%DBConnection.TransactionError{}), do: {:error, :rollback}
1076+
defp rollback_or_raise(other), do: raise(other)
1077+
10891078
@doc """
10901079
Rollback a database transaction and release lock on connection.
10911080
@@ -1147,14 +1136,8 @@ defmodule DBConnection do
11471136
@spec status(conn, opts :: Keyword.t()) :: status
11481137
def status(conn, opts \\ []) do
11491138
case run(conn, &run_status/3, nil, opts) do
1150-
{status, _meter} ->
1151-
status
1152-
1153-
{:error, _err, _meter} ->
1154-
:error
1155-
1156-
{kind, reason, stack, _meter} ->
1157-
:erlang.raise(kind, reason, stack)
1139+
{:ok, status, _meter} -> status
1140+
{:error, _err, _meter} -> :error
11581141
end
11591142
end
11601143

@@ -1336,25 +1319,6 @@ defmodule DBConnection do
13361319
end
13371320
end
13381321

1339-
defp checkout(%DBConnection{} = conn, fun, meter, opts) do
1340-
with {:ok, result, meter} <- fun.(conn, meter, opts) do
1341-
{:ok, conn, result, meter}
1342-
end
1343-
end
1344-
1345-
defp checkout(pool, fun, meter, opts) do
1346-
with {:ok, conn, meter} <- checkout(pool, meter, opts) do
1347-
case fun.(conn, meter, opts) do
1348-
{:ok, result, meter} ->
1349-
{:ok, conn, result, meter}
1350-
1351-
error ->
1352-
checkin(conn)
1353-
error
1354-
end
1355-
end
1356-
end
1357-
13581322
defp checkin(%DBConnection{pool_ref: pool_ref}) do
13591323
Holder.checkin(pool_ref)
13601324
end
@@ -1365,10 +1329,6 @@ defmodule DBConnection do
13651329
return
13661330
end
13671331

1368-
defp checkin(pool, fun, meter, opts) do
1369-
run(pool, fun, meter, opts)
1370-
end
1371-
13721332
defp disconnect(%DBConnection{pool_ref: pool_ref}, err) do
13731333
_ = Holder.disconnect(pool_ref, err)
13741334
:ok
@@ -1487,16 +1447,12 @@ defmodule DBConnection do
14871447
defp prepare_declare(conn, query, params, opts) do
14881448
result =
14891449
with {:ok, query, meter} <- parse(query, meter(opts), opts) do
1490-
parsed_prepare_declare(conn, query, params, meter, opts)
1450+
run(conn, &run_prepare_declare(&1, query, params, &2, &3), meter, opts)
14911451
end
14921452

14931453
log(result, :prepare_declare, query, params)
14941454
end
14951455

1496-
defp parsed_prepare_declare(conn, query, params, meter, opts) do
1497-
run(conn, &run_prepare_declare(&1, query, params, &2, &3), meter, opts)
1498-
end
1499-
15001456
defp prepare_declare!(conn, query, params, opts) do
15011457
case prepare_declare(conn, query, params, opts) do
15021458
{:ok, query, cursor} ->
@@ -1511,7 +1467,7 @@ defmodule DBConnection do
15111467
result =
15121468
case maybe_encode(query, params, meter(opts), opts) do
15131469
{:prepare, meter} ->
1514-
parsed_prepare_declare(conn, query, params, meter, opts)
1470+
run(conn, &run_prepare_declare(&1, query, params, &2, &3), meter, opts)
15151471

15161472
{:ok, params, meter} ->
15171473
run(conn, &run_declare(&1, query, params, &2, &3), meter, opts)
@@ -1523,12 +1479,6 @@ defmodule DBConnection do
15231479
log(result, :declare, query, params)
15241480
end
15251481

1526-
defp deallocate(conn, query, cursor, opts) do
1527-
conn
1528-
|> run_cleanup(&run_deallocate/4, [query, cursor], meter(opts), opts)
1529-
|> log(:deallocate, query, cursor)
1530-
end
1531-
15321482
defp run_prepare(conn, query, meter, opts) do
15331483
with {:ok, query, meter} <- prepare(conn, query, meter, opts) do
15341484
describe(conn, query, meter, opts)
@@ -1565,53 +1515,26 @@ defmodule DBConnection do
15651515
end
15661516

15671517
defp raised_close(conn, query, meter, opts, kind, reason, stack) do
1568-
with {:ok, _, meter} <- run_close(conn, [query], meter, opts) do
1518+
with {:ok, _, meter} <- run_close(conn, query, meter, opts) do
15691519
{kind, reason, stack, meter}
15701520
end
15711521
end
15721522

1573-
defp run_close(conn, args, meter, opts) do
1523+
defp run_close(conn, query, meter, opts) do
15741524
meter = event(meter, :close)
1575-
cleanup(conn, :handle_close, args, meter, opts)
1576-
end
1577-
1578-
defp run_cleanup(%DBConnection{} = conn, fun, args, meter, opts) do
1579-
fun.(conn, args, meter, opts)
1580-
end
1581-
1582-
defp run_cleanup(pool, fun, args, meter, opts) do
1583-
with {:ok, conn, meter} <- checkout(pool, meter, opts) do
1584-
try do
1585-
fun.(conn, args, meter, opts)
1586-
after
1587-
checkin(conn)
1588-
end
1589-
end
1525+
run_cleanup(conn, :handle_close, [query], meter, opts)
15901526
end
15911527

1592-
defp cleanup(conn, fun, args, meter, opts) do
1528+
defp run_cleanup(conn, fun, args, meter, opts) do
15931529
%DBConnection{pool_ref: pool_ref} = conn
15941530

1595-
case Holder.cleanup(pool_ref, fun, args, opts) do
1596-
{:ok, result, _conn_state} ->
1597-
{:ok, result, meter}
1598-
1599-
{:error, err, _conn_state} ->
1600-
{:error, err, meter}
1601-
1602-
{:disconnect, err, _conn_state} ->
1603-
disconnect(conn, err)
1604-
{:error, err, meter}
1605-
1606-
{:catch, kind, reason, stack} ->
1607-
stop(conn, kind, reason, stack)
1608-
{kind, reason, stack, meter}
1609-
1610-
other ->
1611-
bad_return!(other, conn, meter)
1612-
end
1531+
Holder.cleanup(pool_ref, fun, args, opts)
1532+
|> handle_common_result(conn, meter)
16131533
end
16141534

1535+
# run/4 and checkout/4 are the two entry points to get a connection.
1536+
# run returns only the result, checkout also returns the connection.
1537+
16151538
defp run(%DBConnection{} = conn, fun, meter, opts) do
16161539
fun.(conn, meter, opts)
16171540
end
@@ -1626,6 +1549,25 @@ defmodule DBConnection do
16261549
end
16271550
end
16281551

1552+
defp checkout(%DBConnection{} = conn, fun, meter, opts) do
1553+
with {:ok, result, meter} <- fun.(conn, meter, opts) do
1554+
{:ok, conn, result, meter}
1555+
end
1556+
end
1557+
1558+
defp checkout(pool, fun, meter, opts) do
1559+
with {:ok, conn, meter} <- checkout(pool, meter, opts) do
1560+
case fun.(conn, meter, opts) do
1561+
{:ok, result, meter} ->
1562+
{:ok, conn, result, meter}
1563+
1564+
error ->
1565+
checkin(conn)
1566+
error
1567+
end
1568+
end
1569+
end
1570+
16291571
defp meter(opts) do
16301572
case Keyword.get(opts, :log) do
16311573
nil -> nil
@@ -1880,15 +1822,15 @@ defmodule DBConnection do
18801822

18811823
case Holder.handle(pool_ref, :handle_status, [], opts) do
18821824
{status, _conn_state} when status in [:idle, :transaction, :error] ->
1883-
{status, meter}
1825+
{:ok, status, meter}
18841826

18851827
{:disconnect, err, _conn_state} ->
18861828
disconnect(conn, err)
1887-
{:error, err, meter}
1829+
{:ok, :error, meter}
18881830

18891831
{:catch, kind, reason, stack} ->
18901832
stop(conn, kind, reason, stack)
1891-
{kind, reason, stack, meter}
1833+
:erlang.raise(kind, reason, stack)
18921834

18931835
other ->
18941836
bad_return!(other, conn, meter)
@@ -1920,9 +1862,12 @@ defmodule DBConnection do
19201862
end
19211863
end
19221864

1923-
defp stream_fetch(conn, {:cont, query, cursor}, opts) do
1924-
conn
1925-
|> run(&run_stream_fetch(&1, [query, cursor], &2, &3), meter(opts), opts)
1865+
defp stream_fetch(%DBConnection{} = conn, {:cont, query, cursor}, opts) do
1866+
with {ok, result, meter} when ok in [:cont, :halt] <-
1867+
run_fetch(conn, [query, cursor], meter(opts), opts),
1868+
{:ok, result, meter} <- decode(query, result, meter, opts) do
1869+
{ok, result, meter}
1870+
end
19261871
|> log(:fetch, query, cursor)
19271872
|> case do
19281873
{ok, result} when ok in [:cont, :halt] ->
@@ -1937,15 +1882,6 @@ defmodule DBConnection do
19371882
{:halt, state}
19381883
end
19391884

1940-
defp run_stream_fetch(conn, args, meter, opts) do
1941-
[query, _] = args
1942-
1943-
with {ok, result, meter} when ok in [:cont, :halt] <- run_fetch(conn, args, meter, opts),
1944-
{:ok, result, meter} <- decode(query, result, meter, opts) do
1945-
{ok, result, meter}
1946-
end
1947-
end
1948-
19491885
defp run_fetch(conn, args, meter, opts) do
19501886
%DBConnection{pool_ref: pool_ref} = conn
19511887
meter = event(meter, :fetch)
@@ -1962,12 +1898,12 @@ defmodule DBConnection do
19621898
end
19631899
end
19641900

1965-
defp stream_deallocate(conn, {_status, query, cursor}, opts),
1966-
do: deallocate(conn, query, cursor, opts)
1901+
defp stream_deallocate(conn, {_status, query, cursor}, opts) do
1902+
meter = event(meter(opts), :deallocate)
19671903

1968-
defp run_deallocate(conn, args, meter, opts) do
1969-
meter = event(meter, :deallocate)
1970-
cleanup(conn, :handle_deallocate, args, meter, opts)
1904+
conn
1905+
|> run_cleanup(:handle_deallocate, [query, cursor], meter, opts)
1906+
|> log(:deallocate, query, cursor)
19711907
end
19721908

19731909
defp resource(%DBConnection{} = conn, start, next, stop, opts) do

0 commit comments

Comments
 (0)