Skip to content

Commit

Permalink
Introduce drop-table-only feature
Browse files Browse the repository at this point in the history
Basically, dropping tables are very dangerous operation. So
Ridgepole disables drop tables by default.

But of course we need to do drop sometimes.  In that case, I would
like to run only `drop tables` to avoid unexpected changes.
This PR implements the feature for that.
  • Loading branch information
y-yagi committed Apr 16, 2024
1 parent 37811c5 commit a524c99
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 6 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ Usage: ridgepole [options]
--dump-with-default-fk-name
--index-removed-drop-column
--drop-table
--drop-table-only
--mysql-change-table-options
--mysql-change-table-comment
--check-relation-type DEF_PK
Expand Down
1 change: 1 addition & 0 deletions bin/ridgepole
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ ARGV.options do |opt|
opt.on('', '--dump-with-default-fk-name') { options[:dump_with_default_fk_name] = true }
opt.on('', '--index-removed-drop-column') { options[:index_removed_drop_column] = true }
opt.on('', '--drop-table') { options[:force_drop_table] = true }
opt.on('', '--drop-table-only') { options[:drop_table_only] = true }
opt.on('', '--mysql-change-table-options') { options[:mysql_change_table_options] = true }
opt.on('', '--mysql-change-table-comment') { options[:mysql_change_table_comment] = true }
opt.on('', '--check-relation-type DEF_PK') { |v| options[:check_relation_type] = v }
Expand Down
14 changes: 8 additions & 6 deletions lib/ridgepole/diff.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,22 @@ def diff(from, to, options = {})
if (from_attrs = from.delete(table_name))
@logger.verbose_info("# #{table_name}")

unless (attrs_delta = diff_inspect(from_attrs, to_attrs)).empty?
@logger.verbose_info(attrs_delta)
end
unless @options[:drop_table_only]
unless (attrs_delta = diff_inspect(from_attrs, to_attrs)).empty?
@logger.verbose_info(attrs_delta)
end

scan_change(table_name, from_attrs, to_attrs, delta)
else
scan_change(table_name, from_attrs, to_attrs, delta)
end
elsif !@options[:drop_table_only]
delta[:add] ||= {}
delta[:add][table_name] = to_attrs
end
end

scan_relation_info(relation_info)

if !@options[:merge] && @options[:force_drop_table]
if !@options[:merge] && (@options[:force_drop_table] || @options[:drop_table_only])
from.each do |table_name, from_attrs|
next unless target?(table_name)

Expand Down
1 change: 1 addition & 0 deletions spec/mysql/cli/ridgepole_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def conn_spec_str(database)
--dump-with-default-fk-name
--index-removed-drop-column
--drop-table
--drop-table-only
--mysql-change-table-options
--mysql-change-table-comment
--check-relation-type DEF_PK
Expand Down
135 changes: 135 additions & 0 deletions spec/mysql/migrate/migrate_drop_table_only_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# frozen_string_literal: true

describe 'Ridgepole::Client#diff -> migrate' do
context 'when drop table only' do
let(:dsl) do
erbh(<<-ERB)
create_table "clubs", force: :cascade do |t|
t.string "name", default: "", null: false
t.index ["name"], name: "idx_name", unique: true
end
create_table "departments", primary_key: "dept_no", force: :cascade do |t|
t.string "dept_name", limit: 40, null: false
t.index ["dept_name"], name: "dept_name", unique: true
end
create_table "dept_emp", id: false, force: :cascade do |t|
t.integer "emp_no", null: false
t.string "dept_no", null: false
t.date "from_date", null: false
t.date "to_date", null: false
t.index ["dept_no"], name: "dept_no"
t.index ["emp_no"], name: "emp_no"
end
create_table "dept_manager", id: false, force: :cascade do |t|
t.string "dept_no", null: false
t.integer "emp_no", null: false
t.date "from_date", null: false
t.date "to_date", null: false
t.index ["dept_no"], name: "dept_no"
t.index ["emp_no"], name: "emp_no"
end
create_table "employee_clubs", force: :cascade do |t|
t.integer "emp_no", null: false
t.integer "club_id", null: false
t.index ["emp_no", "club_id"], name: "idx_emp_no_club_id"
end
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
t.date "birth_date", null: false
t.string "first_name", limit: 14, null: false
t.string "last_name", limit: 16, null: false
t.string "gender", limit: 1, null: false
t.date "hire_date", null: false
end
ERB
end

let(:migrate_dsl) do
erbh(<<-ERB)
create_table "departments", primary_key: "dept_no", force: :cascade do |t|
t.string "dept_name", limit: 40, null: false
t.date "from_date", null: false
t.date "to_date", null: false
t.index ["dept_name"], name: "dept_name", unique: true
end
create_table "dept_manager", id: false, force: :cascade do |t|
t.string "dept_no", null: false
t.integer "emp_no", null: false
t.index ["dept_no"], name: "dept_no"
t.index ["emp_no"], name: "emp_no"
end
create_table "employee_clubs", force: :cascade do |t|
t.string "emp_no", null: false
t.integer "club_id", null: false
t.index ["emp_no", "club_id"], name: "idx_emp_no_club_id"
end
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
t.date "birth_date", null: false
t.string "first_name", limit: 14, null: false
t.string "last_name", limit: 16, null: false
t.string "gender", limit: 1, null: false
t.date "hire_date", null: false
end
create_table "salaries", id: false, force: :cascade do |t|
t.integer "emp_no", null: false
t.integer "salary", null: false
t.date "from_date", null: false
t.date "to_date", null: false
end
add_index "salaries", ["emp_no"], name: "emp_no", using: :btree
ERB
end

let(:expected_dsl) do
erbh(<<-ERB)
create_table "departments", primary_key: "dept_no", force: :cascade do |t|
t.string "dept_name", limit: 40, null: false
t.index ["dept_name"], name: "dept_name", unique: true
end
create_table "dept_manager", id: false, force: :cascade do |t|
t.string "dept_no", null: false
t.integer "emp_no", null: false
t.date "from_date", null: false
t.date "to_date", null: false
t.index ["dept_no"], name: "dept_no"
t.index ["emp_no"], name: "emp_no"
end
create_table "employee_clubs", force: :cascade do |t|
t.integer "emp_no", null: false
t.integer "club_id", null: false
t.index ["emp_no", "club_id"], name: "idx_emp_no_club_id"
end
create_table "employees", primary_key: "emp_no", force: :cascade do |t|
t.date "birth_date", null: false
t.string "first_name", limit: 14, null: false
t.string "last_name", limit: 16, null: false
t.string "gender", limit: 1, null: false
t.date "hire_date", null: false
end
ERB
end

before { client.diff(dsl).migrate }
subject { client(drop_table_only: true) }

it {
delta = subject.diff(migrate_dsl)
expect(delta.differ?).to be_truthy
expect(subject.dump).to match_ruby dsl
delta.migrate
expect(subject.dump).to match_ruby expected_dsl
}
end
end

0 comments on commit a524c99

Please sign in to comment.