diff --git a/integration_test/constraints_test.exs b/integration_test/constraints_test.exs index aa43ca7..eaa2697 100644 --- a/integration_test/constraints_test.exs +++ b/integration_test/constraints_test.exs @@ -52,7 +52,7 @@ defmodule Ecto.Integration.ConstraintsTest do assert_raise Ecto.ConstraintError, ~r/constraint error when attempting to insert struct/, fn -> PoolRepo.insert(overlapping_changeset) end - assert exception.message =~ "cannot_overlap (check_constraint)" + assert exception.message =~ ~r/cannot_overlap.*\(check_constraint\)/ assert exception.message =~ "The changeset has not defined any constraint." assert exception.message =~ "call `check_constraint/3`" diff --git a/integration_test/test_helper.exs b/integration_test/test_helper.exs index c622829..854a37c 100644 --- a/integration_test/test_helper.exs +++ b/integration_test/test_helper.exs @@ -116,6 +116,8 @@ ExUnit.start( :placeholders, # SQLite3 stores booleans as integers, causing Ecto's json_extract_path tests to fail :json_extract_path, + # SQLite3 doesn't support specifying columns for ON DELETE SET NULL + :on_delete_nilify_column_list, # We don't support selected_as :selected_as_with_group_by, diff --git a/lib/ecto/adapters/sqlite3/connection.ex b/lib/ecto/adapters/sqlite3/connection.ex index 0e3cf92..b5b8503 100644 --- a/lib/ecto/adapters/sqlite3/connection.ex +++ b/lib/ecto/adapters/sqlite3/connection.ex @@ -681,6 +681,13 @@ defmodule Ecto.Adapters.SQLite3.Connection do ] end + def execute_ddl({:rename, %Index{} = index, new_index}) do + [ + execute_ddl({:drop, index}), + execute_ddl({:create, %Index{index | name: new_index}}) + ] + end + def execute_ddl(string) when is_binary(string), do: [string] def execute_ddl(keyword) when is_list(keyword) do @@ -894,6 +901,10 @@ defmodule Ecto.Adapters.SQLite3.Connection do def cte(%{with_ctes: _}, _), do: [] + defp cte_expr({name, _opts, cte}, sources, query) do + cte_expr({name, cte}, sources, query) + end + defp cte_expr({name, cte}, sources, query) do [ quote_name(name), @@ -1113,7 +1124,7 @@ defmodule Ecto.Adapters.SQLite3.Connection do def limit(%{limit: nil}, _sources), do: [] - def limit(%{limit: %QueryExpr{expr: expression}} = query, sources) do + def limit(%{limit: %{expr: expression}} = query, sources) do [" LIMIT " | expr(expression, sources, query)] end diff --git a/mix.exs b/mix.exs index b09780d..9e32f71 100644 --- a/mix.exs +++ b/mix.exs @@ -34,8 +34,8 @@ defmodule EctoSQLite3.MixProject do defp deps do [ {:decimal, "~> 1.6 or ~> 2.0"}, - {:ecto_sql, "~> 3.9"}, - {:ecto, "~> 3.9"}, + {:ecto_sql, "~> 3.10"}, + {:ecto, "~> 3.10"}, {:exqlite, "~> 0.9"}, {:ex_doc, "~> 0.27", only: [:dev], runtime: false}, {:jason, ">= 0.0.0", only: [:dev, :test, :docs]}, diff --git a/mix.lock b/mix.lock index 3496f35..8af16bd 100644 --- a/mix.lock +++ b/mix.lock @@ -2,14 +2,13 @@ "benchee": {:hex, :benchee, "1.1.0", "f3a43817209a92a1fade36ef36b86e1052627fd8934a8b937ac9ab3a76c43062", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}], "hexpm", "7da57d545003165a012b587077f6ba90b89210fd88074ce3c60ce239eb5e6d93"}, "benchee_markdown": {:hex, :benchee_markdown, "0.3.1", "9d08a81ae217722ba65ade422b39dfb932cc14d96a2047c44dd30b025bbbb8b7", [:mix], [{:benchee, ">= 1.1.0 and < 2.0.0", [hex: :benchee, repo: "hexpm", optional: false]}], "hexpm", "6274a076e8bd51b192e957b6a7de957b4a1bbb5583892ea3673e0808f658bf5f"}, "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, - "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, - "db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"}, + "db_connection": {:hex, :db_connection, "2.5.0", "bb6d4f30d35ded97b29fe80d8bd6f928a1912ca1ff110831edcd238a1973652c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c92d5ba26cd69ead1ff7582dbb860adeedfff39774105a4f1c92cbb654b55aa2"}, "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"}, - "ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"}, - "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, + "ecto": {:hex, :ecto, "3.10.0", "1a088843f42a1917f2ff2a9191d3b5995db10faeb9fa8c1a8f8ebcdf39a70161", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4a8339a6acc0500516cf94ef074acb9c7f7c75360e45bf88f5c3a4577116686f"}, + "ecto_sql": {:hex, :ecto_sql, "3.10.1", "6ea6b3036a0b0ca94c2a02613fd9f742614b5cfe494c41af2e6571bb034dd94c", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.10.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 0.17.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f6a25bdbbd695f12c8171eaff0851fa4c8e72eec1e98c7364402dda9ce11c56b"}, "elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"}, "ex_doc": {:hex, :ex_doc, "0.29.1", "b1c652fa5f92ee9cf15c75271168027f92039b3877094290a75abcaac82a9f77", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "b7745fa6374a36daf484e2a2012274950e084815b936b1319aeebcf7809574f6"}, "exqlite": {:hex, :exqlite, "0.11.8", "b6bf596caa92d4811c303ddd8544dc9493a5351a18d2d16e1f85f977705cb39f", [:make, :mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "8591959284f1012c0d8cb26a09d5d9ba0bc0559cbeaf26fb8fbef14213d73bc0"}, @@ -20,7 +19,7 @@ "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, "myxql": {:hex, :myxql, "0.6.3", "3d77683a09f1227abb8b73d66b275262235c5cae68182f0cfa5897d72a03700e", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:geo, "~> 3.4", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "af9eb517ddaced5c5c28e8749015493757fd4413f2cfccea449c466d405d9f51"}, "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, - "postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"}, + "postgrex": {:hex, :postgrex, "0.17.0", "1ea81cb0820079bcedd880379357cfc9faf70bc8fee3a87054b13fcb646c6150", [:mix], [{:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "ea670562ed62a5ca40aa4689290167a97b0712f59f7e318d6ce9eb253f52e02e"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, "temp": {:hex, :temp, "0.4.7", "2c78482cc2294020a4bc0c95950b907ff386523367d4e63308a252feffbea9f2", [:mix], [], "hexpm", "6af19e7d6a85a427478be1021574d1ae2a1e1b90882586f06bde76c63cd03e0d"}, diff --git a/test/ecto/adapters/sqlite3/connection_test.exs b/test/ecto/adapters/sqlite3/connection_test.exs index a1bb188..b34d6ea 100644 --- a/test/ecto/adapters/sqlite3/connection_test.exs +++ b/test/ecto/adapters/sqlite3/connection_test.exs @@ -1148,11 +1148,11 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do assert_raise Ecto.QueryError, fn -> update_all(query) end - end test "update all with subquery" do sub = from(p in Schema, where: p.x > ^10) + query = Schema |> join(:inner, [p], p2 in subquery(sub), on: p.id == p2.id) @@ -1162,9 +1162,9 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do Ecto.Adapter.Queryable.plan_query(:update_all, Ecto.Adapters.SQLite3, query) assert update_all(planned_query) == - ~s{UPDATE "schema" AS s0 SET "x" = ? FROM } <> - ~s{(SELECT ss0."id" AS "id", ss0."x" AS "x", ss0."y" AS "y", ss0."z" AS "z", ss0."w" AS "w", ss0."meta" AS "meta" FROM "schema" AS ss0 WHERE (ss0."x" > ?)) } <> - ~s{AS s1 WHERE (s0."id" = s1."id")} + ~s{UPDATE "schema" AS s0 SET "x" = ? FROM } <> + ~s{(SELECT ss0."id" AS "id", ss0."x" AS "x", ss0."y" AS "y", ss0."z" AS "z", ss0."w" AS "w", ss0."meta" AS "meta" FROM "schema" AS ss0 WHERE (ss0."x" > ?)) } <> + ~s{AS s1 WHERE (s0."id" = s1."id")} assert cast_params == [100, 10] assert dump_params == [100, 10] @@ -1823,7 +1823,6 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do assert query == ~s{UPDATE "schema" SET "x" = ?, "y" = ? WHERE "id" = ? RETURNING "z"} - end test "delete" do @@ -1902,7 +1901,7 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do on_update: :update_all }, [null: false]}, {:add, :category_9, %Reference{table: :categories, on_delete: :restrict}, []}, - {:add, :category_10, %Reference{table: :categories, on_update: :restrict}, []}, + {:add, :category_10, %Reference{table: :categories, on_update: :restrict}, []} ]} assert execute_ddl(create) == [ @@ -2106,13 +2105,12 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do ]} assert_raise ArgumentError, - "unsupported type `{:a, :b, :c}`. " <> - "The type can either be an atom, a string or a tuple of the form " <> - "`{:map, t}` or `{:array, t}` where `t` itself follows the same conditions.", - fn -> execute_ddl(create) end + "unsupported type `{:a, :b, :c}`. " <> + "The type can either be an atom, a string or a tuple of the form " <> + "`{:map, t}` or `{:array, t}` where `t` itself follows the same conditions.", + fn -> execute_ddl(create) end end - test "drop table" do drop = {:drop, table(:posts)} assert execute_ddl(drop) == [~s|DROP TABLE "posts"|] @@ -2120,6 +2118,7 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do test "drop table with prefix" do drop = {:drop, table(:posts, prefix: :foo)} + assert_raise ArgumentError, "SQLite3 does not support table prefixes", fn -> execute_ddl(drop) end @@ -2151,6 +2150,7 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do alter = {:alter, table(:posts, prefix: :foo), [{:add, :author_id, %Reference{table: :author}, []}]} + assert_raise ArgumentError, "SQLite3 does not support table prefixes", fn -> execute_ddl(alter) end @@ -2339,6 +2339,7 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do test "rename table with prefix" do rename = {:rename, table(:posts, prefix: :foo), table(:new_posts, prefix: :foo)} + assert_raise ArgumentError, "SQLite3 does not support table prefixes", fn -> execute_ddl(rename) end