2017-05-26 03:07:12 +08:00
|
|
|
class AddUnreadTrackingColumns < ActiveRecord::Migration
|
|
|
|
def up
|
|
|
|
add_column :user_stats, :first_topic_unread_at, :datetime, null: false, default: "epoch"
|
|
|
|
add_column :topics, :last_unread_at, :datetime, null: false, default: "epoch"
|
|
|
|
|
|
|
|
execute <<SQL
|
2017-05-26 06:50:51 +08:00
|
|
|
UPDATE topics SET last_unread_at = COALESCE((
|
2017-05-26 03:07:12 +08:00
|
|
|
SELECT MAX(created_at)
|
|
|
|
FROM posts
|
|
|
|
WHERE topics.id = posts.topic_id
|
2017-05-26 06:50:51 +08:00
|
|
|
), current_timestamp)
|
2017-05-26 03:07:12 +08:00
|
|
|
SQL
|
|
|
|
|
|
|
|
execute <<SQL
|
|
|
|
UPDATE user_stats SET first_topic_unread_at = COALESCE((
|
|
|
|
SELECT MIN(last_unread_at) FROM topics
|
|
|
|
JOIN users u ON u.id = user_stats.user_id
|
|
|
|
JOIN topic_users tu ON tu.user_id = user_stats.user_id AND topics.id = tu.topic_id
|
|
|
|
WHERE notification_level > 1 AND last_read_post_number < CASE WHEN moderator OR admin
|
|
|
|
THEN topics.highest_staff_post_number
|
|
|
|
ELSE topics.highest_post_number
|
|
|
|
END
|
2017-05-26 06:40:32 +08:00
|
|
|
AND topics.deleted_at IS NULL
|
|
|
|
), current_timestamp)
|
2017-05-26 03:07:12 +08:00
|
|
|
SQL
|
|
|
|
|
|
|
|
add_index :topics, [:last_unread_at]
|
|
|
|
|
|
|
|
# we need this function for performance reasons
|
|
|
|
execute <<SQL
|
2017-05-26 06:12:45 +08:00
|
|
|
CREATE OR REPLACE FUNCTION first_unread_topic_for(user_id int)
|
2017-05-26 03:07:12 +08:00
|
|
|
RETURNS timestamp AS
|
|
|
|
$$
|
|
|
|
SELECT COALESCE(first_topic_unread_at, 'epoch'::timestamp)
|
|
|
|
FROM users u
|
|
|
|
JOIN user_stats ON user_id = u.id
|
|
|
|
WHERE u.id = $1
|
|
|
|
$$
|
|
|
|
LANGUAGE SQL STABLE
|
|
|
|
SQL
|
|
|
|
end
|
|
|
|
|
|
|
|
def down
|
|
|
|
execute "DROP FUNCTION first_unread_topic_for(int)"
|
|
|
|
remove_column :user_stats, :first_topic_unread_at
|
|
|
|
remove_column :topics, :last_unread_at
|
|
|
|
end
|
|
|
|
end
|