Add an index to users login to speed up find user by login. For MySQL and MSSQL databases which are case-insensitive by default, search for lower cases in the existing results to avoid extra queries (#43838).

git-svn-id: https://svn.redmine.org/redmine/trunk@24516 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Marius Balteanu
2026-03-19 06:21:30 +00:00
parent f8813c5a49
commit 81745a295e
2 changed files with 12 additions and 2 deletions

View File

@@ -546,11 +546,17 @@ class User < Principal
def self.find_by_login(login)
login = Redmine::CodesetUtil.replace_invalid_utf8(login.to_s)
if login.present?
users = where(:login => login)
# First look for an exact match
user = where(:login => login).detect {|u| u.login == login}
user = users.detect {|u| u.login == login}
unless user
# Fail over to case-insensitive if none was found
user = find_by("LOWER(login) = ?", login.downcase)
if Redmine::Database.mysql? || Redmine::Database.sqlserver?
# MySQL and SQLServer are case-insensitive by default, we can search in the existing results
user = users.detect {|u| u.login.casecmp?(login)}
else
user = find_by("LOWER(login) = ?", login.downcase)
end
end
user
end

View File

@@ -65,6 +65,10 @@ module Redmine
mysql? ? ActiveRecord::Base.connection.select_value("SELECT VERSION()") : nil
end
def sqlserver?
/sqlserver/i.match?(ActiveRecord::Base.connection.adapter_name)
end
# Returns a SQL statement for case/accent (if possible) insensitive match
def like(left, right, options={})
neg = (options[:match] == false ? 'NOT ' : '')