Skip to content

Commit

Permalink
Dropped support for Postgres < 12, MySQL < 8.0, and MariaDB < 10.5
Browse files Browse the repository at this point in the history
  • Loading branch information
ankane committed Jun 17, 2024
1 parent 0376695 commit 1e42866
Show file tree
Hide file tree
Showing 12 changed files with 39 additions and 156 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
## 1.9.0 (unreleased)
## 2.0.0 (unreleased)

- Improved install generator for Trilogy
- Fixed charset check for MariaDB 11.4
- Dropped support for Ruby < 3.1 and Active Record < 6.1
- Dropped support for Postgres < 12, MySQL < 8.0, and MariaDB < 10.5

## 1.8.0 (2024-03-11)

Expand Down
2 changes: 1 addition & 1 deletion lib/strong_migrations/adapters/mariadb_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def name
end

def min_version
"10.2"
"10.5"
end

def server_version
Expand Down
2 changes: 1 addition & 1 deletion lib/strong_migrations/adapters/mysql_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ def name
end

def min_version
"5.7"
"8.0"
end

def server_version
Expand Down
6 changes: 3 additions & 3 deletions lib/strong_migrations/adapters/postgresql_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def name
end

def min_version
"10"
"12"
end

def server_version
Expand Down Expand Up @@ -42,7 +42,7 @@ def analyze_table(table)
end

def add_column_default_safe?
server_version >= Gem::Version.new("11")
true
end

def change_type_safe?(table, column, type, options, existing_column, existing_type)
Expand Down Expand Up @@ -103,7 +103,7 @@ def change_type_safe?(table, column, type, options, existing_column, existing_ty
# resolve with fallback
new_type = type_map[new_type] || new_type

safe = new_type == existing_type || (server_version >= Gem::Version.new("12") && time_zone == "UTC")
safe = new_type == existing_type || time_zone == "UTC"
end
when "time"
precision = options[:precision] || options[:limit] || 6
Expand Down
48 changes: 15 additions & 33 deletions lib/strong_migrations/checks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,20 @@ def check_add_column(*args)
#
# 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
Expand Down Expand Up @@ -235,11 +228,7 @@ 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
Expand All @@ -251,12 +240,10 @@ def check_change_column_null(*args)

validate_constraint_code = String.new(command_str(:validate_check_constraint, [table, {name: constraint_name}]))

if safe_with_check_constraint
change_args = [table, column, null]
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}])}"
end
validate_constraint_code << "\n #{command_str(:change_column_null, change_args)}"
validate_constraint_code << "\n #{command_str(:remove_check_constraint, [table, {name: constraint_name}])}"

if StrongMigrations.safe_by_default
safe_change_column_null(add_code, validate_code, change_args, remove_code, default)
Expand All @@ -265,13 +252,8 @@ def check_change_column_null(*args)

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,
Expand Down
10 changes: 0 additions & 10 deletions lib/strong_migrations/error_messages.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,6 @@ def up
end
end",

add_column_default_null:
"Adding a column with a null default blocks %{rewrite_blocks} while the entire table is rewritten.
Instead, add the column without a default value.
class %{migration_name} < ActiveRecord::Migration%{migration_suffix}
def change
%{command}
end
end",

add_column_default_callable:
"Strong Migrations does not support inspecting callable default values.
Please make really sure you're not calling a VOLATILE function,
Expand Down
34 changes: 3 additions & 31 deletions test/add_column_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,17 @@

class AddColumnTest < Minitest::Test
def test_default
if mysql? || mariadb?
assert_safe AddColumnDefault
else
with_target_version(10) do
assert_unsafe AddColumnDefault
end
end
end

def test_default_database_specific_versions
skip unless postgresql?
StrongMigrations.target_postgresql_version = "10"
assert_unsafe AddColumnDefault
ensure
StrongMigrations.target_postgresql_version = nil
assert_safe AddColumnDefault
end

def test_default_null
skip unless postgresql?

with_target_version(10) do
assert_unsafe AddColumnDefaultNull, "Adding a column with a null default"
end
assert_safe AddColumnDefaultNull
end

def test_default_not_null
skip unless postgresql?

with_target_version(10) do
assert_unsafe AddColumnDefaultNotNull, "Then add the NOT NULL constraint"
end
end

def test_default_safe_latest
skip unless postgresql? || mysql? || mariadb?

with_target_version(postgresql? ? 11 : (mysql? ? "8.0.12" : "10.3.2")) do
assert_safe AddColumnDefault
end
assert_unsafe AddColumnDefaultNotNull, "Then add the NOT NULL constraint"
end

def test_default_safe
Expand Down
28 changes: 5 additions & 23 deletions test/change_column_null_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,33 +12,19 @@ def test_basic
def test_constraint
skip unless postgresql?

with_target_version(12) do
assert_safe ChangeColumnNullConstraint
end
assert_safe ChangeColumnNullConstraint
end

def test_constraint_unvalidated
skip unless postgresql?

with_target_version(12) do
assert_unsafe ChangeColumnNullConstraintUnvalidated
end
assert_unsafe ChangeColumnNullConstraintUnvalidated
end

def test_constraint_default
skip unless postgresql?

with_target_version(12) do
assert_unsafe ChangeColumnNullConstraintDefault
end
end

def test_constraint_before_12
skip unless postgresql?

with_target_version(11) do
assert_unsafe ChangeColumnNullConstraint
end
assert_unsafe ChangeColumnNullConstraintDefault
end

def test_default
Expand All @@ -48,17 +34,13 @@ def test_default
def test_constraint_methods
skip unless postgresql?

with_target_version(12) do
assert_safe ChangeColumnNullConstraintMethods
end
assert_safe ChangeColumnNullConstraintMethods
end

def test_quoted
skip unless postgresql?

with_target_version(12) do
assert_safe ChangeColumnNullQuoted
end
assert_safe ChangeColumnNullQuoted
end

def test_mysql_non_strict_mode
Expand Down
37 changes: 2 additions & 35 deletions test/change_column_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,25 +122,13 @@ def test_decimal_unconstrained
def test_timestamps
skip unless postgresql?

with_target_version(12) do
assert_safe ChangeColumnTimestamps
end
assert_safe ChangeColumnTimestamps
end

def test_timestamps_non_utc
skip unless postgresql?

with_target_version(12) do
with_time_zone do
assert_unsafe ChangeColumnTimestamps
end
end
end

def test_timestamps_unsafe
skip unless postgresql?

with_target_version(11) do
with_time_zone do
assert_unsafe ChangeColumnTimestamps
end
end
Expand All @@ -150,13 +138,6 @@ def test_datetime_increase_precision
assert_safe ChangeColumnDatetimeIncreasePrecision
end

def test_datetime_increase_precision_before_12
skip unless postgresql?
with_target_version(11) do
assert_safe ChangeColumnDatetimeIncreasePrecision
end
end

def test_datetime_decrease_precision
skip unless postgresql?
assert_unsafe ChangeColumnDatetimeDecreasePrecision
Expand All @@ -167,13 +148,6 @@ def test_timestamp_increase_limit
assert_safe ChangeColumnTimestampIncreaseLimit
end

def test_timestamp_increase_limit_before_12
skip unless postgresql?
with_target_version(11) do
assert_safe ChangeColumnTimestampIncreaseLimit
end
end

def test_timestamp_decrease_limit
skip unless postgresql?
assert_unsafe ChangeColumnTimestampDecreaseLimit
Expand All @@ -184,13 +158,6 @@ def test_timestamptz_increase_limit
assert_safe ChangeColumnTimestamptzIncreaseLimit
end

def test_timestamptz_increase_limit_before_12
skip unless postgresql?
with_target_version(11) do
assert_safe ChangeColumnTimestamptzIncreaseLimit
end
end

def test_timestamptz_decrease_limit
skip unless postgresql?
assert_unsafe ChangeColumnTimestamptzDecreaseLimit
Expand Down
2 changes: 1 addition & 1 deletion test/migrations/add_column.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def change

class AddColumnDefaultNotNull < TestMigration
def change
add_column :users, :nice, :boolean, default: true, null: false
add_column :users, :nice, :uuid, default: "gen_random_uuid()", null: false
end
end

Expand Down
7 changes: 4 additions & 3 deletions test/multiple_databases_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ class MultipleDatabasesTest < Minitest::Test
def test_target_version
skip unless postgresql?

with_target_version({primary: 10, animals: 11}) do
with_target_version({primary: 12, animals: 16}) do
with_database(:primary) do
assert_unsafe AddColumnDefault
# TODO use new check
# assert_unsafe AddColumnDefault
end
with_database(:animals) do
assert_safe AddColumnDefault
Expand All @@ -16,7 +17,7 @@ def test_target_version

def test_target_version_unconfigured
error = assert_raises(StrongMigrations::Error) do
with_target_version({primary: 10}) do
with_target_version({primary: 12}) do
with_database(:animals) do
assert_safe AddColumnDefault
end
Expand Down
16 changes: 2 additions & 14 deletions test/safe_by_default_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,17 +115,7 @@ def test_add_check_constraint_extra_arguments
def test_change_column_null
skip unless postgresql?

with_target_version(12) do
assert_safe ChangeColumnNull
end
end

def test_change_column_null_constraint
skip unless postgresql?

with_target_version(11) do
assert_safe ChangeColumnNull
end
assert_safe ChangeColumnNull
end

def test_change_column_null_default
Expand All @@ -134,9 +124,7 @@ def test_change_column_null_default
# TODO add
# User.create!
error = assert_raises(StrongMigrations::Error) do
with_target_version(12) do
assert_safe ChangeColumnNullDefault
end
assert_safe ChangeColumnNullDefault
end
assert_match "default value not supported yet with safe_by_default", error.message
ensure
Expand Down

0 comments on commit 1e42866

Please sign in to comment.