lib/strong_migrations/checks.rb in strong_migrations-1.8.0 vs lib/strong_migrations/checks.rb in strong_migrations-2.0.0

- old
+ new

@@ -37,31 +37,24 @@ # Check key since DEFAULT NULL behaves differently from no default # # Also, Active Record has special case for uuid columns that allows function default values # https://github.com/rails/rails/blob/v7.0.3.1/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb#L92-L93 - if options.key?(:default) && (!adapter.add_column_default_safe? || (volatile = (postgresql? && type.to_s == "uuid" && default.to_s.include?("()") && adapter.default_volatile?(default)))) + if !default.nil? && (!adapter.add_column_default_safe? || (volatile = (postgresql? && type.to_s == "uuid" && default.to_s.include?("()") && adapter.default_volatile?(default)))) if options[:null] == false options = options.except(:null) append = "\n\nThen add the NOT NULL constraint in separate migrations." end - if default.nil? - raise_error :add_column_default_null, - command: command_str("add_column", [table, column, type, options.except(:default)]), - append: append, - rewrite_blocks: adapter.rewrite_blocks - else - raise_error :add_column_default, - add_command: command_str("add_column", [table, column, type, options.except(:default)]), - change_command: command_str("change_column_default", [table, column, default]), - remove_command: command_str("remove_column", [table, column]), - code: backfill_code(table, column, default, volatile), - append: append, - rewrite_blocks: adapter.rewrite_blocks, - default_type: (volatile ? "volatile" : "non-null") - end + raise_error :add_column_default, + add_command: command_str("add_column", [table, column, type, options.except(:default)]), + change_command: command_str("change_column_default", [table, column, default]), + remove_command: command_str("remove_column", [table, column]), + code: backfill_code(table, column, default, volatile), + append: append, + rewrite_blocks: adapter.rewrite_blocks, + default_type: (volatile ? "volatile" : "non-null") elsif default.is_a?(Proc) && postgresql? # adding a column with a VOLATILE default is not safe # https://www.postgresql.org/docs/current/sql-altertable.html#SQL-ALTERTABLE-NOTES # functions like random() and clock_timestamp() are VOLATILE # check for Proc to match Active Record @@ -233,64 +226,36 @@ def check_change_column_null(*args) table, column, null, default = args if !null if postgresql? - safe = false - safe_with_check_constraint = adapter.server_version >= Gem::Version.new("12") - if safe_with_check_constraint - safe = adapter.constraints(table).any? { |c| c["def"] == "CHECK ((#{column} IS NOT NULL))" || c["def"] == "CHECK ((#{connection.quote_column_name(column)} IS NOT NULL))" } - end + safe = adapter.constraints(table).any? { |c| c["def"] == "CHECK ((#{column} IS NOT NULL))" || c["def"] == "CHECK ((#{connection.quote_column_name(column)} IS NOT NULL))" } unless safe # match https://github.com/nullobject/rein constraint_name = "#{table}_#{column}_null" add_code = constraint_str("ALTER TABLE %s ADD CONSTRAINT %s CHECK (%s IS NOT NULL) NOT VALID", [table, constraint_name, column]) validate_code = constraint_str("ALTER TABLE %s VALIDATE CONSTRAINT %s", [table, constraint_name]) remove_code = constraint_str("ALTER TABLE %s DROP CONSTRAINT %s", [table, constraint_name]) - constraint_methods = ar_version >= 6.1 + validate_constraint_code = String.new(command_str(:validate_check_constraint, [table, {name: constraint_name}])) - validate_constraint_code = - if constraint_methods - String.new(command_str(:validate_check_constraint, [table, {name: constraint_name}])) - else - String.new(safety_assured_str(validate_code)) - end + change_args = [table, column, null] - if safe_with_check_constraint - change_args = [table, column, null] + validate_constraint_code << "\n #{command_str(:change_column_null, change_args)}" + validate_constraint_code << "\n #{command_str(:remove_check_constraint, [table, {name: constraint_name}])}" - validate_constraint_code << "\n #{command_str(:change_column_null, change_args)}" - - if constraint_methods - validate_constraint_code << "\n #{command_str(:remove_check_constraint, [table, {name: constraint_name}])}" - else - validate_constraint_code << "\n #{safety_assured_str(remove_code)}" - end - end - if StrongMigrations.safe_by_default safe_change_column_null(add_code, validate_code, change_args, remove_code, default) throw :safe end - add_constraint_code = - if constraint_methods - command_str(:add_check_constraint, [table, "#{quote_column_if_needed(column)} IS NOT NULL", {name: constraint_name, validate: false}]) - else - safety_assured_str(add_code) - end + add_constraint_code = command_str(:add_check_constraint, [table, "#{quote_column_if_needed(column)} IS NOT NULL", {name: constraint_name, validate: false}]) - validate_constraint_code = - if safe_with_check_constraint - down_code = "#{add_constraint_code}\n #{command_str(:change_column_null, [table, column, true])}" - "def up\n #{validate_constraint_code}\n end\n\n def down\n #{down_code}\n end" - else - "def change\n #{validate_constraint_code}\n end" - end + down_code = "#{add_constraint_code}\n #{command_str(:change_column_null, [table, column, true])}" + validate_constraint_code = "def up\n #{validate_constraint_code}\n end\n\n def down\n #{down_code}\n end" raise_error :change_column_null_postgresql, add_constraint_code: add_constraint_code, validate_constraint_code: validate_constraint_code end @@ -371,16 +336,10 @@ if postgresql? && options[:algorithm] != :concurrently && !new_table?(table) # avoid suggesting extra (invalid) args args = args[0..1] unless StrongMigrations.safe_by_default - # Active Record < 6.1 only supports two arguments (including options) - if args.size == 2 && ar_version < 6.1 - # arg takes precedence over option - options[:column] = args.pop - end - if StrongMigrations.safe_by_default safe_remove_index(*args, **options) throw :safe end @@ -485,10 +444,10 @@ end # only quote when needed # important! only use for display purposes def quote_column_if_needed(column) - column.to_s =~ /\A[a-z0-9_]+\z/ ? column : connection.quote_column_name(column) + /\A[a-z0-9_]+\z/.match?(column.to_s) ? column : connection.quote_column_name(column) end def new_table?(table) @new_tables.include?(table.to_s) end