diff options
author | Starfall <us@starfall.systems> | 2021-04-02 15:04:35 -0500 |
---|---|---|
committer | Starfall <us@starfall.systems> | 2021-04-02 15:04:35 -0500 |
commit | aeb0f34cefd88caaaa51e8250e1f6ddde280c4bb (patch) | |
tree | 15dafdc2cdfd9e78e72e461440b593c3fc89788e /app/models/concerns | |
parent | 0f7be4b48947a9edcbb6fb84d5d0fd9150ee0870 (diff) | |
parent | b7ec2a900251410c65ba214b50c1657209285b07 (diff) |
Merge branch 'glitch'
Diffstat (limited to 'app/models/concerns')
-rw-r--r-- | app/models/concerns/account_counters.rb | 60 | ||||
-rw-r--r-- | app/models/concerns/account_interactions.rb | 2 | ||||
-rw-r--r-- | app/models/concerns/expireable.rb | 2 | ||||
-rw-r--r-- | app/models/concerns/omniauthable.rb | 1 |
4 files changed, 60 insertions, 5 deletions
diff --git a/app/models/concerns/account_counters.rb b/app/models/concerns/account_counters.rb index 6e25e1905..fd3f161ad 100644 --- a/app/models/concerns/account_counters.rb +++ b/app/models/concerns/account_counters.rb @@ -3,6 +3,8 @@ module AccountCounters extend ActiveSupport::Concern + ALLOWED_COUNTER_KEYS = %i(statuses_count following_count followers_count).freeze + included do has_one :account_stat, inverse_of: :account after_save :save_account_stat @@ -14,11 +16,65 @@ module AccountCounters :following_count=, :followers_count, :followers_count=, - :increment_count!, - :decrement_count!, :last_status_at, to: :account_stat + # @param [Symbol] key + def increment_count!(key) + update_count!(key, 1) + end + + # @param [Symbol] key + def decrement_count!(key) + update_count!(key, -1) + end + + # @param [Symbol] key + # @param [Integer] value + def update_count!(key, value) + raise ArgumentError, "Invalid key #{key}" unless ALLOWED_COUNTER_KEYS.include?(key) + raise ArgumentError, 'Do not call update_count! on dirty objects' if association(:account_stat).loaded? && account_stat&.changed? && account_stat.changed_attribute_names_to_save == %w(id) + + value = value.to_i + default_value = value.positive? ? value : 0 + + # We do an upsert using manually written SQL, as Rails' upsert method does + # not seem to support writing expressions in the UPDATE clause, but only + # re-insert the provided values instead. + # Even ARel seem to be missing proper handling of upserts. + sql = if value.positive? && key == :statuses_count + <<-SQL.squish + INSERT INTO account_stats(account_id, #{key}, created_at, updated_at, last_status_at) + VALUES (:account_id, :default_value, now(), now(), now()) + ON CONFLICT (account_id) DO UPDATE + SET #{key} = account_stats.#{key} + :value, + last_status_at = now(), + lock_version = account_stats.lock_version + 1, + updated_at = now() + RETURNING id; + SQL + else + <<-SQL.squish + INSERT INTO account_stats(account_id, #{key}, created_at, updated_at) + VALUES (:account_id, :default_value, now(), now()) + ON CONFLICT (account_id) DO UPDATE + SET #{key} = account_stats.#{key} + :value, + lock_version = account_stats.lock_version + 1, + updated_at = now() + RETURNING id; + SQL + end + + sql = AccountStat.sanitize_sql([sql, account_id: id, default_value: default_value, value: value]) + account_stat_id = AccountStat.connection.exec_query(sql)[0]['id'] + + # Reload account_stat if it was loaded, taking into account newly-created unsaved records + if association(:account_stat).loaded? + account_stat.id = account_stat_id if account_stat.new_record? + account_stat.reload + end + end + def account_stat super || build_account_stat end diff --git a/app/models/concerns/account_interactions.rb b/app/models/concerns/account_interactions.rb index 974f57820..51e8e04a8 100644 --- a/app/models/concerns/account_interactions.rb +++ b/app/models/concerns/account_interactions.rb @@ -67,7 +67,7 @@ module AccountInteractions private def follow_mapping(query, field) - query.pluck(field).each_with_object({}) { |id, mapping| mapping[id] = true } + query.pluck(field).index_with(true) end end diff --git a/app/models/concerns/expireable.rb b/app/models/concerns/expireable.rb index a66a4661b..4d902abcb 100644 --- a/app/models/concerns/expireable.rb +++ b/app/models/concerns/expireable.rb @@ -17,7 +17,7 @@ module Expireable end def expires_in=(interval) - self.expires_at = interval.to_i.seconds.from_now if interval.present? + self.expires_at = interval.present? ? interval.to_i.seconds.from_now : nil @expires_in = interval end diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb index 79d671d10..791a94911 100644 --- a/app/models/concerns/omniauthable.rb +++ b/app/models/concerns/omniauthable.rb @@ -68,7 +68,6 @@ module Omniauthable def user_params_from_auth(email, auth) { email: email || "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com", - password: Devise.friendly_token[0, 20], agreement: true, external: true, account_attributes: { |