mirror of https://github.com/tootsuite/mastodon
Consolidate account scopes for `LOWER` (index using) username/domain queries (#30451)
parent
32c30bf0fd
commit
4a77e477ee
|
@ -142,6 +142,8 @@ class Account < ApplicationRecord
|
|||
scope :not_excluded_by_account, ->(account) { where.not(id: account.excluded_from_timeline_account_ids) }
|
||||
scope :not_domain_blocked_by_account, ->(account) { where(arel_table[:domain].eq(nil).or(arel_table[:domain].not_in(account.excluded_from_timeline_domains))) }
|
||||
scope :dormant, -> { joins(:account_stat).merge(AccountStat.without_recent_activity) }
|
||||
scope :with_username, ->(value) { where arel_table[:username].lower.eq(value.to_s.downcase) }
|
||||
scope :with_domain, ->(value) { where arel_table[:domain].lower.eq(value&.to_s&.downcase) }
|
||||
|
||||
after_update_commit :trigger_update_webhooks
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
||||
def get(account, limit: DEFAULT_LIMIT)
|
||||
if setting_enabled?
|
||||
base_account_scope(account).where(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
|
||||
base_account_scope(account).merge(setting_to_where_condition).limit(limit).pluck(:id).zip([key].cycle)
|
||||
else
|
||||
[]
|
||||
end
|
||||
|
@ -25,11 +25,9 @@ class AccountSuggestions::SettingSource < AccountSuggestions::Source
|
|||
|
||||
def setting_to_where_condition
|
||||
usernames_and_domains.map do |(username, domain)|
|
||||
Arel::Nodes::Grouping.new(
|
||||
Account.arel_table[:username].lower.eq(username.downcase).and(
|
||||
Account.arel_table[:domain].lower.eq(domain&.downcase)
|
||||
)
|
||||
)
|
||||
Account
|
||||
.with_username(username)
|
||||
.with_domain(domain)
|
||||
end.reduce(:or)
|
||||
end
|
||||
|
||||
|
|
|
@ -25,42 +25,11 @@ module Account::FinderConcern
|
|||
end
|
||||
|
||||
def find_remote(username, domain)
|
||||
AccountFinder.new(username, domain).account
|
||||
end
|
||||
end
|
||||
|
||||
class AccountFinder
|
||||
attr_reader :username, :domain
|
||||
|
||||
def initialize(username, domain)
|
||||
@username = username
|
||||
@domain = domain
|
||||
end
|
||||
|
||||
def account
|
||||
scoped_accounts.order(id: :asc).take
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def scoped_accounts
|
||||
Account.unscoped.tap do |scope|
|
||||
scope.merge! with_usernames
|
||||
scope.merge! matching_username
|
||||
scope.merge! matching_domain
|
||||
end
|
||||
end
|
||||
|
||||
def with_usernames
|
||||
Account.where.not(Account.arel_table[:username].lower.eq '')
|
||||
end
|
||||
|
||||
def matching_username
|
||||
Account.where(Account.arel_table[:username].lower.eq username.to_s.downcase)
|
||||
end
|
||||
|
||||
def matching_domain
|
||||
Account.where(Account.arel_table[:domain].lower.eq(domain.nil? ? nil : domain.to_s.downcase))
|
||||
Account
|
||||
.with_username(username)
|
||||
.with_domain(domain)
|
||||
.order(id: :asc)
|
||||
.take
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -22,7 +22,7 @@ module User::LdapAuthenticable
|
|||
safe_username = safe_username.gsub(keys, replacement)
|
||||
end
|
||||
|
||||
resource = joins(:account).merge(Account.where(Account.arel_table[:username].lower.eq safe_username.downcase)).take
|
||||
resource = joins(:account).merge(Account.with_username(safe_username)).take
|
||||
|
||||
if resource.blank?
|
||||
resource = new(
|
||||
|
|
|
@ -81,7 +81,7 @@ class ReportService < BaseService
|
|||
|
||||
# If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses.
|
||||
domain = @source_account.domain.to_s.downcase
|
||||
has_followers = @target_account.followers.where(Account.arel_table[:domain].lower.eq(domain)).exists?
|
||||
has_followers = @target_account.followers.with_domain(domain).exists?
|
||||
visibility = has_followers ? %i(public unlisted private) : %i(public unlisted)
|
||||
scope = @target_account.statuses.with_discarded
|
||||
scope.merge!(scope.where(visibility: visibility).or(scope.where('EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)', domain)))
|
||||
|
|
|
@ -6,10 +6,7 @@ class UniqueUsernameValidator < ActiveModel::Validator
|
|||
def validate(account)
|
||||
return if account.username.blank?
|
||||
|
||||
normalized_username = account.username.downcase
|
||||
normalized_domain = account.domain&.downcase
|
||||
|
||||
scope = Account.where(Account.arel_table[:username].lower.eq normalized_username).where(Account.arel_table[:domain].lower.eq normalized_domain)
|
||||
scope = Account.with_username(account.username).with_domain(account.domain)
|
||||
scope = scope.where.not(id: account.id) if account.persisted?
|
||||
|
||||
account.errors.add(:username, :taken) if scope.exists?
|
||||
|
|
Loading…
Reference in New Issue