Raise a descriptive error if the MySQL adapter fails to parse the version string.

This commit is contained in:
Kevin McPhillips 2024-04-03 11:32:24 -04:00
parent 3d418c0551
commit 869d802c48
No known key found for this signature in database
GPG Key ID: 55E5FDCFFBA68323
4 changed files with 48 additions and 2 deletions

View File

@ -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.

View File

@ -680,7 +680,7 @@ module ActiveRecord
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 @@ module ActiveRecord
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

View File

@ -575,4 +575,9 @@ module ActiveRecord
# 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

View File

@ -216,6 +216,39 @@ class ConnectionTest < ActiveRecord::AbstractMysqlTestCase
"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_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")