feat: sync GIFv and saved GIF support

This commit is contained in:
A 2026-07-11 21:43:13 +08:00
parent c0088f1160
commit 5f7c0b9804
21 changed files with 641 additions and 50 deletions

View file

@ -540,17 +540,19 @@ func (s *PasswordStore) SaveStickerCollectionItem(ctx context.Context, userID in
if _, err := tx.Exec(ctx, `
INSERT INTO user_sticker_collections (owner_user_id, kind, document_id, used_at)
VALUES ($1, $2, $3, $4)
ON CONFLICT (owner_user_id, kind, document_id) DO UPDATE SET used_at = EXCLUDED.used_at`,
ON CONFLICT (owner_user_id, kind, document_id) DO UPDATE
SET used_at = EXCLUDED.used_at,
order_key = nextval('user_sticker_collections_order_key_seq')`,
userID, string(kind), documentID, now); err != nil {
return fmt.Errorf("upsert sticker collection item: %w", err)
}
// 截断超上界:单次有序窗口扫描(索引 user_sticker_collections_order_idx 服务
// used_at DESC 排序),按 ctid 删除排名 > max 的旧项,避免 NOT IN 双扫全集。
// order_key DESC 排序),按 ctid 删除排名 > max 的旧项,避免 NOT IN 双扫全集。
if _, err := tx.Exec(ctx, `
DELETE FROM user_sticker_collections
WHERE ctid IN (
SELECT ctid FROM (
SELECT ctid, ROW_NUMBER() OVER (ORDER BY used_at DESC, document_id DESC) AS rn
SELECT ctid, ROW_NUMBER() OVER (ORDER BY order_key DESC) AS rn
FROM user_sticker_collections
WHERE owner_user_id = $1 AND kind = $2
) t WHERE rn > $3
@ -572,7 +574,7 @@ func (s *PasswordStore) ListStickerCollection(ctx context.Context, userID int64,
SELECT document_id, used_at
FROM user_sticker_collections
WHERE owner_user_id = $1 AND kind = $2
ORDER BY used_at DESC, document_id DESC
ORDER BY order_key DESC
LIMIT $3`, userID, string(kind), limit)
if err != nil {
return nil, fmt.Errorf("list sticker collection: %w", err)

View file

@ -38,6 +38,17 @@ func TestStickerCollectionsRoundTripPostgres(t *testing.T) {
t.Fatalf("faved after re-fave = %v, want 101 first", ids)
}
// used_at 只有秒精度:同秒保存仍必须严格按最后一次 mutation 排序。
if err := store.SaveStickerCollectionItem(ctx, owner, faved, 102, false, 3000, 100); err != nil {
t.Fatalf("same-second fave 102: %v", err)
}
if err := store.SaveStickerCollectionItem(ctx, owner, faved, 101, false, 3000, 100); err != nil {
t.Fatalf("same-second re-fave 101: %v", err)
}
if ids := stickerIDs(t, store, ctx, owner, faved); len(ids) != 2 || ids[0] != 101 || ids[1] != 102 {
t.Fatalf("same-second order = %v, want [101 102]", ids)
}
// 截断max=2加第 3 个挤掉最旧。
if err := store.SaveStickerCollectionItem(ctx, owner, faved, 103, false, 1003, 2); err != nil {
t.Fatalf("fave 103 (max 2): %v", err)