Merge pull request #51478 from kmcphillips/mysql-parse-version-error

Raise named exception in `AbstractMysqlAdapter` when DB reports an invalid version
This commit is contained in:
Jean Boussier 2024-04-04 17:15:45 +02:00 committed by GitHub
commit 58158c0f8c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 2 deletions

@ -1,3 +1,7 @@
* Raise an `ActiveRecord::ActiveRecordError` error when the MySQL database returns an invalid version string.
*Kevin McPhillips*
* `ActiveRecord::Base.transaction` now yields an `ActiveRecord::Transation` object.
This allows to register callbacks on it.

@ -680,7 +680,7 @@ def build_insert_sql(insert) # :nodoc:
def check_version # :nodoc:
if database_version < "5.5.8"
raise "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
raise DatabaseVersionError, "Your version of MySQL (#{database_version}) is too old. Active Record supports MySQL >= 5.5.8."
end
end
@ -1023,7 +1023,11 @@ def mismatched_foreign_key(message, sql:, binds:, connection_pool:)
end
def version_string(full_version_string)
full_version_string.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)[1]
if full_version_string && matches = full_version_string.match(/^(?:5\.5\.5-)?(\d+\.\d+\.\d+)/)
matches[1]
else
raise DatabaseVersionError, "Unable to parse MySQL version from #{full_version_string.inspect}"
end
end
end
end

@ -575,4 +575,9 @@ class ConnectionFailed < QueryAborted
# values, such as request parameters or model attributes to query methods.
class UnknownAttributeReference < ActiveRecordError
end
# DatabaseVersionError will be raised when the database version is not supported, or when
# the database version cannot be determined.
class DatabaseVersionError < ActiveRecordError
end
end

@ -216,6 +216,45 @@ def test_release_non_existent_advisory_lock
"expected release_advisory_lock to return false when there was no lock to release"
end
def test_version_string
@connection.stub(:get_full_version, "8.0.35-0ubuntu0.22.04.1") do
assert_equal "8.0.35", @connection.get_database_version.to_s
end
@connection.stub(:get_full_version, "5.7.0") do
assert_equal "5.7.0", @connection.get_database_version.to_s
end
end
def test_version_string_with_mariadb
@connection.stub(:get_full_version, "5.5.5-10.6.5-MariaDB-1:10.6.5+maria~focal") do
assert_equal "10.6.5", @connection.get_database_version.to_s
end
end
def test_version_string_invalid
@connection.stub(:get_full_version, "some-database-proxy") do
error = assert_raises(ActiveRecord::DatabaseVersionError) do
@connection.get_database_version
end
assert_equal "Unable to parse MySQL version from \"some-database-proxy\"", error.message
end
@connection.stub(:get_full_version, "") do
error = assert_raises(ActiveRecord::DatabaseVersionError) do
@connection.get_database_version
end
assert_equal "Unable to parse MySQL version from \"\"", error.message
end
@connection.stub(:get_full_version, nil) do
error = assert_raises(ActiveRecord::DatabaseVersionError) do
@connection.get_database_version
end
assert_equal "Unable to parse MySQL version from nil", error.message
end
end
private
def cause_server_side_disconnect
@connection.update("set @@wait_timeout=1")