summaryrefslogtreecommitdiff
path: root/lib/gitlab/database/tables_sorted_by_foreign_keys.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/database/tables_sorted_by_foreign_keys.rb')
-rw-r--r--lib/gitlab/database/tables_sorted_by_foreign_keys.rb41
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/gitlab/database/tables_sorted_by_foreign_keys.rb b/lib/gitlab/database/tables_sorted_by_foreign_keys.rb
new file mode 100644
index 00000000000..9f096904d31
--- /dev/null
+++ b/lib/gitlab/database/tables_sorted_by_foreign_keys.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Database
+ class TablesSortedByForeignKeys
+ include TSort
+
+ def initialize(connection, tables)
+ @connection = connection
+ @tables = tables
+ end
+
+ def execute
+ strongly_connected_components
+ end
+
+ private
+
+ def tsort_each_node(&block)
+ tables_dependencies.each_key(&block)
+ end
+
+ def tsort_each_child(node, &block)
+ tables_dependencies[node].each(&block)
+ end
+
+ # it maps the tables to the tables that depend on it
+ def tables_dependencies
+ @tables.to_h do |table_name|
+ [table_name, all_foreign_keys[table_name]&.map(&:from_table).to_a]
+ end
+ end
+
+ def all_foreign_keys
+ @all_foreign_keys ||= @tables.flat_map do |table_name|
+ @connection.foreign_keys(table_name)
+ end.group_by(&:to_table)
+ end
+ end
+ end
+end