Skip to content

Commit

Permalink
Merge pull request #284 from abicky/consider-table-dependency
Browse files Browse the repository at this point in the history
Drop tables in an order considering foreign key constraints
  • Loading branch information
abicky authored Sep 10, 2019
2 parents 74efcc0 + 0ddf891 commit 02d56d8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 12 deletions.
2 changes: 1 addition & 1 deletion lib/ridgepole/delta.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def script
append_change(table_name, attrs, buf, pre_buf_for_fk, post_buf_for_fk)
end

(@delta[:delete] || {}).each do |table_name, attrs|
(@delta[:delete] || {}).reverse_each do |table_name, attrs|
append_drop_table(table_name, attrs, buf)
end

Expand Down
25 changes: 24 additions & 1 deletion lib/ridgepole/dsl_parser.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require 'tsort'

module Ridgepole
class DSLParser
def initialize(options = {})
Expand All @@ -10,7 +12,11 @@ def parse(dsl, opts = {})
definition, execute = Context.eval(dsl, opts)
check_orphan_index(definition)
check_orphan_foreign_key(definition)
[definition, execute]
sorted_definition = {}
DependencyGraph.new(definition).tsort_each do |table_name|
sorted_definition[table_name] = definition[table_name]
end
[sorted_definition, execute]
end

private
Expand All @@ -26,5 +32,22 @@ def check_orphan_foreign_key(definition)
raise "Table `#{table_name}` to create the foreign key is not defined: #{attrs[:foreign_keys].keys.join(',')}" if attrs[:foreign_keys] && !(attrs[:definition])
end
end

class DependencyGraph
include TSort

def initialize(definition)
@definition = definition
end

def tsort_each_child(table_name, &block)
keys = @definition[table_name].fetch(:foreign_keys, {})
keys.each_value { |v| block.call(v[:to_table]) }
end

def tsort_each_node(&block)
@definition.each_key(&block)
end
end
end
end
20 changes: 10 additions & 10 deletions spec/mysql/fk/migrate_drop_fk_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,29 @@
context 'when drop fk when drop table' do
let(:dsl) do
erbh(<<-ERB)
create_table "parent", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade do |t|
create_table "0_parent", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade do |t|
end
create_table "child", force: :cascade do |t|
t.integer "parent_id"
t.index ["parent_id"], name: "par_id", <%= i cond(5.0, using: :btree) %>
create_table "1_child", force: :cascade do |t|
t.integer "0_parent_id"
t.index ["0_parent_id"], name: "par_id", <%= i cond(5.0, using: :btree) %>
end
add_foreign_key "child", "parent", name: "child_ibfk_1"
add_foreign_key "1_child", "0_parent", name: "child_ibfk_1"
ERB
end

let(:sorted_dsl) do
erbh(<<-ERB)
create_table "child", force: :cascade do |t|
t.integer "parent_id"
t.index ["parent_id"], name: "par_id", <%= i cond(5.0, using: :btree) %>
create_table "0_parent", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade do |t|
end
create_table "parent", <%= i cond('>= 5.1',id: :integer) %>, force: :cascade do |t|
create_table "1_child", force: :cascade do |t|
t.integer "0_parent_id"
t.index ["0_parent_id"], name: "par_id", <%= i cond(5.0, using: :btree) %>
end
add_foreign_key "child", "parent", name: "child_ibfk_1"
add_foreign_key "1_child", "0_parent", name: "child_ibfk_1"
ERB
end

Expand Down

0 comments on commit 02d56d8

Please sign in to comment.