Skip to content

Commit 837a15d

Browse files
authored
Adding before_disconnect hook (#271)
Allows consumers to specify a function or MFA to call before the database is disconnected.
1 parent fe3acf5 commit 837a15d

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

lib/exqlite/connection.ex

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,18 @@ defmodule Exqlite.Connection do
3636
:path,
3737
:transaction_status,
3838
:status,
39-
:chunk_size
39+
:chunk_size,
40+
:before_disconnect
4041
]
4142

4243
@type t() :: %__MODULE__{
4344
db: Sqlite3.db(),
4445
directory: String.t() | nil,
4546
path: String.t(),
4647
transaction_status: :idle | :transaction,
47-
status: :idle | :busy
48+
status: :idle | :busy,
49+
chunk_size: integer(),
50+
before_disconnect: (t -> any) | {module, atom, [any]} | nil
4851
}
4952

5053
@type journal_mode() :: :delete | :truncate | :persist | :memory | :wal | :off
@@ -73,6 +76,7 @@ defmodule Exqlite.Connection do
7376
| {:hard_heap_limit, integer()}
7477
| {:key, String.t()}
7578
| {:custom_pragmas, [{keyword(), integer() | boolean() | String.t()}]}
79+
| {:before_disconnect, (t -> any) | {module, atom, [any]} | nil}
7680

7781
@impl true
7882
@doc """
@@ -155,6 +159,9 @@ defmodule Exqlite.Connection do
155159
"./priv/sqlite/\#{arch_dir}/vss0"
156160
]
157161
```
162+
* `:before_disconnect` - A function to run before disconnect, either a
163+
2-arity fun or `{module, function, args}` with the close reason and
164+
`t:Exqlite.Connection.t/0` prepended to `args` or `nil` (default: `nil`)
158165
159166
For more information about the options above, see [sqlite documentation][1]
160167
@@ -190,7 +197,11 @@ defmodule Exqlite.Connection do
190197
end
191198

192199
@impl true
193-
def disconnect(_err, %__MODULE__{db: db}) do
200+
def disconnect(err, %__MODULE__{db: db} = state) do
201+
if state.before_disconnect != nil do
202+
apply(state.before_disconnect, [err, state])
203+
end
204+
194205
case Sqlite3.close(db) do
195206
:ok -> :ok
196207
{:error, reason} -> {:error, %Error{message: to_string(reason)}}
@@ -539,7 +550,8 @@ defmodule Exqlite.Connection do
539550
path: database,
540551
transaction_status: :idle,
541552
status: :idle,
542-
chunk_size: Keyword.get(options, :chunk_size)
553+
chunk_size: Keyword.get(options, :chunk_size),
554+
before_disconnect: Keyword.get(options, :before_disconnect, nil)
543555
}
544556

545557
{:ok, state}

test/exqlite/connection_test.exs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,23 @@ defmodule Exqlite.ConnectionTest do
184184

185185
assert :ok == Connection.disconnect(nil, conn)
186186
end
187+
188+
test "executes before_disconnect before disconnecting" do
189+
{:ok, pid} = Agent.start_link(fn -> 0 end)
190+
191+
{:ok, conn} =
192+
Connection.connect(
193+
database: :memory,
194+
before_disconnect: fn err, db ->
195+
Agent.update(pid, fn count -> count + 1 end)
196+
assert err == true
197+
assert db
198+
end
199+
)
200+
201+
assert :ok == Connection.disconnect(true, conn)
202+
assert Agent.get(pid, &Function.identity/1) == 1
203+
end
187204
end
188205

189206
describe ".handle_execute/4" do

0 commit comments

Comments
 (0)