summaryrefslogtreecommitdiff
path: root/rubocop/cop
diff options
context:
space:
mode:
authorRobert Speicher <rspeicher@gmail.com>2017-04-24 12:48:35 -0500
committerRobert Speicher <rspeicher@gmail.com>2017-04-28 15:55:55 -0500
commitb9fa17d87b534e588d80bb029c7f8cf9f9ff0c45 (patch)
tree11af18e9ec7f21e687c31b5f3fca414cd19b6892 /rubocop/cop
parent9c27c90b4a8a9ea179af9588a7dbd2037829905f (diff)
downloadgitlab-ce-b9fa17d87b534e588d80bb029c7f8cf9f9ff0c45.tar.gz
Add AddColumnWithDefaultToLargeTable cop
Diffstat (limited to 'rubocop/cop')
-rw-r--r--rubocop/cop/migration/add_column_with_default_to_large_table.rb51
1 files changed, 51 insertions, 0 deletions
diff --git a/rubocop/cop/migration/add_column_with_default_to_large_table.rb b/rubocop/cop/migration/add_column_with_default_to_large_table.rb
new file mode 100644
index 00000000000..2372e6b60ea
--- /dev/null
+++ b/rubocop/cop/migration/add_column_with_default_to_large_table.rb
@@ -0,0 +1,51 @@
+require_relative '../../migration_helpers'
+
+module RuboCop
+ module Cop
+ module Migration
+ # This cop checks for `add_column_with_default` on a table that's been
+ # explicitly blacklisted because of its size.
+ #
+ # Even though this helper performs the update in batches to avoid
+ # downtime, using it with tables with millions of rows still causes a
+ # significant delay in the deploy process and is best avoided.
+ #
+ # See https://gitlab.com/gitlab-com/infrastructure/issues/1602 for more
+ # information.
+ class AddColumnWithDefaultToLargeTable < RuboCop::Cop::Cop
+ include MigrationHelpers
+
+ MSG = 'Using `add_column_with_default` on the `%s` table will take a ' \
+ 'long time to complete, and should be avoided unless absolutely ' \
+ 'necessary'.freeze
+
+ LARGE_TABLES = %i[
+ events
+ issues
+ merge_requests
+ namespaces
+ notes
+ projects
+ routes
+ users
+ ].freeze
+
+ def_node_matcher :add_column_with_default?, <<~PATTERN
+ (send nil :add_column_with_default $(sym ...) ...)
+ PATTERN
+
+ def on_send(node)
+ return unless in_migration?(node)
+
+ matched = add_column_with_default?(node)
+ return unless matched
+
+ table = matched.to_a.first
+ return unless LARGE_TABLES.include?(table)
+
+ add_offense(node, :expression, format(MSG, table))
+ end
+ end
+ end
+ end
+end