lib/strong_migrations/checker.rb in strong_migrations-0.7.4 vs lib/strong_migrations/checker.rb in strong_migrations-0.7.5

- old
+ new

@@ -229,22 +229,42 @@ 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]) - validate_constraint_code = String.new(safety_assured_str(validate_code)) + validate_constraint_code = + if ar_version >= 6.1 + String.new(command_str(:validate_check_constraint, [table, {name: constraint_name}])) + else + String.new(safety_assured_str(validate_code)) + end + if postgresql_version >= Gem::Version.new("12") change_args = [table, column, null] validate_constraint_code << "\n #{command_str(:change_column_null, change_args)}" - validate_constraint_code << "\n #{safety_assured_str(remove_code)}" + + if ar_version >= 6.1 + 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 return safe_change_column_null(add_code, validate_code, change_args, remove_code) if StrongMigrations.safe_by_default + add_constraint_code = + if ar_version >= 6.1 + # only quote when needed + expr_column = column.to_s =~ /\A[a-z0-9_]+\z/ ? column : connection.quote_column_name(column) + command_str(:add_check_constraint, [table, "#{expr_column} IS NOT NULL", {name: constraint_name, validate: false}]) + else + safety_assured_str(add_code) + end + raise_error :change_column_null_postgresql, - add_constraint_code: safety_assured_str(add_code), + add_constraint_code: add_constraint_code, validate_constraint_code: validate_constraint_code end elsif mysql? || mariadb? raise_error :change_column_null_mysql elsif !default.nil? @@ -255,14 +275,14 @@ when :add_foreign_key from_table, to_table, options = args options ||= {} # always validated before 5.2 - validate = options.fetch(:validate, true) || ActiveRecord::VERSION::STRING < "5.2" + validate = options.fetch(:validate, true) || ar_version < 5.2 if postgresql? && validate - if ActiveRecord::VERSION::STRING < "5.2" + if ar_version < 5.2 # fk name logic from rails primary_key = options[:primary_key] || "id" column = options[:column] || "#{to_table.to_s.singularize}_id" hashed_identifier = Digest::SHA256.hexdigest("#{from_table}_#{column}_fk").first(10) fk_name = options[:name] || "fk_rails_#{hashed_identifier}" @@ -285,10 +305,33 @@ end when :validate_foreign_key if postgresql? && writes_blocked? raise_error :validate_foreign_key end + when :add_check_constraint + table, expression, options = args + options ||= {} + + if !new_table?(table) + if postgresql? && options[:validate] != false + add_options = options.merge(validate: false) + name = options[:name] || @migration.check_constraint_options(table, expression, options)[:name] + validate_options = {name: name} + + return safe_add_check_constraint(table, expression, add_options, validate_options) if StrongMigrations.safe_by_default + + raise_error :add_check_constraint, + add_check_constraint_code: command_str("add_check_constraint", [table, expression, add_options]), + validate_check_constraint_code: command_str("validate_check_constraint", [table, validate_options]) + elsif mysql? || mariadb? + raise_error :add_check_constraint_mysql + end + end + when :validate_check_constraint + if postgresql? && writes_blocked? + raise_error :validate_check_constraint + end end StrongMigrations.checks.each do |check| @migration.instance_exec(method, args, &check) end @@ -406,9 +449,13 @@ target_version.to_s else yield end Gem::Version.new(version) + end + + def ar_version + ActiveRecord::VERSION::STRING.to_f end def check_lock_timeout limit = StrongMigrations.lock_timeout_limit