diff --git a/lib/feeb/db/repo.ex b/lib/feeb/db/repo.ex index 8046818..e49ce85 100644 --- a/lib/feeb/db/repo.ex +++ b/lib/feeb/db/repo.ex @@ -236,7 +236,7 @@ defmodule Feeb.DB.Repo do with {:ok, {stmt, stmt_sql}} <- prepare_query(state, query_id, sql), true = stmt_sql == sql, - :ok <- SQLite.bind(state.conn, stmt, bindings_values), + :ok <- SQLite.bind(stmt, bindings_values), {:ok, rows} <- SQLite.all(state.conn, stmt) do attrs = %{ format: opts[:format] || :schema, @@ -258,7 +258,7 @@ defmodule Feeb.DB.Repo do raise "Remove or document usage" with {:ok, stmt} <- SQLite.prepare(state.conn, raw_sql), - :ok <- SQLite.bind(state.conn, stmt, bindings_values), + :ok <- SQLite.bind(stmt, bindings_values), {:ok, rows} <- SQLite.all(state.conn, stmt) do schema = Keyword.fetch!(opts, :schema) result = format_custom(:all, schema, rows) diff --git a/lib/feeb/db/sqlite.ex b/lib/feeb/db/sqlite.ex index db8becd..6f647b0 100644 --- a/lib/feeb/db/sqlite.ex +++ b/lib/feeb/db/sqlite.ex @@ -4,6 +4,8 @@ defmodule Feeb.DB.SQLite do - List of error codes and their meaning: https://www.sqlite.org/rescode.html """ + require Logger + alias Exqlite.Sqlite3, as: Driver @type conn :: reference() @@ -39,8 +41,15 @@ defmodule Feeb.DB.SQLite do def bind(_, _, []), do: :ok - def bind(conn, stmt, bindings) when is_list(bindings), - do: Driver.bind(conn, stmt, bindings) + def bind(stmt, bindings) when is_list(bindings) do + try do + Driver.bind(stmt, bindings) + rescue + e in ArgumentError -> + Logger.error(e) + {:error, :arguments_wrong_length} + end + end @doc """ Convenience wrapper for functions that do not expect a return value diff --git a/mix.exs b/mix.exs index 9ded148..c618d2b 100644 --- a/mix.exs +++ b/mix.exs @@ -54,10 +54,10 @@ defmodule Feeb.DB.Mixfile do def deps do [ - {:exqlite, "~> 0.23"}, + {:exqlite, "~> 0.33"}, {:stack, "~> 1.0"}, {:dialyxir, "~> 1.4", only: [:dev], runtime: false}, - {:excoveralls, "~> 0.18.2", only: :test}, + {:excoveralls, "~> 0.18.5", only: :test}, {:mix_test_watch, "~> 1.2", only: [:dev, :test], runtime: false}, {:mox, "~> 1.1", only: :test} ] diff --git a/mix.lock b/mix.lock index 8ce79f6..c079ac1 100644 --- a/mix.lock +++ b/mix.lock @@ -1,16 +1,16 @@ %{ - "cc_precompiler": {:hex, :cc_precompiler, "0.1.10", "47c9c08d8869cf09b41da36538f62bc1abd3e19e41701c2cea2675b53c704258", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "f6e046254e53cd6b41c6bacd70ae728011aa82b2742a80d6e2214855c6e06b22"}, - "db_connection": {:hex, :db_connection, "2.7.0", "b99faa9291bb09892c7da373bb82cba59aefa9b36300f6145c5f201c7adf48ec", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dcf08f31b2701f857dfc787fbad78223d61a32204f217f15e881dd93e4bdd3ff"}, - "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, - "elixir_make": {:hex, :elixir_make, "0.8.4", "4960a03ce79081dee8fe119d80ad372c4e7badb84c493cc75983f9d3bc8bde0f", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.0", [hex: :certifi, repo: "hexpm", optional: true]}], "hexpm", "6e7f1d619b5f61dfabd0a20aa268e575572b542ac31723293a4c1a567d5ef040"}, + "cc_precompiler": {:hex, :cc_precompiler, "0.1.11", "8c844d0b9fb98a3edea067f94f616b3f6b29b959b6b3bf25fee94ffe34364768", [:mix], [{:elixir_make, "~> 0.7", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "3427232caf0835f94680e5bcf082408a70b48ad68a5f5c0b02a3bea9f3a075b9"}, + "db_connection": {:hex, :db_connection, "2.8.0", "64fd82cfa6d8e25ec6660cea73e92a4cbc6a18b31343910427b702838c4b33b2", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "008399dae5eee1bf5caa6e86d204dcb44242c82b1ed5e22c881f2c34da201b15"}, + "dialyxir": {:hex, :dialyxir, "1.4.6", "7cca478334bf8307e968664343cbdb432ee95b4b68a9cba95bdabb0ad5bdfd9a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "8cf5615c5cd4c2da6c501faae642839c8405b49f8aa057ad4ae401cb808ef64d"}, + "elixir_make": {:hex, :elixir_make, "0.9.0", "6484b3cd8c0cee58f09f05ecaf1a140a8c97670671a6a0e7ab4dc326c3109726", [:mix], [], "hexpm", "db23d4fd8b757462ad02f8aa73431a426fe6671c80b200d9710caf3d1dd0ffdb"}, "erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"}, - "excoveralls": {:hex, :excoveralls, "0.18.2", "86efd87a0676a3198ff50b8c77620ea2f445e7d414afa9ec6c4ba84c9f8bdcc2", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "230262c418f0de64077626a498bd4fdf1126d5c2559bb0e6b43deac3005225a4"}, - "exqlite": {:hex, :exqlite, "0.23.0", "6e851c937a033299d0784994c66da24845415072adbc455a337e20087bce9033", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "404341cceec5e6466aaed160cf0b58be2019b60af82588c215e1224ebd3ec831"}, - "file_system": {:hex, :file_system, "1.0.1", "79e8ceaddb0416f8b8cd02a0127bdbababe7bf4a23d2a395b983c1f8b3f73edd", [:mix], [], "hexpm", "4414d1f38863ddf9120720cd976fce5bdde8e91d8283353f0e31850fa89feb9e"}, + "excoveralls": {:hex, :excoveralls, "0.18.5", "e229d0a65982613332ec30f07940038fe451a2e5b29bce2a5022165f0c9b157e", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "523fe8a15603f86d64852aab2abe8ddbd78e68579c8525ae765facc5eae01562"}, + "exqlite": {:hex, :exqlite, "0.33.0", "2cc96c4227fbb2d0864716def736dff18afb9949b1eaa74630822a0865b4b342", [:make, :mix], [{:cc_precompiler, "~> 0.1", [hex: :cc_precompiler, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.8", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "8a7c2792e567bbebb4dafe96f6397f1c527edd7039d74f508a603817fbad2844"}, + "file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"}, "jason": {:hex, :jason, "1.4.4", "b9226785a9aa77b6857ca22832cffa5d5011a667207eb2a0ad56adb5db443b8a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "c5eb0cab91f094599f94d55bc63409236a8ec69a21a67814529e8d5f6cc90b3b"}, - "mix_test_watch": {:hex, :mix_test_watch, "1.2.0", "1f9acd9e1104f62f280e30fc2243ae5e6d8ddc2f7f4dc9bceb454b9a41c82b42", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "278dc955c20b3fb9a3168b5c2493c2e5cffad133548d307e0a50c7f2cfbf34f6"}, + "mix_test_watch": {:hex, :mix_test_watch, "1.3.0", "2ffc9f72b0d1f4ecf0ce97b044e0e3c607c3b4dc21d6228365e8bc7c2856dc77", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "f9e5edca976857ffac78632e635750d158df14ee2d6185a15013844af7570ffe"}, "mox": {:hex, :mox, "1.2.0", "a2cd96b4b80a3883e3100a221e8adc1b98e4c3a332a8fc434c39526babafd5b3", [:mix], [{:nimble_ownership, "~> 1.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}], "hexpm", "c7b92b3cc69ee24a7eeeaf944cd7be22013c52fcb580c1f33f50845ec821089a"}, - "nimble_ownership": {:hex, :nimble_ownership, "1.0.0", "3f87744d42c21b2042a0aa1d48c83c77e6dd9dd357e425a038dd4b49ba8b79a1", [:mix], [], "hexpm", "7c16cc74f4e952464220a73055b557a273e8b1b7ace8489ec9d86e9ad56cb2cc"}, + "nimble_ownership": {:hex, :nimble_ownership, "1.0.1", "f69fae0cdd451b1614364013544e66e4f5d25f36a2056a9698b793305c5aa3a6", [:mix], [], "hexpm", "3825e461025464f519f3f3e4a1f9b68c47dc151369611629ad08b636b73bb22d"}, "stack": {:hex, :stack, "1.0.0", "a216e49ca95d501b3d3ea1a68fc74061742deb412e94fc8a5ffb5bffc28efe9a", [:mix], [], "hexpm", "ba1142933a9a7f7e11f8565b9360395e736657e0cccee61d4e39db7c79983894"}, - "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, + "telemetry": {:hex, :telemetry, "1.3.0", "fedebbae410d715cf8e7062c96a1ef32ec22e764197f70cda73d82778d61e7a2", [:rebar3], [], "hexpm", "7015fc8919dbe63764f4b4b87a95b7c0996bd539e0d499be6ec9d7f3875b79e6"}, } diff --git a/test/db/sqlite_test.exs b/test/db/sqlite_test.exs index 9403177..f11dd0c 100644 --- a/test/db/sqlite_test.exs +++ b/test/db/sqlite_test.exs @@ -19,29 +19,29 @@ defmodule Feeb.DB.SQLiteTest do describe "bind/3" do test "binds variables to a prepared statement", %{c: c} do {:ok, stmt} = SQLite.prepare(c, "SELECT * FROM friends WHERE id = ?") - assert :ok = SQLite.bind(c, stmt, [1]) + assert :ok = SQLite.bind(stmt, [1]) {:ok, stmt} = SQLite.prepare(c, "BEGIN") - assert :ok = SQLite.bind(c, stmt, []) + assert :ok = SQLite.bind(stmt, []) end + @tag :capture_log test "fails when the number of arguments is wrong", %{c: c} do {:ok, stmt} = SQLite.prepare(c, "SELECT * FROM friends WHERE id = ?") - assert {:error, :arguments_wrong_length} = SQLite.bind(c, stmt, [1, 2, 3]) - # I *can* bind an empty list though - assert :ok = SQLite.bind(c, stmt, []) + assert {:error, :arguments_wrong_length} = SQLite.bind(stmt, [1, 2, 3]) + assert {:error, :arguments_wrong_length} = SQLite.bind(stmt, []) end end describe "one/2" do test "returns an entry if found", %{c: c} do {:ok, stmt} = SQLite.prepare(c, "SELECT * FROM friends WHERE id = ?") - :ok = SQLite.bind(c, stmt, [1]) + :ok = SQLite.bind(stmt, [1]) assert {:ok, [1, "Phoebe", nil]} == SQLite.one(c, stmt) end test "returns nil if not found", %{c: c} do {:ok, stmt} = SQLite.prepare(c, "SELECT * FROM friends WHERE id = ?") - :ok = SQLite.bind(c, stmt, [999]) + :ok = SQLite.bind(stmt, [999]) assert {:ok, nil} == SQLite.one(c, stmt) end @@ -99,7 +99,7 @@ defmodule Feeb.DB.SQLiteTest do # No results here {:ok, stmt} = SQLite.prepare(c, "UPDATE friends SET name = ? WHERE id = ?") - SQLite.bind(c, stmt, ["Jessie", 1]) + SQLite.bind(stmt, ["Jessie", 1]) assert :ok = SQLite.perform(c, stmt) # But the update did go through