Skip to content
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

Support DDL transactions #123

Merged
merged 3 commits into from
Sep 5, 2023
Merged
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
126 changes: 126 additions & 0 deletions integration_test/migrations_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
defmodule Ecto.Integration.MigrationsTest do
use ExUnit.Case, async: true

alias Ecto.Integration.PoolRepo
import ExUnit.CaptureLog

@moduletag :capture_log
@base_migration 3_000_000

defmodule NormalMigration do
use Ecto.Migration

def change do
create_if_not_exists table(:log_mode_table)

alter table(:log_mode_table) do
add :name, :text
end
end
end

defmodule RollbackMigration do
use Ecto.Migration

def change do
create_if_not_exists table(:log_mode_table)

alter table(:log_mode_table) do
remove :not_exists, :text
end
end
end

describe "Migrator" do
@create_table_sql ~s(CREATE TABLE IF NOT EXISTS "log_mode_table")
@create_table_log "create table if not exists log_mode_table"
@add_column_sql ~S(ALTER TABLE "log_mode_table" ADD COLUMN "name" TEXT)
@alter_table_log "alter table log_mode_table"
@drop_column_sql ~S(ALTER TABLE "log_mode_table" DROP COLUMN "name")
@drop_table_sql ~s(DROP TABLE IF EXISTS "log_mode_table")
@drop_table_log "drop table if exists log_mode_table"
@version_insert ~s(INSERT INTO "schema_migrations")
@version_delete ~s(DELETE FROM "schema_migrations")

test "logs transaction commands" do
num = @base_migration + System.unique_integer([:positive])
up_log =
capture_log(fn ->
Ecto.Migrator.up(PoolRepo, num, NormalMigration, log_migrator_sql: :info, log_migrations_sql: :info, log: :info)
end)

assert up_log =~ "begin []"
assert up_log =~ @create_table_sql
assert up_log =~ @create_table_log
assert up_log =~ @add_column_sql
assert up_log =~ @alter_table_log
assert up_log =~ @version_insert
assert up_log =~ "commit []"

# two columns in the table
assert %{num_rows: 2} = PoolRepo.query!("PRAGMA table_info(log_mode_table)", [])

down_log =
capture_log(fn ->
Ecto.Migrator.down(PoolRepo, num, NormalMigration, log_migrator_sql: :info, log_migrations_sql: :info, log: :info)
end)

assert down_log =~ "begin []"
assert down_log =~ @drop_column_sql
assert down_log =~ @drop_table_sql
assert down_log =~ @drop_table_log
assert down_log =~ @version_delete
assert down_log =~ "commit []"
end

test "does not log sql when log is default" do
num = @base_migration + System.unique_integer([:positive])
up_log =
capture_log(fn ->
Ecto.Migrator.up(PoolRepo, num, NormalMigration, log: :info)
end)

refute up_log =~ "begin []"
refute up_log =~ @create_table_sql
assert up_log =~ @create_table_log
refute up_log =~ @add_column_sql
assert up_log =~ @alter_table_log
refute up_log =~ @version_insert
refute up_log =~ "commit []"

down_log =
capture_log(fn ->
Ecto.Migrator.down(PoolRepo, num, NormalMigration, log: :info)
end)

refute down_log =~ "begin []"
refute down_log =~ @drop_column_sql
refute down_log =~ @drop_table_sql
assert down_log =~ @drop_table_log
refute down_log =~ @version_delete
refute down_log =~ "commit []"
end

test "rolling back undoes previous migrations" do
num = @base_migration + System.unique_integer([:positive])
up_log =
capture_log(fn ->
try do
Ecto.Migrator.up(PoolRepo, num, RollbackMigration, log_migrator_sql: :info, log_migrations_sql: :info, log: :info)
rescue
_ -> :ok
end
end)

assert up_log =~ "begin []"
assert up_log =~ @create_table_sql
assert up_log =~ @create_table_log
assert up_log =~ "rollback []"
refute up_log =~ @version_insert
refute up_log =~ "commit []"

# table was not created due to rollback
assert %{num_rows: 0} = PoolRepo.query!("PRAGMA table_info(log_mode_table)", [])
end
end
end
2 changes: 1 addition & 1 deletion lib/ecto/adapters/sqlite3.ex
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ defmodule Ecto.Adapters.SQLite3 do
end

@impl Ecto.Adapter.Migration
def supports_ddl_transaction?, do: false
def supports_ddl_transaction?, do: true

@impl Ecto.Adapter.Migration
def lock_for_migrations(_meta, _options, fun) do
Expand Down
Loading