Skip to content

Implement Structure.dump_cmd/3 #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 24 additions & 24 deletions integration_test/json_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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

Expand Down
8 changes: 7 additions & 1 deletion integration_test/test_helper.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
]
)
11 changes: 9 additions & 2 deletions lib/ecto/adapters/sqlite3.ex
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
8 changes: 4 additions & 4 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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]},
Expand All @@ -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

Expand Down
10 changes: 5 additions & 5 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"},
Expand All @@ -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"},
Expand Down
4 changes: 3 additions & 1 deletion test/ecto/adapters/sqlite3/connection_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
18 changes: 18 additions & 0 deletions test/ecto/adapters/sqlite3_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -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