88 lines
2.7 KiB
Ruby
88 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class TopicGroup < ActiveRecord::Base
|
|
belongs_to :group
|
|
belongs_to :topic
|
|
|
|
def self.update_last_read(user, topic_id, post_number)
|
|
updated_groups = update_read_count(user, topic_id, post_number)
|
|
create_topic_group(user, topic_id, post_number, updated_groups.map(&:group_id))
|
|
TopicTrackingState.publish_read_indicator_on_read(topic_id, post_number, user.id)
|
|
end
|
|
|
|
def self.new_message_update(user, topic_id, post_number)
|
|
updated_groups = update_read_count(user, topic_id, post_number)
|
|
create_topic_group(user, topic_id, post_number, updated_groups.map(&:group_id))
|
|
TopicTrackingState.publish_read_indicator_on_write(topic_id, post_number, user.id)
|
|
end
|
|
|
|
def self.update_read_count(user, topic_id, post_number)
|
|
update_query = <<~SQL
|
|
UPDATE topic_groups tg
|
|
SET
|
|
last_read_post_number = GREATEST(:post_number, tg.last_read_post_number),
|
|
updated_at = :now
|
|
FROM topic_allowed_groups tag
|
|
INNER JOIN group_users gu ON gu.group_id = tag.group_id
|
|
WHERE gu.user_id = :user_id
|
|
AND tag.topic_id = :topic_id
|
|
AND tg.topic_id = :topic_id
|
|
RETURNING
|
|
tg.group_id
|
|
SQL
|
|
|
|
updated_groups =
|
|
DB.query(
|
|
update_query,
|
|
user_id: user.id,
|
|
topic_id: topic_id,
|
|
post_number: post_number,
|
|
now: DateTime.now,
|
|
)
|
|
end
|
|
|
|
def self.create_topic_group(user, topic_id, post_number, updated_group_ids)
|
|
query = <<~SQL
|
|
INSERT INTO topic_groups (topic_id, group_id, last_read_post_number, created_at, updated_at)
|
|
SELECT tag.topic_id, tag.group_id, :post_number, :now, :now
|
|
FROM topic_allowed_groups tag
|
|
INNER JOIN group_users gu ON gu.group_id = tag.group_id
|
|
WHERE gu.user_id = :user_id
|
|
AND tag.topic_id = :topic_id
|
|
SQL
|
|
|
|
query +=
|
|
"AND NOT(tag.group_id IN (:already_updated_groups))" unless updated_group_ids.length.zero?
|
|
|
|
query += <<~SQL
|
|
ON CONFLICT(topic_id, group_id)
|
|
DO UPDATE SET last_read_post_number = :post_number, created_at = :now, updated_at = :now
|
|
SQL
|
|
|
|
DB.exec(
|
|
query,
|
|
user_id: user.id,
|
|
topic_id: topic_id,
|
|
post_number: post_number,
|
|
now: DateTime.now,
|
|
already_updated_groups: updated_group_ids,
|
|
)
|
|
end
|
|
end
|
|
|
|
# == Schema Information
|
|
#
|
|
# Table name: topic_groups
|
|
#
|
|
# id :bigint not null, primary key
|
|
# group_id :integer not null
|
|
# topic_id :integer not null
|
|
# last_read_post_number :integer default(0), not null
|
|
# created_at :datetime not null
|
|
# updated_at :datetime not null
|
|
#
|
|
# Indexes
|
|
#
|
|
# index_topic_groups_on_group_id_and_topic_id (group_id,topic_id) UNIQUE
|
|
#
|