diff --git a/integration_test/json_test.exs b/integration_test/json_test.exs index e03fc01..a8ef7e9 100644 --- a/integration_test/json_test.exs +++ b/integration_test/json_test.exs @@ -8,7 +8,7 @@ defmodule Ecto.Integration.JsonTest do test "json_extract_path with primitive values" do order = %Order{ - meta: %{ + metadata: %{ :id => 123, :time => ~T[09:00:00], "code" => "good", @@ -21,67 +21,67 @@ defmodule Ecto.Integration.JsonTest do order = TestRepo.insert!(order) - assert TestRepo.one(from(o in Order, select: o.meta["id"])) == 123 - assert TestRepo.one(from(o in Order, select: o.meta["bad"])) == nil - assert TestRepo.one(from(o in Order, select: o.meta["bad"]["bad"])) == nil + assert TestRepo.one(from(o in Order, select: o.metadata["id"])) == 123 + assert TestRepo.one(from(o in Order, select: o.metadata["bad"])) == nil + assert TestRepo.one(from(o in Order, select: o.metadata["bad"]["bad"])) == nil field = "id" - assert TestRepo.one(from(o in Order, select: o.meta[^field])) == 123 - assert TestRepo.one(from(o in Order, select: o.meta["time"])) == "09:00:00" - assert TestRepo.one(from(o in Order, select: o.meta["'single quoted'"])) == "bar" - assert TestRepo.one(from(o in Order, select: o.meta["';"])) == nil - assert TestRepo.one(from(o in Order, select: o.meta["\"double quoted\""])) == "baz" - assert TestRepo.one(from(o in Order, select: o.meta["enabled"])) == 1 - assert TestRepo.one(from(o in Order, select: o.meta["extra"][0]["enabled"])) == 0 + assert TestRepo.one(from(o in Order, select: o.metadata[^field])) == 123 + assert TestRepo.one(from(o in Order, select: o.metadata["time"])) == "09:00:00" + assert TestRepo.one(from(o in Order, select: o.metadata["'single quoted'"])) == "bar" + assert TestRepo.one(from(o in Order, select: o.metadata["';"])) == nil + assert TestRepo.one(from(o in Order, select: o.metadata["\"double quoted\""])) == "baz" + assert TestRepo.one(from(o in Order, select: o.metadata["enabled"])) == 1 + assert TestRepo.one(from(o in Order, select: o.metadata["extra"][0]["enabled"])) == 0 # where - assert TestRepo.one(from(o in Order, where: o.meta["id"] == 123, select: o.id)) == + assert TestRepo.one(from(o in Order, where: o.metadata["id"] == 123, select: o.id)) == order.id - assert TestRepo.one(from(o in Order, where: o.meta["id"] == 456, select: o.id)) == + assert TestRepo.one(from(o in Order, where: o.metadata["id"] == 456, select: o.id)) == nil - assert TestRepo.one(from(o in Order, where: o.meta["code"] == "good", select: o.id)) == + assert TestRepo.one(from(o in Order, where: o.metadata["code"] == "good", select: o.id)) == order.id - assert TestRepo.one(from(o in Order, where: o.meta["code"] == "bad", select: o.id)) == + assert TestRepo.one(from(o in Order, where: o.metadata["code"] == "bad", select: o.id)) == nil assert TestRepo.one( - from(o in Order, where: o.meta["enabled"] == true, select: o.id) + from(o in Order, where: o.metadata["enabled"] == true, select: o.id) ) == order.id assert TestRepo.one( from(o in Order, - where: o.meta["extra"][0]["enabled"] == false, + where: o.metadata["extra"][0]["enabled"] == false, select: o.id ) ) == order.id end test "json_extract_path with arrays and objects" do - order = %Order{meta: %{tags: [%{name: "red"}, %{name: "green"}]}} + order = %Order{metadata: %{tags: [%{name: "red"}, %{name: "green"}]}} order = TestRepo.insert!(order) - assert TestRepo.one(from(o in Order, select: o.meta["tags"][0]["name"])) == "red" - assert TestRepo.one(from(o in Order, select: o.meta["tags"][99]["name"])) == nil + assert TestRepo.one(from(o in Order, select: o.metadata["tags"][0]["name"])) == "red" + assert TestRepo.one(from(o in Order, select: o.metadata["tags"][99]["name"])) == nil index = 1 - assert TestRepo.one(from(o in Order, select: o.meta["tags"][^index]["name"])) == + assert TestRepo.one(from(o in Order, select: o.metadata["tags"][^index]["name"])) == "green" # where assert TestRepo.one( - from(o in Order, where: o.meta["tags"][0]["name"] == "red", select: o.id) + from(o in Order, where: o.metadata["tags"][0]["name"] == "red", select: o.id) ) == order.id assert TestRepo.one( - from(o in Order, where: o.meta["tags"][0]["name"] == "blue", select: o.id) + from(o in Order, where: o.metadata["tags"][0]["name"] == "blue", select: o.id) ) == nil assert TestRepo.one( - from(o in Order, where: o.meta["tags"][99]["name"] == "red", select: o.id) + from(o in Order, where: o.metadata["tags"][99]["name"] == "red", select: o.id) ) == nil end diff --git a/integration_test/test_helper.exs b/integration_test/test_helper.exs index ce93da3..ca3dbf0 100644 --- a/integration_test/test_helper.exs +++ b/integration_test/test_helper.exs @@ -114,6 +114,12 @@ ExUnit.start( # SQLite3 does not support placeholders :placeholders, # SQLite3 stores booleans as integers, causing Ecto's json_extract_path tests to fail - :json_extract_path + :json_extract_path, + + # We don't support selected_as + :selected_as_with_group_by, + :selected_as_with_order_by, + :selected_as_with_order_by_expression, + :selected_as_with_having, ] ) diff --git a/lib/ecto/adapters/sqlite3.ex b/lib/ecto/adapters/sqlite3.ex index fe5d51e..3bcd698 100644 --- a/lib/ecto/adapters/sqlite3.ex +++ b/lib/ecto/adapters/sqlite3.ex @@ -247,6 +247,11 @@ defmodule Ecto.Adapters.SQLite3 do end end + @impl Ecto.Adapter.Structure + def dump_cmd(args, opts \\ [], config) when is_list(config) and is_list(args) do + run_with_cmd("sqlite3", [config[:database] | args], opts) + end + @impl Ecto.Adapter.Schema def autogenerate(:id), do: nil def autogenerate(:embed_id), do: Ecto.UUID.generate() @@ -487,12 +492,14 @@ defmodule Ecto.Adapters.SQLite3 do end end - defp run_with_cmd(cmd, args) do + defp run_with_cmd(cmd, args, cmd_opts \\ []) do unless System.find_executable(cmd) do raise "could not find executable `#{cmd}` in path, " <> "please guarantee it is available before running ecto commands" end - System.cmd(cmd, args, stderr_to_stdout: true) + cmd_opts = Keyword.put_new(cmd_opts, :stderr_to_stdout, true) + + System.cmd(cmd, args, cmd_opts) end end diff --git a/mix.exs b/mix.exs index 0fdaf5e..4b9326e 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.7"}, - {:ecto, "~> 3.7"}, + {:ecto_sql, "~> 3.9"}, + {:ecto, "~> 3.9"}, {:exqlite, "~> 0.9"}, {:ex_doc, "~> 0.27", only: [:dev], runtime: false}, {:jason, ">= 0.0.0", only: [:dev, :test, :docs]}, @@ -45,8 +45,8 @@ defmodule EctoSQLite3.MixProject do # Benchmarks {:benchee, "~> 1.0", only: :dev}, {:benchee_markdown, "~> 0.2", only: :dev}, - {:postgrex, "~> 0.15.0", only: :dev}, - {:myxql, "~> 0.5.0", only: :dev} + {:postgrex, "~> 0.15", only: :dev}, + {:myxql, "~> 0.6.0", only: :dev} ] end diff --git a/mix.lock b/mix.lock index e7779c5..175809b 100644 --- a/mix.lock +++ b/mix.lock @@ -4,12 +4,12 @@ "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.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"}, + "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"}, "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.28", "0bf6546eb7cd6185ae086cbc5d20cd6dbb4b428aad14c02c49f7b554484b4586", [:mix], [], "hexpm", "501cef12286a3231dc80c81352a9453decf9586977f917a96e619293132743fb"}, - "ecto": {:hex, :ecto, "3.7.2", "44c034f88e1980754983cc4400585970b4206841f6f3780967a65a9150ef09a8", [: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", "a600da5772d1c31abbf06f3e4a1ffb150e74ed3e2aa92ff3cee95901657a874e"}, - "ecto_sql": {:hex, :ecto_sql, "3.7.2", "55c60aa3a06168912abf145c6df38b0295c34118c3624cf7a6977cd6ce043081", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0 or ~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 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", "3c218ea62f305dcaef0b915fb56583195e7b91c91dcfb006ba1f669bfacbff2a"}, + "ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [: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", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"}, + "ecto_sql": {:hex, :ecto_sql, "3.9.1", "9bd5894eecc53d5b39d0c95180d4466aff00e10679e13a5cfa725f6f85c03c22", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.0", [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", "5fd470a4fff2e829bbf9dcceb7f3f9f6d1e49b4241e802f614de6b8b67c51118"}, "elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"}, "ex_doc": {:hex, :ex_doc, "0.28.5", "3e52a6d2130ce74d096859e477b97080c156d0926701c13870a4e1f752363279", [: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", "d2c4b07133113e9aa3e9ba27efb9088ba900e9e51caa383919676afdf09ab181"}, "exqlite": {:hex, :exqlite, "0.11.6", "a8210b2adfa49c7155a54014bd0c2a51b8bb7bbabb8fd5fa70a5497531176991", [: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", "9262f7570ac326b34ec0e03e13322f54690eff06bbbe34fae5180c28bc5916dc"}, @@ -18,9 +18,9 @@ "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, "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.5.2", "6c054789112d4d1f626462c771b3aa74bb0fe56012e5a2ef04e629ea96a9088d", [: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]}], "hexpm", "7bf09e80dde8887cfcb314604b0f39463da91cac6f12af2c4f1553411fa6ee8d"}, + "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.15.13", "7794e697481799aee8982688c261901de493eb64451feee6ea58207d7266d54a", [:mix], [{:connection, "~> 1.0", [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]}], "hexpm", "3ffb76e1a97cfefe5c6a95632a27ffb67f28871c9741fb585f9d1c3cd2af70f1"}, + "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"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, "telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"}, "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 f8846bf..4745ace 100644 --- a/test/ecto/adapters/sqlite3/connection_test.exs +++ b/test/ecto/adapters/sqlite3/connection_test.exs @@ -70,7 +70,9 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do end defp plan(query, operation \\ :all) do - {query, _params} = Ecto.Adapter.Queryable.plan_query(operation, SQLite3, query) + {query, _cast_params, _dump_params} = + Ecto.Adapter.Queryable.plan_query(operation, SQLite3, query) + query end diff --git a/test/ecto/adapters/sqlite3_test.exs b/test/ecto/adapters/sqlite3_test.exs index d2d8244..6144f7f 100644 --- a/test/ecto/adapters/sqlite3_test.exs +++ b/test/ecto/adapters/sqlite3_test.exs @@ -82,6 +82,24 @@ defmodule Ecto.Adapters.SQLite3Test do end end + describe "dump_cmd/3" do + test "runs command" do + opts = [database: Temp.path!()] + + assert SQLite3.storage_up(opts) == :ok + + assert {_out, 0} = + SQLite3.dump_cmd( + ["CREATE TABLE test (id INTEGER PRIMARY KEY)"], + [], + opts + ) + + assert {"CREATE TABLE test (id INTEGER PRIMARY KEY);\n", 0} = + SQLite3.dump_cmd([".schema"], [], opts) + end + end + defp string_uuid?(uuid), do: Regex.match?(@uuid_regex, uuid) defp binary_uuid?(uuid), do: bit_size(uuid) == 128 end