diff --git a/lib/foreigner/connection_adapters/mysql2_adapter.rb b/lib/foreigner/connection_adapters/mysql2_adapter.rb index cc83de8..81941c1 100644 --- a/lib/foreigner/connection_adapters/mysql2_adapter.rb +++ b/lib/foreigner/connection_adapters/mysql2_adapter.rb @@ -26,13 +26,13 @@ def foreign_keys(table_name) fk_info.map do |row| options = {column: row['column'], name: row['name'], primary_key: row['primary_key']} - if create_table_info =~ /CONSTRAINT #{quote_column_name(row['name'])} FOREIGN KEY .* REFERENCES .*\)( ON DELETE (CASCADE|SET NULL|RESTRICT))? ?(.*)$/ - options[:dependent] = case $2 + if create_table_info =~ /CONSTRAINT #{quote_column_name(row['name'])} FOREIGN KEY .* REFERENCES .*\)(?: ON DELETE (CASCADE|SET NULL|RESTRICT))?(?: (.+?))?,?$/ + options[:dependent] = case $1 when 'CASCADE' then :delete when 'SET NULL' then :nullify when 'RESTRICT' then :restrict end - options[:options] = $3 # e.g. ON UPDATE ... + options[:options] = $2 # e.g. ON UPDATE ... end ForeignKeyDefinition.new(table_name, row['to_table'], options) end diff --git a/test/foreigner/connection_adapters/mysql2_adapter_test.rb b/test/foreigner/connection_adapters/mysql2_adapter_test.rb index 86267d9..b85df15 100644 --- a/test/foreigner/connection_adapters/mysql2_adapter_test.rb +++ b/test/foreigner/connection_adapters/mysql2_adapter_test.rb @@ -9,6 +9,45 @@ class Mysql2Adapter setup do @adapter = Mysql2Adapter.new + @adapter.instance_variable_set(:@config, database: 'foo') + end + + test 'foreign_keys parsing' do + @adapter.expects(:select_all).at_least_once.returns([ + {'column' => 'foo_id', 'name' => 'foo_bar_foo_id_fk', 'primary_key' => 'id', 'to_table' => 'foo'} + ]) + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`)\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent:nil, options:nil}), + @adapter.foreign_keys('bar').first + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`),\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent:nil, options:nil}), + @adapter.foreign_keys('bar').first + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`) ON DELETE CASCADE\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent: :delete, options:nil}), + @adapter.foreign_keys('bar').first + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`) ON DELETE CASCADE,\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent: :delete, options:nil}), + @adapter.foreign_keys('bar').first + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`) FOO BAR\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent:nil, options:'FOO BAR'}), + @adapter.foreign_keys('bar').first + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`) FOO BAR,\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent:nil, options:'FOO BAR'}), + @adapter.foreign_keys('bar').first + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`) ON DELETE CASCADE FOO BAR,\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent: :delete, options:'FOO BAR'}), + @adapter.foreign_keys('bar').first + + @adapter.expects(:select_one).returns('Create Table' => "CONSTRAINT `foo_bar_foo_id_fk` FOREIGN KEY (`foo_id`) REFERENCES `foo` (`id`) ON DELETE CASCADE FOO BAR,\n") + assert_equal Foreigner::ConnectionAdapters::ForeignKeyDefinition.new('bar', 'foo', {column:"foo_id", name:"foo_bar_foo_id_fk", primary_key:"id", dependent: :delete, options:'FOO BAR'}), + @adapter.foreign_keys('bar').first end test 'remove_foreign_key_sql by table' do @@ -31,4 +70,4 @@ class Mysql2Adapter @adapter.remove_foreign_key_sql(:suppliers, column: "ship_to_id") ) end -end \ No newline at end of file +end