457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
|
# File 'activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb', line 457
def foreign_keys(table_name)
raise ArgumentError unless table_name.present?
scope = quoted_scope(table_name)
fk_info = internal_exec_query(<<~SQL, "SCHEMA")
SELECT fk.referenced_table_name AS 'to_table',
fk.referenced_column_name AS 'primary_key',
fk.column_name AS 'column',
fk.constraint_name AS 'name',
fk.ordinal_position AS 'position',
rc.update_rule AS 'on_update',
rc.delete_rule AS 'on_delete'
FROM information_schema.referential_constraints rc
JOIN information_schema.key_column_usage fk
USING (constraint_schema, constraint_name)
WHERE fk.referenced_column_name IS NOT NULL
AND fk.table_schema = #{scope[:schema]}
AND fk.table_name = #{scope[:name]}
AND rc.constraint_schema = #{scope[:schema]}
AND rc.table_name = #{scope[:name]}
SQL
grouped_fk = fk_info.group_by { |row| row["name"] }.values.each { |group| group.sort_by! { |row| row["position"] } }
grouped_fk.map do |group|
row = group.first
options = {
name: row["name"],
on_update: (row["on_update"]),
on_delete: (row["on_delete"])
}
if group.one?
options[:column] = unquote_identifier(row["column"])
options[:primary_key] = row["primary_key"]
else
options[:column] = group.map { |row| unquote_identifier(row["column"]) }
options[:primary_key] = group.map { |row| row["primary_key"] }
end
ForeignKeyDefinition.new(table_name, unquote_identifier(row["to_table"]), options)
end
end
|