Skip to content

Commit 5a29789

Browse files
authored
Add Ecto.Migration.remove_if_exists/1 (#624)
1 parent b1f7386 commit 5a29789

File tree

9 files changed

+43
-9
lines changed

9 files changed

+43
-9
lines changed

.formatter.exs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ locals_without_parens = [
1919
remove: 1,
2020
remove: 2,
2121
remove: 3,
22+
remove_if_exists: 1,
2223
remove_if_exists: 2,
2324
rename: 2,
2425
rename: 3,

lib/ecto/adapter/migration.ex

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ defmodule Ecto.Adapter.Migration do
3939
| {:remove, field :: atom, type :: Ecto.Type.t() | Reference.t() | binary(),
4040
Keyword.t()}
4141
| {:remove, field :: atom}
42-
| {:remove_if_exists, type :: Ecto.Type.t() | Reference.t() | binary()}
42+
| {:remove_if_exists, field :: atom, type :: Ecto.Type.t() | Reference.t() | binary()}
43+
| {:remove_if_exists, field :: atom}
4344

4445
@typedoc """
4546
A struct that represents a table or index in a database schema.

lib/ecto/adapters/myxql/connection.ex

+4-1
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,10 @@ if Code.ensure_loaded?(MyXQL) do
12391239
[drop_constraint_if_exists_expr(ref, table, name), "DROP IF EXISTS ", quote_name(name)]
12401240
end
12411241

1242-
defp column_change(_table, {:remove_if_exists, name, _type}),
1242+
defp column_change(table, {:remove_if_exists, name, _type}),
1243+
do: column_change(table, {:remove_if_exists, name})
1244+
1245+
defp column_change(_table, {:remove_if_exists, name}),
12431246
do: ["DROP IF EXISTS ", quote_name(name)]
12441247

12451248
defp column_options(opts) do

lib/ecto/adapters/postgres/connection.ex

+4-1
Original file line numberDiff line numberDiff line change
@@ -1588,7 +1588,10 @@ if Code.ensure_loaded?(Postgrex) do
15881588
]
15891589
end
15901590

1591-
defp column_change(_table, {:remove_if_exists, name, _type}),
1591+
defp column_change(table, {:remove_if_exists, name, _type}),
1592+
do: column_change(table, {:remove_if_exists, name})
1593+
1594+
defp column_change(_table, {:remove_if_exists, name}),
15921595
do: ["DROP COLUMN IF EXISTS ", quote_name(name)]
15931596

15941597
defp modify_null(name, opts) do

lib/ecto/adapters/tds/connection.ex

+4-1
Original file line numberDiff line numberDiff line change
@@ -1470,10 +1470,13 @@ if Code.ensure_loaded?(Tds) do
14701470
defp column_change(statement_prefix, _table, {:remove, name, _type, _opts}),
14711471
do: [statement_prefix, "DROP COLUMN ", quote_name(name)]
14721472

1473+
defp column_change(statement_prefix, table, {:remove_if_exists, column_name, _}),
1474+
do: column_change(statement_prefix, table, {:remove_if_exists, column_name})
1475+
14731476
defp column_change(
14741477
statement_prefix,
14751478
%{name: table, prefix: prefix},
1476-
{:remove_if_exists, column_name, _}
1479+
{:remove_if_exists, column_name}
14771480
) do
14781481
[
14791482
[

lib/ecto/migration.ex

+21-4
Original file line numberDiff line numberDiff line change
@@ -1358,15 +1358,32 @@ defmodule Ecto.Migration do
13581358
end
13591359

13601360
@doc """
1361-
Removes a column only if the column exists when altering the constraint if the reference type is passed
1362-
once it only has the constraint name on reference structure.
1361+
Removes a column if the column exists.
13631362
1364-
This command is not reversible as Ecto does not know about column existence before the removal attempt.
1363+
This command is not reversible as Ecto does not know whether or not the column existed before the removal attempt.
13651364
13661365
## Examples
13671366
13681367
alter table("posts") do
1369-
remove_if_exists :title, :string
1368+
remove_if_exists :title
1369+
end
1370+
1371+
"""
1372+
def remove_if_exists(column) when is_atom(column) do
1373+
Runner.subcommand({:remove_if_exists, column})
1374+
end
1375+
1376+
@doc """
1377+
Removes a column if the column exists.
1378+
1379+
If the type is a reference, removes the foreign key constraint for the reference first, if it exists.
1380+
1381+
This command is not reversible as Ecto does not know whether or not the column existed before the removal attempt.
1382+
1383+
## Examples
1384+
1385+
alter table("posts") do
1386+
remove_if_exists :author_id, references(:authors)
13701387
end
13711388
13721389
"""

test/ecto/adapters/myxql_test.exs

+2
Original file line numberDiff line numberDiff line change
@@ -1987,6 +1987,7 @@ defmodule Ecto.Adapters.MyXQLTest do
19871987
{:remove, :body, :text, []},
19881988
{:remove, :space_id, %Reference{table: :author}, []},
19891989
{:remove_if_exists, :body, :text},
1990+
{:remove_if_exists, :body},
19901991
{:remove_if_exists, :space_id, %Reference{table: :author}}
19911992
]}
19921993

@@ -2015,6 +2016,7 @@ defmodule Ecto.Adapters.MyXQLTest do
20152016
DROP FOREIGN KEY `posts_space_id_fkey`,
20162017
DROP `space_id`,
20172018
DROP IF EXISTS `body`,
2019+
DROP IF EXISTS `body`,
20182020
DROP FOREIGN KEY IF EXISTS `posts_space_id_fkey`,
20192021
DROP IF EXISTS `space_id`
20202022
"""

test/ecto/adapters/postgres_test.exs

+2
Original file line numberDiff line numberDiff line change
@@ -2503,6 +2503,7 @@ defmodule Ecto.Adapters.PostgresTest do
25032503
{:remove, :body, :text, []},
25042504
{:remove, :space_id, %Reference{table: :author}, []},
25052505
{:remove_if_exists, :body, :text},
2506+
{:remove_if_exists, :body},
25062507
{:remove_if_exists, :space_id, %Reference{table: :author}}
25072508
]}
25082509

@@ -2541,6 +2542,7 @@ defmodule Ecto.Adapters.PostgresTest do
25412542
DROP CONSTRAINT "posts_space_id_fkey",
25422543
DROP COLUMN "space_id",
25432544
DROP COLUMN IF EXISTS "body",
2545+
DROP COLUMN IF EXISTS "body",
25442546
DROP CONSTRAINT IF EXISTS "posts_space_id_fkey",
25452547
DROP COLUMN IF EXISTS "space_id"
25462548
"""

test/ecto/migration_test.exs

+3-1
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,7 @@ defmodule Ecto.MigrationTest do
469469
remove :views
470470
remove :status, :string
471471
remove_if_exists :status, :string
472+
remove_if_exists :status
472473
end
473474

474475
flush()
@@ -481,7 +482,8 @@ defmodule Ecto.MigrationTest do
481482
{:modify, :title, :text, []},
482483
{:remove, :views},
483484
{:remove, :status, :string, []},
484-
{:remove_if_exists, :status, :string}
485+
{:remove_if_exists, :status, :string},
486+
{:remove_if_exists, :status}
485487
]}
486488
end
487489

0 commit comments

Comments
 (0)