diff --git a/integration_test/migrations_test.exs b/integration_test/migrations_test.exs new file mode 100644 index 0000000..90d3c11 --- /dev/null +++ b/integration_test/migrations_test.exs @@ -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 diff --git a/lib/ecto/adapters/sqlite3.ex b/lib/ecto/adapters/sqlite3.ex index c6a3f9f..9365d36 100644 --- a/lib/ecto/adapters/sqlite3.ex +++ b/lib/ecto/adapters/sqlite3.ex @@ -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