chore: refresh gramsrv public release

This commit is contained in:
A 2026-06-30 14:37:43 +08:00
parent 75cebe8dbf
commit 70b6820474
1274 changed files with 378751 additions and 59919 deletions

View file

@ -12,6 +12,9 @@ WITH base AS (
d.unread_count,
d.unread_mentions_count,
d.unread_reactions_count,
d.ttl_period,
d.theme_emoticon,
d.has_scheduled,
d.pinned,
d.pinned_order,
d.unread_mark,
@ -25,25 +28,64 @@ WITH base AS (
COALESCE(u.country_code, '')::text AS peer_country_code,
COALESCE(u.verified, false)::boolean AS peer_verified,
COALESCE(u.support, false)::boolean AS peer_support,
COALESCE(u.is_bot, false)::boolean AS peer_is_bot,
COALESCE(u.bot_info_version, 0)::int AS peer_bot_info_version,
COALESCE(EXTRACT(EPOCH FROM u.premium_expires_at), 0)::bigint AS peer_premium_until,
COALESCE(u.emoji_status_document_id, 0)::bigint AS peer_emoji_status_document_id,
COALESCE(u.emoji_status_until, 0)::bigint AS peer_emoji_status_until,
COALESCE(u.last_seen_at, 0)::bigint AS peer_last_seen_at,
(c.contact_user_id IS NOT NULL)::boolean AS peer_contact,
COALESCE(c.mutual, false)::boolean AS peer_mutual,
COALESCE(m.box_id, 0)::int AS message_id,
COALESCE(m.private_message_id, 0)::bigint AS message_private_message_id,
COALESCE(m.from_user_id, 0)::bigint AS message_from_user_id,
COALESCE(m.message_date, 0)::int AS message_date,
COALESCE(m.outgoing, false)::boolean AS message_outgoing,
COALESCE(m.body, '')::text AS message_body,
COALESCE(m.entities::text, '[]')::text AS message_entities_json,
COALESCE(m.media::text, '{}')::text AS message_media_json
COALESCE(m.media::text, '{}')::text AS message_media_json,
COALESCE(m.ttl_period, 0)::int AS message_ttl_period,
COALESCE(m.expires_at, 0)::int AS message_expires_at,
COALESCE(m.edit_date, 0)::int AS message_edit_date,
COALESCE(m.silent, false)::boolean AS message_silent,
COALESCE(m.noforwards, false)::boolean AS message_noforwards,
COALESCE(m.reply_to_msg_id, 0)::int AS message_reply_to_msg_id,
COALESCE(m.reply_to_peer_type, '')::text AS message_reply_to_peer_type,
COALESCE(m.reply_to_peer_id, 0)::bigint AS message_reply_to_peer_id,
COALESCE(m.reply_to_top_id, 0)::int AS message_reply_to_top_id,
COALESCE(m.reply_to_story_id, 0)::int AS message_reply_to_story_id,
COALESCE(m.quote_text, '')::text AS message_quote_text,
COALESCE(m.quote_entities::text, '[]')::text AS message_quote_entities_json,
COALESCE(m.quote_offset, 0)::int AS message_quote_offset,
COALESCE(m.fwd_from_peer_type, '')::text AS message_fwd_from_peer_type,
COALESCE(m.fwd_from_peer_id, 0)::bigint AS message_fwd_from_peer_id,
COALESCE(m.fwd_from_name, '')::text AS message_fwd_from_name,
COALESCE(m.fwd_date, 0)::int AS message_fwd_date,
COALESCE(m.fwd_saved_from_peer_type, '')::text AS message_fwd_saved_from_peer_type,
COALESCE(m.fwd_saved_from_peer_id, 0)::bigint AS message_fwd_saved_from_peer_id,
COALESCE(m.fwd_saved_from_msg_id, 0)::int AS message_fwd_saved_from_msg_id,
COALESCE(m.saved_peer_type, '')::text AS message_saved_peer_type,
COALESCE(m.saved_peer_id, 0)::bigint AS message_saved_peer_id,
COALESCE(m.media_unread, false)::boolean AS message_media_unread,
COALESCE(m.reaction_unread, false)::boolean AS message_reaction_unread,
COALESCE(m.via_bot_id, 0)::bigint AS message_via_bot_id,
COALESCE(m.grouped_id, 0)::bigint AS message_grouped_id,
COALESCE(m.effect, 0)::bigint AS message_effect,
COALESCE(m.reply_markup::text, '{}')::text AS message_reply_markup_json,
COALESCE(m.rich_message::text, '{}')::text AS message_rich_message_json,
COALESCE(m.pinned, false)::boolean AS message_pinned
FROM dialogs d
LEFT JOIN users u ON d.peer_type = 'user' AND u.id = d.peer_id
LEFT JOIN contacts c ON d.peer_type = 'user' AND c.user_id = d.user_id AND c.contact_user_id = d.peer_id
LEFT JOIN message_boxes m ON m.owner_user_id = d.user_id AND m.box_id = d.top_message_id AND NOT m.deleted
WHERE d.user_id = $1
AND (
NOT sqlc.arg(has_folder_id)::boolean
-- 不带 folder_id flag 视为主列表folder 0官方语义下归档对话只以
-- dialogFolder 聚合条目出现在主列表DrKLO Android 主列表请求不设 flag。
(NOT sqlc.arg(has_folder_id)::boolean AND d.folder_id = 0)
OR (
sqlc.arg(folder_id)::int < 2
sqlc.arg(has_folder_id)::boolean
AND sqlc.arg(folder_id)::int < 2
AND d.folder_id = sqlc.arg(folder_id)::int
)
OR (
@ -135,6 +177,9 @@ SELECT
unread_count,
unread_mentions_count,
unread_reactions_count,
ttl_period,
theme_emoticon,
has_scheduled,
pinned,
pinned_order,
unread_mark,
@ -148,20 +193,56 @@ SELECT
peer_country_code,
peer_verified,
peer_support,
peer_is_bot,
peer_bot_info_version,
peer_premium_until,
peer_emoji_status_document_id,
peer_emoji_status_until,
peer_last_seen_at,
peer_contact,
peer_mutual,
message_id,
message_private_message_id,
message_from_user_id,
message_date,
message_outgoing,
message_body,
message_entities_json,
message_media_json
message_media_json,
message_ttl_period,
message_expires_at,
message_edit_date,
message_silent,
message_noforwards,
message_reply_to_msg_id,
message_reply_to_peer_type,
message_reply_to_peer_id,
message_reply_to_top_id,
message_reply_to_story_id,
message_quote_text,
message_quote_entities_json,
message_quote_offset,
message_fwd_from_peer_type,
message_fwd_from_peer_id,
message_fwd_from_name,
message_fwd_date,
message_fwd_saved_from_peer_type,
message_fwd_saved_from_peer_id,
message_fwd_saved_from_msg_id,
message_saved_peer_type,
message_saved_peer_id,
message_media_unread,
message_reaction_unread,
message_via_bot_id,
message_grouped_id,
message_effect,
message_reply_markup_json,
message_rich_message_json,
message_pinned
FROM paged
ORDER BY
pinned DESC,
CASE WHEN pinned THEN COALESCE(NULLIF(pinned_order, 0), 2147483647) ELSE 2147483647 END ASC,
CASE WHEN pinned THEN COALESCE(pinned_order, 0) ELSE 0 END DESC,
top_message_date DESC,
top_message_id DESC,
peer_id DESC
@ -179,6 +260,9 @@ SELECT
d.unread_count,
d.unread_mentions_count,
d.unread_reactions_count,
d.ttl_period,
d.theme_emoticon,
d.has_scheduled,
d.pinned,
d.pinned_order,
d.unread_mark,
@ -187,9 +271,10 @@ FROM dialogs d
LEFT JOIN contacts c ON d.peer_type = 'user' AND c.user_id = d.user_id AND c.contact_user_id = d.peer_id
WHERE d.user_id = $1
AND (
NOT sqlc.arg(has_folder_id)::boolean
(NOT sqlc.arg(has_folder_id)::boolean AND d.folder_id = 0)
OR (
sqlc.arg(folder_id)::int < 2
sqlc.arg(has_folder_id)::boolean
AND sqlc.arg(folder_id)::int < 2
AND d.folder_id = sqlc.arg(folder_id)::int
)
OR (
@ -233,7 +318,7 @@ WHERE d.user_id = $1
AND (NOT sqlc.arg(exclude_pinned)::boolean OR NOT d.pinned)
ORDER BY
d.pinned DESC,
CASE WHEN d.pinned THEN COALESCE(NULLIF(d.pinned_order, 0), 2147483647) ELSE 2147483647 END ASC,
CASE WHEN d.pinned THEN COALESCE(d.pinned_order, 0) ELSE 0 END DESC,
d.top_message_date DESC,
d.top_message_id DESC,
d.peer_id DESC;
@ -268,6 +353,9 @@ base AS (
COALESCE(d.unread_count, 0)::int AS unread_count,
COALESCE(d.unread_mentions_count, 0)::int AS unread_mentions_count,
COALESCE(d.unread_reactions_count, 0)::int AS unread_reactions_count,
COALESCE(d.ttl_period, 0)::int AS ttl_period,
COALESCE(d.theme_emoticon, '')::text AS theme_emoticon,
COALESCE(d.has_scheduled, false)::boolean AS has_scheduled,
COALESCE(d.pinned, false)::boolean AS pinned,
COALESCE(d.pinned_order, 0)::int AS pinned_order,
COALESCE(d.unread_mark, false)::boolean AS unread_mark,
@ -281,16 +369,52 @@ base AS (
COALESCE(u.country_code, '')::text AS peer_country_code,
COALESCE(u.verified, false)::boolean AS peer_verified,
COALESCE(u.support, false)::boolean AS peer_support,
COALESCE(u.is_bot, false)::boolean AS peer_is_bot,
COALESCE(u.bot_info_version, 0)::int AS peer_bot_info_version,
COALESCE(EXTRACT(EPOCH FROM u.premium_expires_at), 0)::bigint AS peer_premium_until,
COALESCE(u.emoji_status_document_id, 0)::bigint AS peer_emoji_status_document_id,
COALESCE(u.emoji_status_until, 0)::bigint AS peer_emoji_status_until,
COALESCE(u.last_seen_at, 0)::bigint AS peer_last_seen_at,
(c.contact_user_id IS NOT NULL)::boolean AS peer_contact,
COALESCE(c.mutual, false)::boolean AS peer_mutual,
COALESCE(m.box_id, 0)::int AS message_id,
COALESCE(m.private_message_id, 0)::bigint AS message_private_message_id,
COALESCE(m.from_user_id, 0)::bigint AS message_from_user_id,
COALESCE(m.message_date, 0)::int AS message_date,
COALESCE(m.outgoing, false)::boolean AS message_outgoing,
COALESCE(m.body, '')::text AS message_body,
COALESCE(m.entities::text, '[]')::text AS message_entities_json,
COALESCE(m.media::text, '{}')::text AS message_media_json,
COALESCE(m.ttl_period, 0)::int AS message_ttl_period,
COALESCE(m.expires_at, 0)::int AS message_expires_at,
COALESCE(m.edit_date, 0)::int AS message_edit_date,
COALESCE(m.silent, false)::boolean AS message_silent,
COALESCE(m.noforwards, false)::boolean AS message_noforwards,
COALESCE(m.reply_to_msg_id, 0)::int AS message_reply_to_msg_id,
COALESCE(m.reply_to_peer_type, '')::text AS message_reply_to_peer_type,
COALESCE(m.reply_to_peer_id, 0)::bigint AS message_reply_to_peer_id,
COALESCE(m.reply_to_top_id, 0)::int AS message_reply_to_top_id,
COALESCE(m.reply_to_story_id, 0)::int AS message_reply_to_story_id,
COALESCE(m.quote_text, '')::text AS message_quote_text,
COALESCE(m.quote_entities::text, '[]')::text AS message_quote_entities_json,
COALESCE(m.quote_offset, 0)::int AS message_quote_offset,
COALESCE(m.fwd_from_peer_type, '')::text AS message_fwd_from_peer_type,
COALESCE(m.fwd_from_peer_id, 0)::bigint AS message_fwd_from_peer_id,
COALESCE(m.fwd_from_name, '')::text AS message_fwd_from_name,
COALESCE(m.fwd_date, 0)::int AS message_fwd_date,
COALESCE(m.fwd_saved_from_peer_type, '')::text AS message_fwd_saved_from_peer_type,
COALESCE(m.fwd_saved_from_peer_id, 0)::bigint AS message_fwd_saved_from_peer_id,
COALESCE(m.fwd_saved_from_msg_id, 0)::int AS message_fwd_saved_from_msg_id,
COALESCE(m.saved_peer_type, '')::text AS message_saved_peer_type,
COALESCE(m.saved_peer_id, 0)::bigint AS message_saved_peer_id,
COALESCE(m.media_unread, false)::boolean AS message_media_unread,
COALESCE(m.reaction_unread, false)::boolean AS message_reaction_unread,
COALESCE(m.via_bot_id, 0)::bigint AS message_via_bot_id,
COALESCE(m.grouped_id, 0)::bigint AS message_grouped_id,
COALESCE(m.effect, 0)::bigint AS message_effect,
COALESCE(m.reply_markup::text, '{}')::text AS message_reply_markup_json,
COALESCE(m.rich_message::text, '{}')::text AS message_rich_message_json,
COALESCE(m.pinned, false)::boolean AS message_pinned,
r.ord
FROM deduped r
LEFT JOIN dialogs d
@ -313,6 +437,9 @@ SELECT
unread_count,
unread_mentions_count,
unread_reactions_count,
ttl_period,
theme_emoticon,
has_scheduled,
pinned,
pinned_order,
unread_mark,
@ -326,16 +453,52 @@ SELECT
peer_country_code,
peer_verified,
peer_support,
peer_is_bot,
peer_bot_info_version,
peer_premium_until,
peer_emoji_status_document_id,
peer_emoji_status_until,
peer_last_seen_at,
peer_contact,
peer_mutual,
message_id,
message_private_message_id,
message_from_user_id,
message_date,
message_outgoing,
message_body,
message_entities_json,
message_media_json
message_media_json,
message_ttl_period,
message_expires_at,
message_edit_date,
message_silent,
message_noforwards,
message_reply_to_msg_id,
message_reply_to_peer_type,
message_reply_to_peer_id,
message_reply_to_top_id,
message_reply_to_story_id,
message_quote_text,
message_quote_entities_json,
message_quote_offset,
message_fwd_from_peer_type,
message_fwd_from_peer_id,
message_fwd_from_name,
message_fwd_date,
message_fwd_saved_from_peer_type,
message_fwd_saved_from_peer_id,
message_fwd_saved_from_msg_id,
message_saved_peer_type,
message_saved_peer_id,
message_media_unread,
message_reaction_unread,
message_via_bot_id,
message_grouped_id,
message_effect,
message_reply_markup_json,
message_rich_message_json,
message_pinned
FROM base
ORDER BY ord;
@ -369,6 +532,8 @@ ON CONFLICT (user_id, peer_type, peer_id) DO UPDATE SET
updated_at = now();
-- name: UpsertOutboxDialog :exec
-- 发送方向该会话发出消息即视为已知晓内容:清除手动未读标记,
-- 与 channel 发送路径、readHistory 清除语义对齐。
INSERT INTO dialogs (
user_id,
peer_type,
@ -382,6 +547,7 @@ INSERT INTO dialogs (
ON CONFLICT (user_id, peer_type, peer_id) DO UPDATE SET
top_message_id = EXCLUDED.top_message_id,
top_message_date = EXCLUDED.top_message_date,
unread_mark = false,
updated_at = now();
-- name: UpsertInboxDialog :exec
@ -396,9 +562,22 @@ INSERT INTO dialogs (
$1, $2, $3, $4, $5, 1
)
ON CONFLICT (user_id, peer_type, peer_id) DO UPDATE SET
top_message_id = EXCLUDED.top_message_id,
top_message_date = EXCLUDED.top_message_date,
unread_count = dialogs.unread_count + 1,
top_message_id = GREATEST(dialogs.top_message_id, EXCLUDED.top_message_id),
top_message_date = CASE
WHEN EXCLUDED.top_message_id >= dialogs.top_message_id THEN EXCLUDED.top_message_date
ELSE dialogs.top_message_date
END,
unread_count = (
SELECT COUNT(*)::int
FROM message_boxes m
WHERE m.owner_user_id = dialogs.user_id
AND m.peer_type = dialogs.peer_type
AND m.peer_id = dialogs.peer_id
AND NOT m.deleted
AND NOT m.outgoing
AND m.box_id > dialogs.read_inbox_max_id
AND m.box_id <= GREATEST(dialogs.top_message_id, EXCLUDED.top_message_id)
),
updated_at = now();
-- name: MarkDialogRead :one
@ -409,7 +588,11 @@ WITH target AS (
d.peer_id,
d.top_message_id,
d.read_inbox_max_id,
d.unread_count
d.unread_count,
LEAST(
d.top_message_id,
CASE WHEN sqlc.arg(max_id)::int > 0 THEN sqlc.arg(max_id)::int ELSE d.top_message_id END
)::int AS requested_read_max_id
FROM dialogs d
WHERE d.user_id = $1
AND d.peer_type = $2
@ -418,14 +601,19 @@ WITH target AS (
updated AS (
UPDATE dialogs d
SET
read_inbox_max_id = GREATEST(
d.read_inbox_max_id,
CASE WHEN sqlc.arg(max_id)::int > 0 THEN sqlc.arg(max_id)::int ELSE d.top_message_id END
read_inbox_max_id = GREATEST(d.read_inbox_max_id, target.requested_read_max_id),
unread_count = (
SELECT count(*)::int
FROM message_boxes m
WHERE m.owner_user_id = d.user_id
AND m.peer_type = d.peer_type
AND m.peer_id = d.peer_id
AND NOT m.deleted
AND NOT m.outgoing
AND m.box_id > GREATEST(d.read_inbox_max_id, target.requested_read_max_id)
),
unread_count = 0,
unread_mark = false,
unread_mentions_count = 0,
unread_reactions_count = 0,
updated_at = now()
FROM target
WHERE d.user_id = target.user_id
@ -439,9 +627,7 @@ RETURNING
d.unread_count,
(
target.unread_count > 0
OR (
CASE WHEN sqlc.arg(max_id)::int > 0 THEN sqlc.arg(max_id)::int ELSE target.top_message_id END
) > target.read_inbox_max_id
OR target.requested_read_max_id > target.read_inbox_max_id
)::boolean AS changed
)
SELECT
@ -454,11 +640,34 @@ SELECT
FROM updated;
-- name: SetDialogPinned :one
WITH next_order AS (
SELECT COALESCE(MAX(pinned_order), 0)::int + 1 AS value
FROM dialogs
WHERE user_id = sqlc.arg(user_id)::bigint
AND pinned
-- 置顶顺序在 dialog 当前 folder0 主列表/1 归档)内独立分配,
-- 返回 folder_id 供 updateDialogPinned.folder_id 使用。
WITH target AS (
SELECT d.folder_id
FROM dialogs d
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = sqlc.arg(peer_type)::text
AND d.peer_id = sqlc.arg(peer_id)::bigint
),
next_order AS (
-- order 空间跨 dialogs/channel_dialogs 两表统一(合并层按 pinned_order
-- 全局排序),但仅在目标会话所在 folder 内取最大值。
SELECT GREATEST(
COALESCE((
SELECT MAX(d.pinned_order)
FROM dialogs d, target t
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.pinned
AND d.folder_id = t.folder_id
), 0),
COALESCE((
SELECT MAX(cd.pinned_order)
FROM channel_dialogs cd, target t
WHERE cd.user_id = sqlc.arg(user_id)::bigint
AND cd.pinned
AND COALESCE(cd.folder_id, 0) = t.folder_id
), 0)
)::int + 1 AS value
),
updated AS (
UPDATE dialogs d
@ -473,11 +682,15 @@ updated AS (
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = sqlc.arg(peer_type)::text
AND d.peer_id = sqlc.arg(peer_id)::bigint
RETURNING d.user_id
RETURNING d.folder_id
)
SELECT EXISTS (SELECT 1 FROM updated)::boolean AS changed;
SELECT
EXISTS (SELECT 1 FROM updated)::boolean AS changed,
COALESCE((SELECT folder_id FROM updated), 0)::int AS folder_id;
-- name: SetDialogUnreadMark :one
-- 值守卫 IS DISTINCT FROM重复标记同一值不应算 changed否则上层会记一条
-- 幽灵 durable 未读标事件并多推一次 update对齐频道侧 SetChannelDialogUnreadMark
WITH updated AS (
UPDATE dialogs d
SET unread_mark = sqlc.arg(unread)::boolean,
@ -485,6 +698,7 @@ WITH updated AS (
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = sqlc.arg(peer_type)::text
AND d.peer_id = sqlc.arg(peer_id)::bigint
AND d.unread_mark IS DISTINCT FROM sqlc.arg(unread)::boolean
RETURNING d.user_id
)
SELECT EXISTS (SELECT 1 FROM updated)::boolean AS changed;
@ -527,10 +741,12 @@ WITH requested AS (
WHERE i <= cardinality(sqlc.arg(peer_types)::text[])
),
deduped AS (
-- 请求数组首位是置顶区最顶部;统一编码为"值越大越靠前",与频道
-- reorder、toggle 的 MAX+1 分配以及合并层排序方向一致。
SELECT DISTINCT ON (peer_type, peer_id)
peer_type,
peer_id,
pos::int AS ord
(cardinality(sqlc.arg(peer_ids)::bigint[]) - pos + 1)::int AS ord
FROM requested
ORDER BY peer_type, peer_id, pos
)
@ -541,7 +757,8 @@ SET pinned = true,
FROM deduped
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = deduped.peer_type
AND d.peer_id = deduped.peer_id;
AND d.peer_id = deduped.peer_id
AND d.folder_id = sqlc.arg(folder_id)::int;
-- name: EditDialogPeerFolders :exec
WITH requested AS (
@ -563,13 +780,50 @@ deduped AS (
ORDER BY peer_type, peer_id
)
UPDATE dialogs d
-- 换 folder 时清 pinnedTDesktop History::setFolderPointer 在归档/还原时
-- 本地无条件 unpin服务端保留旧 pin 会在下次 getDialogs 时把状态漂移回来。
SET folder_id = deduped.folder_id,
pinned = CASE WHEN d.folder_id <> deduped.folder_id THEN false ELSE d.pinned END,
pinned_order = CASE WHEN d.folder_id <> deduped.folder_id THEN 0 ELSE d.pinned_order END,
updated_at = now()
FROM deduped
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = deduped.peer_type
AND d.peer_id = deduped.peer_id;
-- name: SetDialogArchivePinned :one
-- archive folder 行本身的置顶状态toggleDialogPin(inputDialogPeerFolder))。
-- 无行时官方默认视为 pinned=true所以这里总是落一行显式值。
WITH current AS (
SELECT archive_pinned
FROM dialog_filter_settings
WHERE user_id = sqlc.arg(user_id)::bigint
),
upserted AS (
INSERT INTO dialog_filter_settings (user_id, archive_pinned)
VALUES (sqlc.arg(user_id)::bigint, sqlc.arg(pinned)::boolean)
ON CONFLICT (user_id) DO UPDATE SET
archive_pinned = EXCLUDED.archive_pinned,
updated_at = now()
RETURNING archive_pinned
)
SELECT (COALESCE((SELECT archive_pinned FROM current), true) IS DISTINCT FROM sqlc.arg(pinned)::boolean)::boolean AS changed
FROM upserted;
-- name: GetDialogArchivePinned :one
SELECT archive_pinned
FROM dialog_filter_settings
WHERE user_id = $1;
-- name: CountArchiveUnreadDialogs :one
-- 归档folder_id=1未读聚合有未读或手动标记未读的会话数 + 未读消息总数。
SELECT
COUNT(*) FILTER (WHERE unread_count > 0 OR unread_mark)::int AS unread_peers,
COALESCE(SUM(unread_count), 0)::int AS unread_messages
FROM dialogs
WHERE user_id = $1
AND folder_id = 1;
-- name: ClearPinnedDialogsNotInOrder :exec
WITH requested AS (
SELECT
@ -584,6 +838,7 @@ SET pinned = false,
updated_at = now()
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.pinned
AND d.folder_id = sqlc.arg(folder_id)::int
AND NOT EXISTS (
SELECT 1
FROM requested r
@ -607,7 +862,15 @@ SET
AND m.box_id > d.read_inbox_max_id
),
unread_mentions_count = 0,
unread_reactions_count = 0,
unread_reactions_count = (
SELECT COUNT(*)::int
FROM message_boxes m2
WHERE m2.owner_user_id = d.user_id
AND m2.peer_type = d.peer_type
AND m2.peer_id = d.peer_id
AND NOT m2.deleted
AND m2.reaction_unread
),
updated_at = now()
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = sqlc.arg(peer_type)::text
@ -623,17 +886,32 @@ SET
unread_count = 0,
unread_mark = false,
unread_mentions_count = 0,
unread_reactions_count = 0,
unread_reactions_count = (
SELECT COUNT(*)::int
FROM message_boxes m2
WHERE m2.owner_user_id = d.user_id
AND m2.peer_type = d.peer_type
AND m2.peer_id = d.peer_id
AND NOT m2.deleted
AND m2.reaction_unread
),
updated_at = now()
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = sqlc.arg(peer_type)::text
AND d.peer_id = sqlc.arg(peer_id)::bigint;
-- name: DeleteDialogByPeer :exec
DELETE FROM dialogs
WHERE user_id = $1
AND peer_type = $2
AND peer_id = $3;
WITH dropped_drafts AS (
-- 删除会话同时丢弃该 peer 的云草稿,避免对端重建会话后旧草稿复活。
DELETE FROM dialog_drafts dd
WHERE dd.user_id = sqlc.arg(user_id)::bigint
AND dd.peer_type = sqlc.arg(peer_type)::text
AND dd.peer_id = sqlc.arg(peer_id)::bigint
)
DELETE FROM dialogs d
WHERE d.user_id = sqlc.arg(user_id)::bigint
AND d.peer_type = sqlc.arg(peer_type)::text
AND d.peer_id = sqlc.arg(peer_id)::bigint;
-- name: ListDialogFolders :many
SELECT
@ -775,3 +1053,11 @@ deleted AS (
)
SELECT draft_json
FROM deleted;
-- name: AdvanceDialogReadInboxFloor :exec
UPDATE dialogs
SET read_inbox_max_id = GREATEST(read_inbox_max_id, @read_inbox_max_id::int),
updated_at = now()
WHERE user_id = @user_id
AND peer_type = @peer_type
AND peer_id = @peer_id;