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