diff --git a/lib/sqlitex.ex b/lib/sqlitex.ex index abe1137..f86f38e 100644 --- a/lib/sqlitex.ex +++ b/lib/sqlitex.ex @@ -64,6 +64,24 @@ defmodule Sqlitex do res end + @doc """ + Sets a PID to recieve notifications about table updates. + + Messages will come in the shape of: + `{action, table, rowid}` + + * `action` -> `:insert | :update | :delete` + * `table` -> charlist of the table name. Example: `'posts'` + * `rowid` -> internal immutable rowid index of the row. + This is *NOT* the `id` or `primary key` of the row. + See the [official docs](https://www.sqlite.org/c3ref/update_hook.html). + """ + @spec set_update_hook(connection, pid, Keyword.t()) :: :ok | {:error, term()} + def set_update_hook(db, pid, opts \\ []) do + timeout = Keyword.get(opts, :db_timeout, Config.db_timeout()) + :esqlite3.set_update_hook(pid, db, timeout) + end + @spec exec(connection, string_or_charlist) :: :ok | sqlite_error @spec exec(connection, string_or_charlist, Keyword.t) :: :ok | sqlite_error def exec(db, sql, opts \\ []) do diff --git a/lib/sqlitex/server.ex b/lib/sqlitex/server.ex index c7276e3..cad6e8d 100644 --- a/lib/sqlitex/server.ex +++ b/lib/sqlitex/server.ex @@ -109,6 +109,11 @@ defmodule Sqlitex.Server do {:reply, result, {db, stmt_cache, timeout}} end + def handle_call({:set_update_hook, pid, opts}, _from, {db, stmt_cache, timeout}) do + result = Sqlitex.set_update_hook(db, pid, opts) + {:reply, result, {db, stmt_cache, timeout}} + end + def handle_cast(:stop, {db, stmt_cache, timeout}) do {:stop, :normal, {db, stmt_cache, timeout}} end @@ -132,6 +137,10 @@ defmodule Sqlitex.Server do GenServer.call(pid, {:query_rows, sql, opts}, timeout(opts)) end + def set_update_hook(server_pid, notification_pid, opts \\ []) do + GenServer.call(server_pid, {:set_update_hook, notification_pid, opts}, timeout(opts)) + end + @doc """ Prepares a SQL statement for future use. diff --git a/mix.exs b/mix.exs index 4f929a8..889ebe1 100644 --- a/mix.exs +++ b/mix.exs @@ -4,21 +4,23 @@ defmodule Sqlitex.Mixfile do def project do [ app: :sqlitex, - version: "1.4.3", + version: "1.5.0", elixir: "~> 1.4", deps: deps(), package: package(), + source_url: "https://github.com/Sqlite-Ecto/sqlitex", test_coverage: [tool: ExCoveralls], preferred_cli_env: [ - coveralls: :test, - "coveralls.circle": :test, - "coveralls.detail": :test, - "coveralls.post": :test, - "coveralls.html": :test], + coveralls: :test, + "coveralls.circle": :test, + "coveralls.detail": :test, + "coveralls.post": :test, + "coveralls.html": :test + ], description: """ A thin Elixir wrapper around esqlite """, - dialyzer: [plt_add_deps: :transitive], + dialyzer: [plt_add_deps: :transitive] ] end @@ -30,22 +32,24 @@ defmodule Sqlitex.Mixfile do # Type `mix help deps` for more examples and options defp deps do [ - {:esqlite, "~> 0.2.4"}, + {:esqlite, "~> 0.2.5"}, {:decimal, "~> 1.5"}, {:credo, "~> 0.10", only: :dev}, {:dialyxir, "~> 1.0.0-rc.3", only: :dev, runtime: false}, {:excoveralls, "~> 0.10", only: :test}, {:ex_doc, "~> 0.19", only: :docs, runtime: false}, {:excheck, "~> 0.6", only: :test}, - {:triq, "~> 1.2", only: :test}, + {:triq, "~> 1.2", only: :test} ] end defp package do - [maintainers: ["Michael Ries", "Jason M Barnes", "Graeme Coupar", "Eric Scouten", "Connor Rigby"], - licenses: ["MIT"], - links: %{ - github: "https://github.com/Sqlite-Ecto/sqlitex", - docs: "http://hexdocs.pm/sqlitex"}] + [ + licenses: ["MIT"], + links: %{ + "GitHub" => "https://github.com/Sqlite-Ecto/sqlitex", + "docs" => "http://hexdocs.pm/sqlitex" + } + ] end end diff --git a/mix.lock b/mix.lock index a9d4876..69242ff 100644 --- a/mix.lock +++ b/mix.lock @@ -5,7 +5,7 @@ "decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"}, "dialyxir": {:hex, :dialyxir, "1.0.0-rc.3", "774306f84973fc3f1e2e8743eeaa5f5d29b117f3916e5de74c075c02f1b8ef55", [:mix], [], "hexpm"}, "earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"}, - "esqlite": {:hex, :esqlite, "0.2.4", "3a8a352c190afe2d6b828b252a6fbff65b5cc1124647f38b15bdab3bf6fd4b3e", [:rebar3], [], "hexpm"}, + "esqlite": {:hex, :esqlite, "0.2.5", "cab6d87aeb5f33d848b9bb8a21129e9512ea608f930d4c63576942d8f7d72218", [:rebar3], [], "hexpm"}, "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"}, "excheck": {:hex, :excheck, "0.6.0", "f8595a8ac2c0abc0d060c1a4fce7d26f41574543366a52d5f3c84de30a69747b", [:mix], [], "hexpm"}, "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"}, diff --git a/test/sqlitex_test.exs b/test/sqlitex_test.exs index 32d93ed..32e0dbd 100644 --- a/test/sqlitex_test.exs +++ b/test/sqlitex_test.exs @@ -12,6 +12,19 @@ defmodule SqlitexTest do {:ok, golf_db: TestDatabase.init(db)} end + test "set_update_hook", %{golf_db: db} do + :ok = Sqlitex.set_update_hook(db, self()) + :ok = Sqlitex.exec(db, "CREATE TABLE test (id INTEGER PRIMARY KEY, val STRING);") + :ok = Sqlitex.exec(db, "INSERT INTO test (val) VALUES ('this is a test');") + assert_receive {:insert, 'test', 1} + + {:ok, conn} = Sqlitex.Server.start_link(@shared_cache) + :ok = Sqlitex.Server.set_update_hook(conn, self()) + :ok = Sqlitex.Server.exec(conn, "CREATE TABLE blerps (id INTEGER PRIMARY KEY, val STRING);") + :ok = Sqlitex.Server.exec(conn, "INSERT INTO blerps (val) VALUES ('this is a test');") + assert_receive {:insert, 'blerps', 1} + end + test "server basic query" do {:ok, conn} = Sqlitex.Server.start_link(@shared_cache) {:ok, [row]} = Sqlitex.Server.query(conn, "SELECT * FROM players ORDER BY id LIMIT 1")