Skip to content
This repository was archived by the owner on Mar 19, 2021. It is now read-only.

Commit 64357a5

Browse files
authored
Add notifications feature (#72)
This adds the ability to subscribe to notifications about a table
1 parent b0471de commit 64357a5

File tree

5 files changed

+59
-15
lines changed

5 files changed

+59
-15
lines changed

lib/sqlitex.ex

+18
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,24 @@ defmodule Sqlitex do
6464
res
6565
end
6666

67+
@doc """
68+
Sets a PID to recieve notifications about table updates.
69+
70+
Messages will come in the shape of:
71+
`{action, table, rowid}`
72+
73+
* `action` -> `:insert | :update | :delete`
74+
* `table` -> charlist of the table name. Example: `'posts'`
75+
* `rowid` -> internal immutable rowid index of the row.
76+
This is *NOT* the `id` or `primary key` of the row.
77+
See the [official docs](https://www.sqlite.org/c3ref/update_hook.html).
78+
"""
79+
@spec set_update_hook(connection, pid, Keyword.t()) :: :ok | {:error, term()}
80+
def set_update_hook(db, pid, opts \\ []) do
81+
timeout = Keyword.get(opts, :db_timeout, Config.db_timeout())
82+
:esqlite3.set_update_hook(pid, db, timeout)
83+
end
84+
6785
@spec exec(connection, string_or_charlist) :: :ok | sqlite_error
6886
@spec exec(connection, string_or_charlist, Keyword.t) :: :ok | sqlite_error
6987
def exec(db, sql, opts \\ []) do

lib/sqlitex/server.ex

+9
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ defmodule Sqlitex.Server do
109109
{:reply, result, {db, stmt_cache, timeout}}
110110
end
111111

112+
def handle_call({:set_update_hook, pid, opts}, _from, {db, stmt_cache, timeout}) do
113+
result = Sqlitex.set_update_hook(db, pid, opts)
114+
{:reply, result, {db, stmt_cache, timeout}}
115+
end
116+
112117
def handle_cast(:stop, {db, stmt_cache, timeout}) do
113118
{:stop, :normal, {db, stmt_cache, timeout}}
114119
end
@@ -132,6 +137,10 @@ defmodule Sqlitex.Server do
132137
GenServer.call(pid, {:query_rows, sql, opts}, timeout(opts))
133138
end
134139

140+
def set_update_hook(server_pid, notification_pid, opts \\ []) do
141+
GenServer.call(server_pid, {:set_update_hook, notification_pid, opts}, timeout(opts))
142+
end
143+
135144
@doc """
136145
Prepares a SQL statement for future use.
137146

mix.exs

+18-14
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,23 @@ defmodule Sqlitex.Mixfile do
44
def project do
55
[
66
app: :sqlitex,
7-
version: "1.4.3",
7+
version: "1.5.0",
88
elixir: "~> 1.4",
99
deps: deps(),
1010
package: package(),
11+
source_url: "https://github.com/Sqlite-Ecto/sqlitex",
1112
test_coverage: [tool: ExCoveralls],
1213
preferred_cli_env: [
13-
coveralls: :test,
14-
"coveralls.circle": :test,
15-
"coveralls.detail": :test,
16-
"coveralls.post": :test,
17-
"coveralls.html": :test],
14+
coveralls: :test,
15+
"coveralls.circle": :test,
16+
"coveralls.detail": :test,
17+
"coveralls.post": :test,
18+
"coveralls.html": :test
19+
],
1820
description: """
1921
A thin Elixir wrapper around esqlite
2022
""",
21-
dialyzer: [plt_add_deps: :transitive],
23+
dialyzer: [plt_add_deps: :transitive]
2224
]
2325
end
2426

@@ -30,22 +32,24 @@ defmodule Sqlitex.Mixfile do
3032
# Type `mix help deps` for more examples and options
3133
defp deps do
3234
[
33-
{:esqlite, "~> 0.2.4"},
35+
{:esqlite, "~> 0.2.5"},
3436
{:decimal, "~> 1.5"},
3537
{:credo, "~> 0.10", only: :dev},
3638
{:dialyxir, "~> 1.0.0-rc.3", only: :dev, runtime: false},
3739
{:excoveralls, "~> 0.10", only: :test},
3840
{:ex_doc, "~> 0.19", only: :docs, runtime: false},
3941
{:excheck, "~> 0.6", only: :test},
40-
{:triq, "~> 1.2", only: :test},
42+
{:triq, "~> 1.2", only: :test}
4143
]
4244
end
4345

4446
defp package do
45-
[maintainers: ["Michael Ries", "Jason M Barnes", "Graeme Coupar", "Eric Scouten", "Connor Rigby"],
46-
licenses: ["MIT"],
47-
links: %{
48-
github: "https://github.com/Sqlite-Ecto/sqlitex",
49-
docs: "http://hexdocs.pm/sqlitex"}]
47+
[
48+
licenses: ["MIT"],
49+
links: %{
50+
"GitHub" => "https://github.com/Sqlite-Ecto/sqlitex",
51+
"docs" => "http://hexdocs.pm/sqlitex"
52+
}
53+
]
5054
end
5155
end

mix.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
66
"dialyxir": {:hex, :dialyxir, "1.0.0-rc.3", "774306f84973fc3f1e2e8743eeaa5f5d29b117f3916e5de74c075c02f1b8ef55", [:mix], [], "hexpm"},
77
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
8-
"esqlite": {:hex, :esqlite, "0.2.4", "3a8a352c190afe2d6b828b252a6fbff65b5cc1124647f38b15bdab3bf6fd4b3e", [:rebar3], [], "hexpm"},
8+
"esqlite": {:hex, :esqlite, "0.2.5", "cab6d87aeb5f33d848b9bb8a21129e9512ea608f930d4c63576942d8f7d72218", [:rebar3], [], "hexpm"},
99
"ex_doc": {:hex, :ex_doc, "0.19.1", "519bb9c19526ca51d326c060cb1778d4a9056b190086a8c6c115828eaccea6cf", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.7", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm"},
1010
"excheck": {:hex, :excheck, "0.6.0", "f8595a8ac2c0abc0d060c1a4fce7d26f41574543366a52d5f3c84de30a69747b", [:mix], [], "hexpm"},
1111
"excoveralls": {:hex, :excoveralls, "0.10.0", "a4508bdd408829f38e7b2519f234b7fd5c83846099cda348efcb5291b081200c", [:mix], [{:hackney, "~> 1.13", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm"},

test/sqlitex_test.exs

+13
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ defmodule SqlitexTest do
1212
{:ok, golf_db: TestDatabase.init(db)}
1313
end
1414

15+
test "set_update_hook", %{golf_db: db} do
16+
:ok = Sqlitex.set_update_hook(db, self())
17+
:ok = Sqlitex.exec(db, "CREATE TABLE test (id INTEGER PRIMARY KEY, val STRING);")
18+
:ok = Sqlitex.exec(db, "INSERT INTO test (val) VALUES ('this is a test');")
19+
assert_receive {:insert, 'test', 1}
20+
21+
{:ok, conn} = Sqlitex.Server.start_link(@shared_cache)
22+
:ok = Sqlitex.Server.set_update_hook(conn, self())
23+
:ok = Sqlitex.Server.exec(conn, "CREATE TABLE blerps (id INTEGER PRIMARY KEY, val STRING);")
24+
:ok = Sqlitex.Server.exec(conn, "INSERT INTO blerps (val) VALUES ('this is a test');")
25+
assert_receive {:insert, 'blerps', 1}
26+
end
27+
1528
test "server basic query" do
1629
{:ok, conn} = Sqlitex.Server.start_link(@shared_cache)
1730
{:ok, [row]} = Sqlitex.Server.query(conn, "SELECT * FROM players ORDER BY id LIMIT 1")

0 commit comments

Comments
 (0)