-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
test_repo.exs
122 lines (91 loc) · 3.27 KB
/
test_repo.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
defmodule Ecto.TestAdapter do
@behaviour Ecto.Adapter
alias Ecto.Migration.SchemaMigration
defmacro __before_compile__(_opts), do: :ok
def application, do: :ecto
def child_spec(_repo, opts) do
:ecto = opts[:otp_app]
"user" = opts[:username]
"pass" = opts[:password]
"hello" = opts[:database]
"local" = opts[:hostname]
Supervisor.Spec.worker(Task, [fn -> :timer.sleep(:infinity) end])
end
## Types
def loaders(:binary_id, type), do: [Ecto.UUID, type]
def loaders(_primitive, type), do: [type]
def dumpers(:binary_id, type), do: [type, Ecto.UUID]
def dumpers(_primitive, type), do: [type]
def autogenerate(:id), do: nil
def autogenerate(:embed_id), do: Ecto.UUID.autogenerate
def autogenerate(:binary_id), do: Ecto.UUID.autogenerate
## Queryable
def prepare(operation, query), do: {:nocache, {operation, query}}
def execute(_repo, _, {:nocache, {:all, %{from: {_, SchemaMigration}}}}, _, _, _) do
{length(migrated_versions()),
Enum.map(migrated_versions(), &List.wrap/1)}
end
def execute(_repo, _, {:nocache, {:all, _}}, _, _, _) do
{1, [[1]]}
end
def execute(_repo, _meta, {:nocache, {:delete_all, %{from: {_, SchemaMigration}}}}, [version], _, _) do
Process.put(:migrated_versions, List.delete(migrated_versions(), version))
{1, nil}
end
def execute(_repo, _meta, {:nocache, {op, %{from: {source, _}}}}, _params, _preprocess, _opts) do
send self, {op, source}
{1, nil}
end
## Schema
def insert_all(_repo, %{source: {_, source}}, _header, rows, _returning, _opts) do
send self(), {:insert_all, source, rows}
{1, nil}
end
def insert(_repo, %{source: {nil, "schema_migrations"}}, val, _, _) do
version = Keyword.fetch!(val, :version)
Process.put(:migrated_versions, [version|migrated_versions()])
{:ok, [version: 1]}
end
def insert(_repo, %{context: nil}, _fields, return, _opts),
do: send(self, :insert) && {:ok, Enum.zip(return, 1..length(return))}
def insert(_repo, %{context: {:invalid, _}=res}, _fields, _return, _opts),
do: res
# Notice the list of changes is never empty.
def update(_repo, %{context: nil}, [_|_], _filters, return, _opts),
do: send(self, :update) && {:ok, Enum.zip(return, 1..length(return))}
def update(_repo, %{context: {:invalid, _}=res}, [_|_], _filters, _return, _opts),
do: res
def delete(_repo, _model_meta, _filter, _opts),
do: send(self, :delete) && {:ok, []}
## Transactions
def transaction(_repo, _opts, fun) do
# Makes transactions "trackable" in tests
send self, {:transaction, fun}
try do
{:ok, fun.()}
catch
:throw, {:ecto_rollback, value} ->
{:error, value}
end
end
def rollback(_repo, value) do
send self, {:rollback, value}
throw {:ecto_rollback, value}
end
## Migrations
def supports_ddl_transaction? do
Process.get(:supports_ddl_transaction?) || false
end
def execute_ddl(_repo, command, _) do
Process.put(:last_command, command)
:ok
end
defp migrated_versions do
Process.get(:migrated_versions) || []
end
end
Application.put_env(:ecto, Ecto.TestRepo, [user: "invalid"])
defmodule Ecto.TestRepo do
use Ecto.Repo, otp_app: :ecto, adapter: Ecto.TestAdapter
end
Ecto.TestRepo.start_link(url: "ecto://user:pass@local/hello")