2017-05-13 03:01:43 +08:00
|
|
|
require 'rails_helper'
|
2018-03-20 15:20:50 +08:00
|
|
|
require_dependency 'migration/table_dropper'
|
2017-05-13 03:01:43 +08:00
|
|
|
|
2018-03-20 15:20:50 +08:00
|
|
|
describe Migration::TableDropper do
|
2017-05-13 03:01:43 +08:00
|
|
|
|
|
|
|
def table_exists?(table_name)
|
2018-03-21 18:31:05 +08:00
|
|
|
sql = <<~SQL
|
|
|
|
SELECT 1
|
|
|
|
FROM INFORMATION_SCHEMA.TABLES
|
|
|
|
WHERE table_schema = 'public' AND
|
|
|
|
table_name = '#{table_name}'
|
2017-05-13 03:01:43 +08:00
|
|
|
SQL
|
|
|
|
|
|
|
|
ActiveRecord::Base.exec_sql(sql).to_a.length > 0
|
|
|
|
end
|
|
|
|
|
2018-03-26 22:51:27 +08:00
|
|
|
def update_first_migration_date(created_at)
|
|
|
|
ActiveRecord::Base.exec_sql(<<~SQL, created_at: created_at)
|
|
|
|
UPDATE schema_migration_details
|
|
|
|
SET created_at = :created_at
|
|
|
|
WHERE id = (SELECT MIN(id)
|
|
|
|
FROM schema_migration_details)
|
|
|
|
SQL
|
|
|
|
end
|
|
|
|
|
|
|
|
def create_new_table
|
|
|
|
ActiveRecord::Base.exec_sql "CREATE TABLE table_with_new_name (topic_id INTEGER)"
|
|
|
|
end
|
|
|
|
|
2018-03-21 18:31:05 +08:00
|
|
|
let(:migration_name) do
|
|
|
|
ActiveRecord::Base
|
2018-03-26 22:51:27 +08:00
|
|
|
.exec_sql("SELECT name FROM schema_migration_details ORDER BY id DESC LIMIT 1")
|
2018-03-21 18:31:05 +08:00
|
|
|
.getvalue(0, 0)
|
|
|
|
end
|
2017-05-13 03:01:43 +08:00
|
|
|
|
2018-03-21 18:31:05 +08:00
|
|
|
before do
|
|
|
|
ActiveRecord::Base.exec_sql "CREATE TABLE table_with_old_name (topic_id INTEGER)"
|
2017-05-13 03:01:43 +08:00
|
|
|
|
2018-03-26 22:51:27 +08:00
|
|
|
ActiveRecord::Base.exec_sql(<<~SQL, name: migration_name, created_at: 15.minutes.ago)
|
|
|
|
UPDATE schema_migration_details
|
|
|
|
SET created_at = :created_at
|
|
|
|
WHERE name = :name
|
|
|
|
SQL
|
2018-03-21 18:31:05 +08:00
|
|
|
end
|
2017-05-13 03:01:43 +08:00
|
|
|
|
2018-03-26 22:51:27 +08:00
|
|
|
context "first migration was a long time ago" do
|
|
|
|
before do
|
|
|
|
update_first_migration_date(2.years.ago)
|
|
|
|
end
|
|
|
|
|
|
|
|
describe ".delayed_rename" do
|
|
|
|
it "can drop a table after correct delay and when new table exists" do
|
|
|
|
dropped_proc_called = false
|
|
|
|
|
|
|
|
described_class.delayed_rename(
|
|
|
|
old_name: 'table_with_old_name',
|
|
|
|
new_name: 'table_with_new_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 20.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(true)
|
|
|
|
expect(dropped_proc_called).to eq(false)
|
|
|
|
|
|
|
|
described_class.delayed_rename(
|
|
|
|
old_name: 'table_with_old_name',
|
|
|
|
new_name: 'table_with_new_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 10.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(true)
|
|
|
|
expect(dropped_proc_called).to eq(false)
|
|
|
|
|
|
|
|
create_new_table
|
|
|
|
|
|
|
|
described_class.delayed_rename(
|
|
|
|
old_name: 'table_with_old_name',
|
|
|
|
new_name: 'table_with_new_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 10.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(false)
|
|
|
|
expect(dropped_proc_called).to eq(true)
|
2018-03-26 23:05:18 +08:00
|
|
|
|
|
|
|
dropped_proc_called = false
|
|
|
|
|
|
|
|
described_class.delayed_rename(
|
|
|
|
old_name: 'table_with_old_name',
|
|
|
|
new_name: 'table_with_new_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 10.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
# it should call "on_drop" only when there is a table to drop
|
|
|
|
expect(dropped_proc_called).to eq(false)
|
2018-03-26 22:51:27 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe ".delayed_drop" do
|
|
|
|
it "can drop a table after correct delay" do
|
|
|
|
dropped_proc_called = false
|
|
|
|
|
|
|
|
described_class.delayed_drop(
|
|
|
|
table_name: 'table_with_old_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 20.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(true)
|
|
|
|
expect(dropped_proc_called).to eq(false)
|
|
|
|
|
|
|
|
described_class.delayed_drop(
|
|
|
|
table_name: 'table_with_old_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 10.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(false)
|
|
|
|
expect(dropped_proc_called).to eq(true)
|
2018-03-26 23:05:18 +08:00
|
|
|
|
|
|
|
dropped_proc_called = false
|
|
|
|
|
|
|
|
described_class.delayed_drop(
|
|
|
|
table_name: 'table_with_old_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 10.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
# it should call "on_drop" only when there is a table to drop
|
|
|
|
expect(dropped_proc_called).to eq(false)
|
2018-03-26 22:51:27 +08:00
|
|
|
end
|
2018-03-21 18:31:05 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2018-03-26 22:51:27 +08:00
|
|
|
context "first migration was a less than 10 minutes ago" do
|
|
|
|
describe ".delayed_rename" do
|
|
|
|
it "can drop a table after correct delay and when new table exists" do
|
|
|
|
dropped_proc_called = false
|
|
|
|
update_first_migration_date(11.minutes.ago)
|
|
|
|
create_new_table
|
|
|
|
|
|
|
|
described_class.delayed_rename(
|
|
|
|
old_name: 'table_with_old_name',
|
|
|
|
new_name: 'table_with_new_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 30.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(true)
|
|
|
|
expect(dropped_proc_called).to eq(false)
|
|
|
|
|
|
|
|
update_first_migration_date(9.minutes.ago)
|
|
|
|
|
|
|
|
described_class.delayed_rename(
|
|
|
|
old_name: 'table_with_old_name',
|
|
|
|
new_name: 'table_with_new_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 30.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(false)
|
|
|
|
expect(dropped_proc_called).to eq(true)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
describe ".delayed_drop" do
|
|
|
|
it "immediately drops the table" do
|
|
|
|
dropped_proc_called = false
|
|
|
|
update_first_migration_date(11.minutes.ago)
|
|
|
|
|
|
|
|
described_class.delayed_drop(
|
|
|
|
table_name: 'table_with_old_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 30.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(true)
|
|
|
|
expect(dropped_proc_called).to eq(false)
|
|
|
|
|
|
|
|
update_first_migration_date(9.minutes.ago)
|
|
|
|
|
|
|
|
described_class.delayed_drop(
|
|
|
|
table_name: 'table_with_old_name',
|
|
|
|
after_migration: migration_name,
|
|
|
|
delay: 30.minutes,
|
|
|
|
on_drop: ->() { dropped_proc_called = true }
|
|
|
|
)
|
|
|
|
|
|
|
|
expect(table_exists?('table_with_old_name')).to eq(false)
|
|
|
|
expect(dropped_proc_called).to eq(true)
|
|
|
|
end
|
2017-05-13 03:01:43 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|