Skip to content

Commit a94866b

Browse files
authored
Implement Structure.dump_cmd/3 and query_many/4 (#93)
* Implement Structure.dump_cmd/3 * Implement query_many/4 to raise exception * Disable logging integration test Co-authored-by: Jonatan Männchen <[email protected]> @maennchen
1 parent 62dda12 commit a94866b

File tree

7 files changed

+67
-29
lines changed

7 files changed

+67
-29
lines changed

integration_test/all_test.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Code.require_file "#{ecto}/integration_test/cases/repo.exs", __DIR__
1111

1212
ecto_sql = Mix.Project.deps_paths()[:ecto_sql]
1313
# Code.require_file "#{ecto_sql}/integration_test/sql/lock.exs", __DIR__
14-
Code.require_file "#{ecto_sql}/integration_test/sql/logging.exs", __DIR__
14+
# Code.require_file "#{ecto_sql}/integration_test/sql/logging.exs", __DIR__
1515
Code.require_file "#{ecto_sql}/integration_test/sql/sandbox.exs", __DIR__
1616
Code.require_file "#{ecto_sql}/integration_test/sql/sql.exs", __DIR__
1717
Code.require_file "#{ecto_sql}/integration_test/sql/stream.exs", __DIR__

integration_test/json_test.exs

+24-24
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ defmodule Ecto.Integration.JsonTest do
88

99
test "json_extract_path with primitive values" do
1010
order = %Order{
11-
meta: %{
11+
metadata: %{
1212
:id => 123,
1313
:time => ~T[09:00:00],
1414
"code" => "good",
@@ -21,67 +21,67 @@ defmodule Ecto.Integration.JsonTest do
2121

2222
order = TestRepo.insert!(order)
2323

24-
assert TestRepo.one(from(o in Order, select: o.meta["id"])) == 123
25-
assert TestRepo.one(from(o in Order, select: o.meta["bad"])) == nil
26-
assert TestRepo.one(from(o in Order, select: o.meta["bad"]["bad"])) == nil
24+
assert TestRepo.one(from(o in Order, select: o.metadata["id"])) == 123
25+
assert TestRepo.one(from(o in Order, select: o.metadata["bad"])) == nil
26+
assert TestRepo.one(from(o in Order, select: o.metadata["bad"]["bad"])) == nil
2727

2828
field = "id"
29-
assert TestRepo.one(from(o in Order, select: o.meta[^field])) == 123
30-
assert TestRepo.one(from(o in Order, select: o.meta["time"])) == "09:00:00"
31-
assert TestRepo.one(from(o in Order, select: o.meta["'single quoted'"])) == "bar"
32-
assert TestRepo.one(from(o in Order, select: o.meta["';"])) == nil
33-
assert TestRepo.one(from(o in Order, select: o.meta["\"double quoted\""])) == "baz"
34-
assert TestRepo.one(from(o in Order, select: o.meta["enabled"])) == 1
35-
assert TestRepo.one(from(o in Order, select: o.meta["extra"][0]["enabled"])) == 0
29+
assert TestRepo.one(from(o in Order, select: o.metadata[^field])) == 123
30+
assert TestRepo.one(from(o in Order, select: o.metadata["time"])) == "09:00:00"
31+
assert TestRepo.one(from(o in Order, select: o.metadata["'single quoted'"])) == "bar"
32+
assert TestRepo.one(from(o in Order, select: o.metadata["';"])) == nil
33+
assert TestRepo.one(from(o in Order, select: o.metadata["\"double quoted\""])) == "baz"
34+
assert TestRepo.one(from(o in Order, select: o.metadata["enabled"])) == 1
35+
assert TestRepo.one(from(o in Order, select: o.metadata["extra"][0]["enabled"])) == 0
3636

3737
# where
38-
assert TestRepo.one(from(o in Order, where: o.meta["id"] == 123, select: o.id)) ==
38+
assert TestRepo.one(from(o in Order, where: o.metadata["id"] == 123, select: o.id)) ==
3939
order.id
4040

41-
assert TestRepo.one(from(o in Order, where: o.meta["id"] == 456, select: o.id)) ==
41+
assert TestRepo.one(from(o in Order, where: o.metadata["id"] == 456, select: o.id)) ==
4242
nil
4343

44-
assert TestRepo.one(from(o in Order, where: o.meta["code"] == "good", select: o.id)) ==
44+
assert TestRepo.one(from(o in Order, where: o.metadata["code"] == "good", select: o.id)) ==
4545
order.id
4646

47-
assert TestRepo.one(from(o in Order, where: o.meta["code"] == "bad", select: o.id)) ==
47+
assert TestRepo.one(from(o in Order, where: o.metadata["code"] == "bad", select: o.id)) ==
4848
nil
4949

5050
assert TestRepo.one(
51-
from(o in Order, where: o.meta["enabled"] == true, select: o.id)
51+
from(o in Order, where: o.metadata["enabled"] == true, select: o.id)
5252
) == order.id
5353

5454
assert TestRepo.one(
5555
from(o in Order,
56-
where: o.meta["extra"][0]["enabled"] == false,
56+
where: o.metadata["extra"][0]["enabled"] == false,
5757
select: o.id
5858
)
5959
) == order.id
6060
end
6161

6262
test "json_extract_path with arrays and objects" do
63-
order = %Order{meta: %{tags: [%{name: "red"}, %{name: "green"}]}}
63+
order = %Order{metadata: %{tags: [%{name: "red"}, %{name: "green"}]}}
6464
order = TestRepo.insert!(order)
6565

66-
assert TestRepo.one(from(o in Order, select: o.meta["tags"][0]["name"])) == "red"
67-
assert TestRepo.one(from(o in Order, select: o.meta["tags"][99]["name"])) == nil
66+
assert TestRepo.one(from(o in Order, select: o.metadata["tags"][0]["name"])) == "red"
67+
assert TestRepo.one(from(o in Order, select: o.metadata["tags"][99]["name"])) == nil
6868

6969
index = 1
7070

71-
assert TestRepo.one(from(o in Order, select: o.meta["tags"][^index]["name"])) ==
71+
assert TestRepo.one(from(o in Order, select: o.metadata["tags"][^index]["name"])) ==
7272
"green"
7373

7474
# where
7575
assert TestRepo.one(
76-
from(o in Order, where: o.meta["tags"][0]["name"] == "red", select: o.id)
76+
from(o in Order, where: o.metadata["tags"][0]["name"] == "red", select: o.id)
7777
) == order.id
7878

7979
assert TestRepo.one(
80-
from(o in Order, where: o.meta["tags"][0]["name"] == "blue", select: o.id)
80+
from(o in Order, where: o.metadata["tags"][0]["name"] == "blue", select: o.id)
8181
) == nil
8282

8383
assert TestRepo.one(
84-
from(o in Order, where: o.meta["tags"][99]["name"] == "red", select: o.id)
84+
from(o in Order, where: o.metadata["tags"][99]["name"] == "red", select: o.id)
8585
) == nil
8686
end
8787

integration_test/test_helper.exs

+7-1
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ ExUnit.start(
114114
# SQLite3 does not support placeholders
115115
:placeholders,
116116
# SQLite3 stores booleans as integers, causing Ecto's json_extract_path tests to fail
117-
:json_extract_path
117+
:json_extract_path,
118+
119+
# We don't support selected_as
120+
:selected_as_with_group_by,
121+
:selected_as_with_order_by,
122+
:selected_as_with_order_by_expression,
123+
:selected_as_with_having,
118124
]
119125
)

lib/ecto/adapters/sqlite3.ex

+9-2
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ defmodule Ecto.Adapters.SQLite3 do
247247
end
248248
end
249249

250+
@impl Ecto.Adapter.Structure
251+
def dump_cmd(args, opts \\ [], config) when is_list(config) and is_list(args) do
252+
run_with_cmd("sqlite3", [config[:database] | args], opts)
253+
end
254+
250255
@impl Ecto.Adapter.Schema
251256
def autogenerate(:id), do: nil
252257
def autogenerate(:embed_id), do: Ecto.UUID.generate()
@@ -487,12 +492,14 @@ defmodule Ecto.Adapters.SQLite3 do
487492
end
488493
end
489494

490-
defp run_with_cmd(cmd, args) do
495+
defp run_with_cmd(cmd, args, cmd_opts \\ []) do
491496
unless System.find_executable(cmd) do
492497
raise "could not find executable `#{cmd}` in path, " <>
493498
"please guarantee it is available before running ecto commands"
494499
end
495500

496-
System.cmd(cmd, args, stderr_to_stdout: true)
501+
cmd_opts = Keyword.put_new(cmd_opts, :stderr_to_stdout, true)
502+
503+
System.cmd(cmd, args, cmd_opts)
497504
end
498505
end

lib/ecto/adapters/sqlite3/connection.ex

+5
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ defmodule Ecto.Adapters.SQLite3.Connection do
9595
end
9696
end
9797

98+
@impl true
99+
def query_many(_conn, _sql, _params, _opts) do
100+
raise RuntimeError, "query_many is not supported in the SQLite3 adapter"
101+
end
102+
98103
@impl true
99104
def stream(conn, sql, params, options) do
100105
query = Exqlite.Query.build(statement: sql)

test/ecto/adapters/sqlite3/connection_test.exs

+3-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ defmodule Ecto.Adapters.SQLite3.ConnectionTest do
7070
end
7171

7272
defp plan(query, operation \\ :all) do
73-
{query, _params} = Ecto.Adapter.Queryable.plan_query(operation, SQLite3, query)
73+
{query, _cast_params, _dump_params} =
74+
Ecto.Adapter.Queryable.plan_query(operation, SQLite3, query)
75+
7476
query
7577
end
7678

test/ecto/adapters/sqlite3_test.exs

+18
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,24 @@ defmodule Ecto.Adapters.SQLite3Test do
8282
end
8383
end
8484

85+
describe "dump_cmd/3" do
86+
test "runs command" do
87+
opts = [database: Temp.path!()]
88+
89+
assert SQLite3.storage_up(opts) == :ok
90+
91+
assert {_out, 0} =
92+
SQLite3.dump_cmd(
93+
["CREATE TABLE test (id INTEGER PRIMARY KEY)"],
94+
[],
95+
opts
96+
)
97+
98+
assert {"CREATE TABLE test (id INTEGER PRIMARY KEY);\n", 0} =
99+
SQLite3.dump_cmd([".schema"], [], opts)
100+
end
101+
end
102+
85103
defp string_uuid?(uuid), do: Regex.match?(@uuid_regex, uuid)
86104
defp binary_uuid?(uuid), do: bit_size(uuid) == 128
87105
end

0 commit comments

Comments
 (0)