// Code generated by sqlc. DO NOT EDIT. // versions: // sqlc v1.31.1 // source: message.sql package sqlcgen import ( "context" ) const countMessagesByUser = `-- name: CountMessagesByUser :one SELECT count(*)::int AS total_count FROM message_boxes m WHERE m.owner_user_id = $1::bigint AND NOT m.deleted AND ($2::bigint = 0 OR m.from_user_id = $2::bigint) AND ( NOT $3::boolean OR (m.peer_type = $4::text AND m.peer_id = $5::bigint) ) AND ( NOT $6::boolean OR (m.peer_type = 'user' AND m.peer_id = ANY($7::bigint[])) ) AND ( $8::text = '' OR m.body ILIKE ('%' || $8::text || '%') ) AND ($9::int <= 0 OR m.message_date > $9::int) AND ($10::int <= 0 OR m.message_date < $10::int) AND ($11::int <= 0 OR m.box_id < $11::int) AND ($12::int <= 0 OR m.box_id > $12::int) AND (NOT $13::boolean OR m.pinned) AND ( NOT $14::boolean OR ( m.media->>'kind' = 'document' AND EXISTS ( SELECT 1 FROM jsonb_array_elements(COALESCE(m.media #> '{document,attributes}', '[]'::jsonb)) AS attr WHERE attr->>'kind' = 'audio' AND COALESCE((attr->>'voice')::boolean, false) = false ) ) ) AND ( NOT $15::boolean OR m.media #>> '{service_action,kind}' = 'phone_call' ) AND ( NOT $16::boolean OR ( NOT m.outgoing AND m.media #>> '{service_action,kind}' = 'phone_call' AND m.media #>> '{service_action,call,reason}' = 'missed' ) ) AND ( $17::text = '' OR (m.saved_peer_type = $17::text AND m.saved_peer_id = $18::bigint) ) AND ( cardinality($19::text[]) = 0 OR EXISTS ( SELECT 1 FROM saved_message_reaction_tags tag WHERE tag.user_id = m.owner_user_id AND tag.message_box_id = m.box_id AND (tag.reaction_type || ':' || tag.reaction_value) = ANY($19::text[]) ) ) ` type CountMessagesByUserParams struct { OwnerUserID int64 SenderUserID int64 HasPeer bool PeerType string PeerID int64 RestrictPeerIds bool PeerIds []int64 Query string MinDate int32 MaxDate int32 MaxID int32 MinID int32 PinnedOnly bool MusicOnly bool PhoneCallsOnly bool MissedPhoneCallsOnly bool SavedPeerType string SavedPeerID int64 SavedReactionKeys []string } // ListMessagesByUser total CTE 的独立化:相同 base 过滤(不含分页 anchor), // 仅 NeedTotalCount 时发,避免热路径(getHistory 恒不需 total)次次规划 count 子树。 func (q *Queries) CountMessagesByUser(ctx context.Context, arg CountMessagesByUserParams) (int32, error) { row := q.db.QueryRow(ctx, countMessagesByUser, arg.OwnerUserID, arg.SenderUserID, arg.HasPeer, arg.PeerType, arg.PeerID, arg.RestrictPeerIds, arg.PeerIds, arg.Query, arg.MinDate, arg.MaxDate, arg.MaxID, arg.MinID, arg.PinnedOnly, arg.MusicOnly, arg.PhoneCallsOnly, arg.MissedPhoneCallsOnly, arg.SavedPeerType, arg.SavedPeerID, arg.SavedReactionKeys, ) var total_count int32 err := row.Scan(&total_count) return total_count, err } const createMessage = `-- name: CreateMessage :one WITH pm AS ( INSERT INTO private_messages ( sender_user_id, recipient_user_id, random_id, request_fingerprint, recipient_delivered, sender_box_id, sender_pts, recipient_box_id, recipient_pts, message_date, body, entities ) VALUES ( $1, $2, 0, '\x'::bytea, false, 0, 0, 0, 0, $3, $4, $5::jsonb ) RETURNING id, sender_user_id ), box AS ( INSERT INTO message_boxes ( owner_user_id, box_id, private_message_id, message_sender_id, peer_type, peer_id, from_user_id, message_date, outgoing, body, entities, pts ) SELECT $2, $6, pm.id, pm.sender_user_id, $7, $8, $1, $3, $9, $4, $5::jsonb, $10 FROM pm RETURNING box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, edit_date, hide_edited, outgoing, body, entities::text AS entities_json, pts ) SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, edit_date, hide_edited, outgoing, body, entities_json, pts FROM box ` type CreateMessageParams struct { FromUserID int64 OwnerUserID int64 MessageDate int32 Body string EntitiesJson []byte BoxID int32 PeerType string PeerID int64 Outgoing bool Pts int32 } type CreateMessageRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Pts int32 } func (q *Queries) CreateMessage(ctx context.Context, arg CreateMessageParams) (CreateMessageRow, error) { row := q.db.QueryRow(ctx, createMessage, arg.FromUserID, arg.OwnerUserID, arg.MessageDate, arg.Body, arg.EntitiesJson, arg.BoxID, arg.PeerType, arg.PeerID, arg.Outgoing, arg.Pts, ) var i CreateMessageRow err := row.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Pts, ) return i, err } const createMessageBox = `-- name: CreateMessageBox :one INSERT INTO message_boxes ( owner_user_id, box_id, private_message_id, message_sender_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, outgoing, body, entities, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities, quote_offset, reply_external, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media, media_unread, reaction_unread, reply_markup, rich_message, via_bot_id, grouped_id, effect ) VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $11::int, $12::int, $9, $10, $13::jsonb, $14::boolean, $15::boolean, $16::int, $17::text, $18::bigint, $19::int, $20::int, $21::text, $22::jsonb, $23::int, COALESCE($24::jsonb, '{}'::jsonb), $25::text, $26::bigint, $27::text, $28::int, $29::text, $30::bigint, $31::int, $32::text, $33::bigint, $34::int, $35::jsonb, $36::boolean, $37::boolean, $38::jsonb, $39::jsonb, $40::bigint, $41::bigint, $42::bigint ) RETURNING box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities::text AS entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities::text AS quote_entities_json, quote_offset, reply_external::text AS reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media::text AS media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup::text AS reply_markup_json, rich_message::text AS rich_message_json ` type CreateMessageBoxParams struct { OwnerUserID int64 BoxID int32 PrivateMessageID int64 MessageSenderID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 Outgoing bool Body string TtlPeriod int32 ExpiresAt int32 EntitiesJson []byte Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson []byte QuoteOffset int32 ReplyExternalJson []byte FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson []byte MediaUnread bool ReactionUnread bool ReplyMarkupJson []byte RichMessageJson []byte ViaBotID int64 GroupedID int64 Effect int64 } type CreateMessageBoxRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string } func (q *Queries) CreateMessageBox(ctx context.Context, arg CreateMessageBoxParams) (CreateMessageBoxRow, error) { row := q.db.QueryRow(ctx, createMessageBox, arg.OwnerUserID, arg.BoxID, arg.PrivateMessageID, arg.MessageSenderID, arg.PeerType, arg.PeerID, arg.FromUserID, arg.MessageDate, arg.Outgoing, arg.Body, arg.TtlPeriod, arg.ExpiresAt, arg.EntitiesJson, arg.Silent, arg.Noforwards, arg.ReplyToMsgID, arg.ReplyToPeerType, arg.ReplyToPeerID, arg.ReplyToTopID, arg.ReplyToStoryID, arg.QuoteText, arg.QuoteEntitiesJson, arg.QuoteOffset, arg.ReplyExternalJson, arg.FwdFromPeerType, arg.FwdFromPeerID, arg.FwdFromName, arg.FwdDate, arg.FwdSavedFromPeerType, arg.FwdSavedFromPeerID, arg.FwdSavedFromMsgID, arg.SavedPeerType, arg.SavedPeerID, arg.Pts, arg.MediaJson, arg.MediaUnread, arg.ReactionUnread, arg.ReplyMarkupJson, arg.RichMessageJson, arg.ViaBotID, arg.GroupedID, arg.Effect, ) var i CreateMessageBoxRow err := row.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, ) return i, err } const createPrivateMessage = `-- name: CreatePrivateMessage :one INSERT INTO private_messages ( sender_user_id, recipient_user_id, random_id, request_fingerprint, recipient_delivered, sender_box_id, sender_pts, recipient_box_id, recipient_pts, message_date, ttl_period, expires_at, body, entities, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities, quote_offset, reply_external, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, media, reply_markup, rich_message, via_bot_id, grouped_id, effect ) VALUES ( $1, $2, $3, $6::bytea, $7::boolean, 0, 0, 0, 0, $4, $8::int, $9::int, $5, $10::jsonb, $11::boolean, $12::boolean, $13::int, $14::text, $15::bigint, $16::int, $17::int, $18::text, $19::jsonb, $20::int, COALESCE($21::jsonb, '{}'::jsonb), $22::text, $23::bigint, $24::text, $25::int, $26::jsonb, $27::jsonb, $28::jsonb, $29::bigint, $30::bigint, $31::bigint ) ON CONFLICT (sender_user_id, random_id) WHERE random_id <> 0 DO NOTHING RETURNING id, sender_user_id, recipient_user_id, random_id, message_date, ttl_period, expires_at, edit_date, body, entities::text AS entities_json ` type CreatePrivateMessageParams struct { SenderUserID int64 RecipientUserID int64 RandomID int64 MessageDate int32 Body string RequestFingerprint []byte RecipientDelivered bool TtlPeriod int32 ExpiresAt int32 EntitiesJson []byte Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson []byte QuoteOffset int32 ReplyExternalJson []byte FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 MediaJson []byte ReplyMarkupJson []byte RichMessageJson []byte ViaBotID int64 GroupedID int64 Effect int64 } type CreatePrivateMessageRow struct { ID int64 SenderUserID int64 RecipientUserID int64 RandomID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 Body string EntitiesJson string } func (q *Queries) CreatePrivateMessage(ctx context.Context, arg CreatePrivateMessageParams) (CreatePrivateMessageRow, error) { row := q.db.QueryRow(ctx, createPrivateMessage, arg.SenderUserID, arg.RecipientUserID, arg.RandomID, arg.MessageDate, arg.Body, arg.RequestFingerprint, arg.RecipientDelivered, arg.TtlPeriod, arg.ExpiresAt, arg.EntitiesJson, arg.Silent, arg.Noforwards, arg.ReplyToMsgID, arg.ReplyToPeerType, arg.ReplyToPeerID, arg.ReplyToTopID, arg.ReplyToStoryID, arg.QuoteText, arg.QuoteEntitiesJson, arg.QuoteOffset, arg.ReplyExternalJson, arg.FwdFromPeerType, arg.FwdFromPeerID, arg.FwdFromName, arg.FwdDate, arg.MediaJson, arg.ReplyMarkupJson, arg.RichMessageJson, arg.ViaBotID, arg.GroupedID, arg.Effect, ) var i CreatePrivateMessageRow err := row.Scan( &i.ID, &i.SenderUserID, &i.RecipientUserID, &i.RandomID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.Body, &i.EntitiesJson, ) return i, err } const deleteMessageBoxesByIDs = `-- name: DeleteMessageBoxesByIDs :many WITH updated AS ( UPDATE message_boxes m SET deleted = true WHERE m.owner_user_id = $1::bigint AND m.box_id = ANY($2::int[]) AND NOT m.deleted RETURNING m.owner_user_id, m.box_id, m.private_message_id, m.message_sender_id, m.peer_type, m.peer_id ) SELECT owner_user_id, box_id, private_message_id, message_sender_id, peer_type, peer_id FROM updated ORDER BY box_id ASC ` type DeleteMessageBoxesByIDsParams struct { OwnerUserID int64 BoxIds []int32 } type DeleteMessageBoxesByIDsRow struct { OwnerUserID int64 BoxID int32 PrivateMessageID int64 MessageSenderID int64 PeerType string PeerID int64 } func (q *Queries) DeleteMessageBoxesByIDs(ctx context.Context, arg DeleteMessageBoxesByIDsParams) ([]DeleteMessageBoxesByIDsRow, error) { rows, err := q.db.Query(ctx, deleteMessageBoxesByIDs, arg.OwnerUserID, arg.BoxIds) if err != nil { return nil, err } defer rows.Close() var items []DeleteMessageBoxesByIDsRow for rows.Next() { var i DeleteMessageBoxesByIDsRow if err := rows.Scan( &i.OwnerUserID, &i.BoxID, &i.PrivateMessageID, &i.MessageSenderID, &i.PeerType, &i.PeerID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const deleteMessageBoxesByPeer = `-- name: DeleteMessageBoxesByPeer :many WITH updated AS ( UPDATE message_boxes m SET deleted = true WHERE m.owner_user_id = $1::bigint AND m.peer_type = $2::text AND m.peer_id = $3::bigint AND ($4::int <= 0 OR m.box_id <= $4::int) AND NOT m.deleted RETURNING m.owner_user_id, m.box_id, m.private_message_id, m.message_sender_id, m.peer_type, m.peer_id ) SELECT owner_user_id, box_id, private_message_id, message_sender_id, peer_type, peer_id FROM updated ORDER BY box_id ASC ` type DeleteMessageBoxesByPeerParams struct { OwnerUserID int64 PeerType string PeerID int64 MaxID int32 } type DeleteMessageBoxesByPeerRow struct { OwnerUserID int64 BoxID int32 PrivateMessageID int64 MessageSenderID int64 PeerType string PeerID int64 } func (q *Queries) DeleteMessageBoxesByPeer(ctx context.Context, arg DeleteMessageBoxesByPeerParams) ([]DeleteMessageBoxesByPeerRow, error) { rows, err := q.db.Query(ctx, deleteMessageBoxesByPeer, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.MaxID, ) if err != nil { return nil, err } defer rows.Close() var items []DeleteMessageBoxesByPeerRow for rows.Next() { var i DeleteMessageBoxesByPeerRow if err := rows.Scan( &i.OwnerUserID, &i.BoxID, &i.PrivateMessageID, &i.MessageSenderID, &i.PeerType, &i.PeerID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const deleteMessageBoxesByPeerBatch = `-- name: DeleteMessageBoxesByPeerBatch :many WITH target AS ( SELECT m.owner_user_id, m.box_id FROM message_boxes m WHERE m.owner_user_id = $1::bigint AND m.peer_type = $2::text AND m.peer_id = $3::bigint AND ($4::int <= 0 OR m.box_id <> $4::int) AND ($5::int <= 0 OR m.box_id <= $5::int) AND ($6::int <= 0 OR m.message_date >= $6::int) AND ($7::int <= 0 OR m.message_date <= $7::int) AND NOT m.deleted ORDER BY m.box_id DESC LIMIT $8::int FOR UPDATE SKIP LOCKED ), updated AS ( UPDATE message_boxes m SET deleted = true FROM target t WHERE m.owner_user_id = t.owner_user_id AND m.box_id = t.box_id RETURNING m.owner_user_id, m.box_id, m.private_message_id, m.message_sender_id, m.peer_type, m.peer_id ) SELECT owner_user_id, box_id, private_message_id, message_sender_id, peer_type, peer_id FROM updated ORDER BY box_id ASC ` type DeleteMessageBoxesByPeerBatchParams struct { OwnerUserID int64 PeerType string PeerID int64 KeepBoxID int32 MaxID int32 MinDate int32 MaxDate int32 LimitCount int32 } type DeleteMessageBoxesByPeerBatchRow struct { OwnerUserID int64 BoxID int32 PrivateMessageID int64 MessageSenderID int64 PeerType string PeerID int64 } func (q *Queries) DeleteMessageBoxesByPeerBatch(ctx context.Context, arg DeleteMessageBoxesByPeerBatchParams) ([]DeleteMessageBoxesByPeerBatchRow, error) { rows, err := q.db.Query(ctx, deleteMessageBoxesByPeerBatch, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.KeepBoxID, arg.MaxID, arg.MinDate, arg.MaxDate, arg.LimitCount, ) if err != nil { return nil, err } defer rows.Close() var items []DeleteMessageBoxesByPeerBatchRow for rows.Next() { var i DeleteMessageBoxesByPeerBatchRow if err := rows.Scan( &i.OwnerUserID, &i.BoxID, &i.PrivateMessageID, &i.MessageSenderID, &i.PeerType, &i.PeerID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const deleteMessageBoxesByPrivateMessages = `-- name: DeleteMessageBoxesByPrivateMessages :many WITH requested AS ( SELECT ($1::bigint[])[i] AS message_sender_id, ($2::bigint[])[i] AS private_message_id, ($3::bigint[])[i] AS owner_user_id FROM generate_subscripts($2::bigint[], 1) AS g(i) WHERE i <= cardinality($1::bigint[]) AND i <= cardinality($3::bigint[]) ), deduped AS ( SELECT DISTINCT message_sender_id, private_message_id, owner_user_id FROM requested WHERE owner_user_id <> 0 ), updated AS ( UPDATE message_boxes m SET deleted = true FROM deduped d WHERE m.owner_user_id = ANY($3::bigint[]) AND m.owner_user_id = d.owner_user_id AND m.message_sender_id = d.message_sender_id AND m.private_message_id = d.private_message_id AND NOT m.deleted RETURNING m.owner_user_id, m.box_id, m.private_message_id, m.message_sender_id, m.peer_type, m.peer_id ) SELECT owner_user_id, box_id, private_message_id, message_sender_id, peer_type, peer_id FROM updated ORDER BY owner_user_id ASC, box_id ASC ` type DeleteMessageBoxesByPrivateMessagesParams struct { MessageSenderIds []int64 PrivateMessageIds []int64 OwnerUserIds []int64 } type DeleteMessageBoxesByPrivateMessagesRow struct { OwnerUserID int64 BoxID int32 PrivateMessageID int64 MessageSenderID int64 PeerType string PeerID int64 } func (q *Queries) DeleteMessageBoxesByPrivateMessages(ctx context.Context, arg DeleteMessageBoxesByPrivateMessagesParams) ([]DeleteMessageBoxesByPrivateMessagesRow, error) { rows, err := q.db.Query(ctx, deleteMessageBoxesByPrivateMessages, arg.MessageSenderIds, arg.PrivateMessageIds, arg.OwnerUserIds) if err != nil { return nil, err } defer rows.Close() var items []DeleteMessageBoxesByPrivateMessagesRow for rows.Next() { var i DeleteMessageBoxesByPrivateMessagesRow if err := rows.Scan( &i.OwnerUserID, &i.BoxID, &i.PrivateMessageID, &i.MessageSenderID, &i.PeerType, &i.PeerID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const getDialogReadStateForUpdate = `-- name: GetDialogReadStateForUpdate :one SELECT user_id, peer_type, peer_id, top_message_id, read_inbox_max_id, unread_count FROM dialogs WHERE user_id = $1::bigint AND peer_type = $2::text AND peer_id = $3::bigint FOR UPDATE ` type GetDialogReadStateForUpdateParams struct { UserID int64 PeerType string PeerID int64 } type GetDialogReadStateForUpdateRow struct { UserID int64 PeerType string PeerID int64 TopMessageID int32 ReadInboxMaxID int32 UnreadCount int32 } func (q *Queries) GetDialogReadStateForUpdate(ctx context.Context, arg GetDialogReadStateForUpdateParams) (GetDialogReadStateForUpdateRow, error) { row := q.db.QueryRow(ctx, getDialogReadStateForUpdate, arg.UserID, arg.PeerType, arg.PeerID) var i GetDialogReadStateForUpdateRow err := row.Scan( &i.UserID, &i.PeerType, &i.PeerID, &i.TopMessageID, &i.ReadInboxMaxID, &i.UnreadCount, ) return i, err } const getMessageBoxByPrivateMessage = `-- name: GetMessageBoxByPrivateMessage :one SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities::text AS entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities::text AS quote_entities_json, quote_offset, reply_external::text AS reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media::text AS media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup::text AS reply_markup_json, rich_message::text AS rich_message_json FROM message_boxes WHERE owner_user_id = $1 AND private_message_id = $2 AND NOT deleted ` type GetMessageBoxByPrivateMessageParams struct { OwnerUserID int64 PrivateMessageID int64 } type GetMessageBoxByPrivateMessageRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string } func (q *Queries) GetMessageBoxByPrivateMessage(ctx context.Context, arg GetMessageBoxByPrivateMessageParams) (GetMessageBoxByPrivateMessageRow, error) { row := q.db.QueryRow(ctx, getMessageBoxByPrivateMessage, arg.OwnerUserID, arg.PrivateMessageID) var i GetMessageBoxByPrivateMessageRow err := row.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, ) return i, err } const getMessageBoxForEdit = `-- name: GetMessageBoxForEdit :one SELECT box_id, private_message_id, owner_user_id, message_sender_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities::text AS entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities::text AS quote_entities_json, quote_offset, reply_external::text AS reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media::text AS media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup::text AS reply_markup_json, rich_message::text AS rich_message_json FROM message_boxes WHERE owner_user_id = $1::bigint AND box_id = $2::int AND peer_type = $3::text AND peer_id = $4::bigint AND NOT deleted LIMIT 1 FOR UPDATE ` type GetMessageBoxForEditParams struct { OwnerUserID int64 BoxID int32 PeerType string PeerID int64 } type GetMessageBoxForEditRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 MessageSenderID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string } func (q *Queries) GetMessageBoxForEdit(ctx context.Context, arg GetMessageBoxForEditParams) (GetMessageBoxForEditRow, error) { row := q.db.QueryRow(ctx, getMessageBoxForEdit, arg.OwnerUserID, arg.BoxID, arg.PeerType, arg.PeerID, ) var i GetMessageBoxForEditRow err := row.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.MessageSenderID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, ) return i, err } const getMessageBoxForPin = `-- name: GetMessageBoxForPin :one SELECT box_id, private_message_id, message_sender_id, pinned, media::text AS media_json FROM message_boxes WHERE owner_user_id = $1::bigint AND peer_type = $2::text AND peer_id = $3::bigint AND box_id = $4::int AND NOT deleted LIMIT 1 FOR UPDATE ` type GetMessageBoxForPinParams struct { OwnerUserID int64 PeerType string PeerID int64 BoxID int32 } type GetMessageBoxForPinRow struct { BoxID int32 PrivateMessageID int64 MessageSenderID int64 Pinned bool MediaJson string } func (q *Queries) GetMessageBoxForPin(ctx context.Context, arg GetMessageBoxForPinParams) (GetMessageBoxForPinRow, error) { row := q.db.QueryRow(ctx, getMessageBoxForPin, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.BoxID, ) var i GetMessageBoxForPinRow err := row.Scan( &i.BoxID, &i.PrivateMessageID, &i.MessageSenderID, &i.Pinned, &i.MediaJson, ) return i, err } const getMessageBoxForReply = `-- name: GetMessageBoxForReply :one SELECT box_id, private_message_id, message_sender_id, from_user_id, message_date, body, entities::text AS entities_json, media::text AS media_json, noforwards FROM message_boxes WHERE owner_user_id = $1::bigint AND peer_type = $2::text AND peer_id = $3::bigint AND box_id = $4::int AND NOT deleted LIMIT 1 ` type GetMessageBoxForReplyParams struct { OwnerUserID int64 PeerType string PeerID int64 BoxID int32 } type GetMessageBoxForReplyRow struct { BoxID int32 PrivateMessageID int64 MessageSenderID int64 FromUserID int64 MessageDate int32 Body string EntitiesJson string MediaJson string Noforwards bool } func (q *Queries) GetMessageBoxForReply(ctx context.Context, arg GetMessageBoxForReplyParams) (GetMessageBoxForReplyRow, error) { row := q.db.QueryRow(ctx, getMessageBoxForReply, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.BoxID, ) var i GetMessageBoxForReplyRow err := row.Scan( &i.BoxID, &i.PrivateMessageID, &i.MessageSenderID, &i.FromUserID, &i.MessageDate, &i.Body, &i.EntitiesJson, &i.MediaJson, &i.Noforwards, ) return i, err } const getMessageBoxesByIDs = `-- name: GetMessageBoxesByIDs :many SELECT wanted.box_id AS requested_box_id, m.box_id, m.private_message_id, m.owner_user_id, m.peer_type, m.peer_id, m.from_user_id, m.message_date, m.ttl_period, m.expires_at, m.edit_date, m.hide_edited, m.outgoing, m.body, m.entities::text AS entities_json, m.silent, m.noforwards, m.reply_to_msg_id, m.reply_to_peer_type, m.reply_to_peer_id, m.reply_to_top_id, m.reply_to_story_id, m.quote_text, m.quote_entities::text AS quote_entities_json, m.quote_offset, m.reply_external::text AS reply_external_json, m.fwd_from_peer_type, m.fwd_from_peer_id, m.fwd_from_name, m.fwd_date, m.fwd_saved_from_peer_type, m.fwd_saved_from_peer_id, m.fwd_saved_from_msg_id, m.saved_peer_type, m.saved_peer_id, m.pts, m.media::text AS media_json, m.media_unread, m.reaction_unread, m.pinned, m.via_bot_id, m.grouped_id, m.effect, m.reply_markup::text AS reply_markup_json, m.rich_message::text AS rich_message_json, COALESCE(peer_u.id, 0)::bigint AS peer_user_id, COALESCE(peer_u.access_hash, 0)::bigint AS peer_access_hash, COALESCE(peer_u.phone, '')::text AS peer_phone, COALESCE(peer_u.first_name, '')::text AS peer_first_name, COALESCE(peer_u.last_name, '')::text AS peer_last_name, COALESCE(peer_u.username, '')::text AS peer_username, COALESCE(peer_u.country_code, '')::text AS peer_country_code, COALESCE(peer_u.verified, false)::boolean AS peer_verified, COALESCE(peer_u.support, false)::boolean AS peer_support, COALESCE(peer_u.is_bot, false)::boolean AS peer_is_bot, COALESCE(peer_u.bot_info_version, 0)::int AS peer_bot_info_version, COALESCE(EXTRACT(EPOCH FROM peer_u.premium_expires_at), 0)::bigint AS peer_premium_until, COALESCE(peer_u.emoji_status_document_id, 0)::bigint AS peer_emoji_status_document_id, COALESCE(peer_u.emoji_status_until, 0)::bigint AS peer_emoji_status_until, COALESCE(peer_u.last_seen_at, 0)::bigint AS peer_last_seen_at, COALESCE(from_u.id, 0)::bigint AS from_user_user_id, COALESCE(from_u.access_hash, 0)::bigint AS from_user_access_hash, COALESCE(from_u.phone, '')::text AS from_user_phone, COALESCE(from_u.first_name, '')::text AS from_user_first_name, COALESCE(from_u.last_name, '')::text AS from_user_last_name, COALESCE(from_u.username, '')::text AS from_user_username, COALESCE(from_u.country_code, '')::text AS from_user_country_code, COALESCE(from_u.verified, false)::boolean AS from_user_verified, COALESCE(from_u.support, false)::boolean AS from_user_support, COALESCE(from_u.is_bot, false)::boolean AS from_user_is_bot, COALESCE(from_u.bot_info_version, 0)::int AS from_user_bot_info_version, COALESCE(EXTRACT(EPOCH FROM from_u.premium_expires_at), 0)::bigint AS from_user_premium_until, COALESCE(from_u.emoji_status_document_id, 0)::bigint AS from_user_emoji_status_document_id, COALESCE(from_u.emoji_status_until, 0)::bigint AS from_user_emoji_status_until, COALESCE(from_u.last_seen_at, 0)::bigint AS from_user_last_seen_at FROM unnest($1::int[]) WITH ORDINALITY AS wanted(box_id, ord) JOIN message_boxes m ON m.owner_user_id = $2::bigint AND m.box_id = wanted.box_id AND NOT m.deleted LEFT JOIN users peer_u ON m.peer_type = 'user' AND peer_u.id = m.peer_id LEFT JOIN users from_u ON from_u.id = m.from_user_id ORDER BY wanted.ord ASC ` type GetMessageBoxesByIDsParams struct { BoxIds []int32 OwnerUserID int64 } type GetMessageBoxesByIDsRow struct { RequestedBoxID interface{} BoxID int32 PrivateMessageID int64 OwnerUserID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string PeerUserID int64 PeerAccessHash int64 PeerPhone string PeerFirstName string PeerLastName string PeerUsername string PeerCountryCode string PeerVerified bool PeerSupport bool PeerIsBot bool PeerBotInfoVersion int32 PeerPremiumUntil int64 PeerEmojiStatusDocumentID int64 PeerEmojiStatusUntil int64 PeerLastSeenAt int64 FromUserUserID int64 FromUserAccessHash int64 FromUserPhone string FromUserFirstName string FromUserLastName string FromUserUsername string FromUserCountryCode string FromUserVerified bool FromUserSupport bool FromUserIsBot bool FromUserBotInfoVersion int32 FromUserPremiumUntil int64 FromUserEmojiStatusDocumentID int64 FromUserEmojiStatusUntil int64 FromUserLastSeenAt int64 } func (q *Queries) GetMessageBoxesByIDs(ctx context.Context, arg GetMessageBoxesByIDsParams) ([]GetMessageBoxesByIDsRow, error) { rows, err := q.db.Query(ctx, getMessageBoxesByIDs, arg.BoxIds, arg.OwnerUserID) if err != nil { return nil, err } defer rows.Close() var items []GetMessageBoxesByIDsRow for rows.Next() { var i GetMessageBoxesByIDsRow if err := rows.Scan( &i.RequestedBoxID, &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, &i.PeerUserID, &i.PeerAccessHash, &i.PeerPhone, &i.PeerFirstName, &i.PeerLastName, &i.PeerUsername, &i.PeerCountryCode, &i.PeerVerified, &i.PeerSupport, &i.PeerIsBot, &i.PeerBotInfoVersion, &i.PeerPremiumUntil, &i.PeerEmojiStatusDocumentID, &i.PeerEmojiStatusUntil, &i.PeerLastSeenAt, &i.FromUserUserID, &i.FromUserAccessHash, &i.FromUserPhone, &i.FromUserFirstName, &i.FromUserLastName, &i.FromUserUsername, &i.FromUserCountryCode, &i.FromUserVerified, &i.FromUserSupport, &i.FromUserIsBot, &i.FromUserBotInfoVersion, &i.FromUserPremiumUntil, &i.FromUserEmojiStatusDocumentID, &i.FromUserEmojiStatusUntil, &i.FromUserLastSeenAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const getMessageBoxesForForward = `-- name: GetMessageBoxesForForward :many WITH requested AS ( SELECT id::int AS box_id, ord::int AS ord FROM unnest($4::int[]) WITH ORDINALITY AS r(id, ord) ) SELECT r.ord, m.box_id, m.private_message_id, m.owner_user_id, m.message_sender_id, m.peer_type, m.peer_id, m.from_user_id, m.message_date, m.ttl_period, m.expires_at, m.edit_date, m.hide_edited, m.outgoing, m.body, m.entities::text AS entities_json, m.silent, m.noforwards, m.reply_to_msg_id, m.reply_to_peer_type, m.reply_to_peer_id, m.reply_to_top_id, m.reply_to_story_id, m.quote_text, m.quote_entities::text AS quote_entities_json, m.quote_offset, m.reply_external::text AS reply_external_json, m.fwd_from_peer_type, m.fwd_from_peer_id, m.fwd_from_name, m.fwd_date, m.fwd_saved_from_peer_type, m.fwd_saved_from_peer_id, m.fwd_saved_from_msg_id, m.saved_peer_type, m.saved_peer_id, m.pts, m.media::text AS media_json, m.media_unread, m.reaction_unread, m.pinned, m.via_bot_id, m.grouped_id FROM requested r JOIN message_boxes m ON m.owner_user_id = $1::bigint AND m.peer_type = $2::text AND m.peer_id = $3::bigint AND m.box_id = r.box_id AND NOT m.deleted ORDER BY r.ord ASC ` type GetMessageBoxesForForwardParams struct { OwnerUserID int64 PeerType string PeerID int64 BoxIds []int32 } type GetMessageBoxesForForwardRow struct { Ord int32 BoxID int32 PrivateMessageID int64 OwnerUserID int64 MessageSenderID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 } func (q *Queries) GetMessageBoxesForForward(ctx context.Context, arg GetMessageBoxesForForwardParams) ([]GetMessageBoxesForForwardRow, error) { rows, err := q.db.Query(ctx, getMessageBoxesForForward, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.BoxIds, ) if err != nil { return nil, err } defer rows.Close() var items []GetMessageBoxesForForwardRow for rows.Next() { var i GetMessageBoxesForForwardRow if err := rows.Scan( &i.Ord, &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.MessageSenderID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const getOutboxMessageForReadDate = `-- name: GetOutboxMessageForReadDate :one SELECT box_id FROM message_boxes WHERE owner_user_id = $1::bigint AND peer_type = $2::text AND peer_id = $3::bigint AND box_id = $4::int AND outgoing AND NOT deleted LIMIT 1 ` type GetOutboxMessageForReadDateParams struct { OwnerUserID int64 PeerType string PeerID int64 BoxID int32 } func (q *Queries) GetOutboxMessageForReadDate(ctx context.Context, arg GetOutboxMessageForReadDateParams) (int32, error) { row := q.db.QueryRow(ctx, getOutboxMessageForReadDate, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.BoxID, ) var box_id int32 err := row.Scan(&box_id) return box_id, err } const getOutboxReadDate = `-- name: GetOutboxReadDate :one SELECT COALESCE(MIN(date), 0)::int AS read_date FROM user_update_events WHERE user_id = $1::bigint AND event_type = 'read_history_outbox' AND peer_type = $2::text AND peer_id = $3::bigint AND max_id >= $4::int ` type GetOutboxReadDateParams struct { UserID int64 PeerType string PeerID int64 MessageID int32 } func (q *Queries) GetOutboxReadDate(ctx context.Context, arg GetOutboxReadDateParams) (int32, error) { row := q.db.QueryRow(ctx, getOutboxReadDate, arg.UserID, arg.PeerType, arg.PeerID, arg.MessageID, ) var read_date int32 err := row.Scan(&read_date) return read_date, err } const getPrivateMessageByRandomID = `-- name: GetPrivateMessageByRandomID :one SELECT id, sender_user_id, recipient_user_id, random_id, request_fingerprint, recipient_delivered, sender_box_id, sender_pts, recipient_box_id, recipient_pts, sender_snapshot::text AS sender_snapshot_json, sender_delete_pts, sender_delete_pts_count, sender_delete_date, sender_delete_message_ids::text AS sender_delete_message_ids_json, message_date, ttl_period, expires_at, edit_date, body, entities::text AS entities_json FROM private_messages WHERE sender_user_id = $1 AND random_id = $2 AND random_id <> 0 ` type GetPrivateMessageByRandomIDParams struct { SenderUserID int64 RandomID int64 } type GetPrivateMessageByRandomIDRow struct { ID int64 SenderUserID int64 RecipientUserID int64 RandomID int64 RequestFingerprint []byte RecipientDelivered bool SenderBoxID int32 SenderPts int32 RecipientBoxID int32 RecipientPts int32 SenderSnapshotJson string SenderDeletePts int32 SenderDeletePtsCount int32 SenderDeleteDate int32 SenderDeleteMessageIdsJson string MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 Body string EntitiesJson string } func (q *Queries) GetPrivateMessageByRandomID(ctx context.Context, arg GetPrivateMessageByRandomIDParams) (GetPrivateMessageByRandomIDRow, error) { row := q.db.QueryRow(ctx, getPrivateMessageByRandomID, arg.SenderUserID, arg.RandomID) var i GetPrivateMessageByRandomIDRow err := row.Scan( &i.ID, &i.SenderUserID, &i.RecipientUserID, &i.RandomID, &i.RequestFingerprint, &i.RecipientDelivered, &i.SenderBoxID, &i.SenderPts, &i.RecipientBoxID, &i.RecipientPts, &i.SenderSnapshotJson, &i.SenderDeletePts, &i.SenderDeletePtsCount, &i.SenderDeleteDate, &i.SenderDeleteMessageIdsJson, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.Body, &i.EntitiesJson, ) return i, err } const hasDeletableMessageBoxByPeer = `-- name: HasDeletableMessageBoxByPeer :one SELECT EXISTS ( SELECT 1 FROM message_boxes m WHERE m.owner_user_id = $1::bigint AND m.peer_type = $2::text AND m.peer_id = $3::bigint AND ($4::int <= 0 OR m.box_id <> $4::int) AND ($5::int <= 0 OR m.box_id <= $5::int) AND ($6::int <= 0 OR m.message_date >= $6::int) AND ($7::int <= 0 OR m.message_date <= $7::int) AND NOT m.deleted LIMIT 1 )::boolean AS more ` type HasDeletableMessageBoxByPeerParams struct { OwnerUserID int64 PeerType string PeerID int64 KeepBoxID int32 MaxID int32 MinDate int32 MaxDate int32 } func (q *Queries) HasDeletableMessageBoxByPeer(ctx context.Context, arg HasDeletableMessageBoxByPeerParams) (bool, error) { row := q.db.QueryRow(ctx, hasDeletableMessageBoxByPeer, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.KeepBoxID, arg.MaxID, arg.MinDate, arg.MaxDate, ) var more bool err := row.Scan(&more) return more, err } const hasPinnedMessageBoxByPeer = `-- name: HasPinnedMessageBoxByPeer :one SELECT EXISTS ( SELECT 1 FROM message_boxes m WHERE m.owner_user_id = $1::bigint AND m.peer_type = $2::text AND m.peer_id = $3::bigint AND m.pinned AND NOT m.deleted LIMIT 1 )::boolean AS more ` type HasPinnedMessageBoxByPeerParams struct { OwnerUserID int64 PeerType string PeerID int64 } func (q *Queries) HasPinnedMessageBoxByPeer(ctx context.Context, arg HasPinnedMessageBoxByPeerParams) (bool, error) { row := q.db.QueryRow(ctx, hasPinnedMessageBoxByPeer, arg.OwnerUserID, arg.PeerType, arg.PeerID) var more bool err := row.Scan(&more) return more, err } const latestIncomingReadReceiptCandidate = `-- name: LatestIncomingReadReceiptCandidate :one SELECT m.message_sender_id, m.private_message_id, sender_box.owner_user_id AS sender_owner_user_id, sender_box.box_id AS sender_box_id FROM message_boxes m JOIN message_boxes sender_box ON sender_box.message_sender_id = m.message_sender_id AND sender_box.private_message_id = m.private_message_id AND sender_box.owner_user_id = m.message_sender_id AND sender_box.outgoing AND NOT sender_box.deleted WHERE m.owner_user_id = $1::bigint AND m.peer_type = $2::text AND m.peer_id = $3::bigint AND NOT m.outgoing AND NOT m.deleted AND m.box_id > $4::int AND m.box_id <= $5::int ORDER BY m.box_id DESC LIMIT 1 ` type LatestIncomingReadReceiptCandidateParams struct { OwnerUserID int64 PeerType string PeerID int64 OldReadInboxMaxID int32 NewReadInboxMaxID int32 } type LatestIncomingReadReceiptCandidateRow struct { MessageSenderID int64 PrivateMessageID int64 SenderOwnerUserID int64 SenderBoxID int32 } func (q *Queries) LatestIncomingReadReceiptCandidate(ctx context.Context, arg LatestIncomingReadReceiptCandidateParams) (LatestIncomingReadReceiptCandidateRow, error) { row := q.db.QueryRow(ctx, latestIncomingReadReceiptCandidate, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.OldReadInboxMaxID, arg.NewReadInboxMaxID, ) var i LatestIncomingReadReceiptCandidateRow err := row.Scan( &i.MessageSenderID, &i.PrivateMessageID, &i.SenderOwnerUserID, &i.SenderBoxID, ) return i, err } const listMessagesBackward = `-- name: ListMessagesBackward :many SELECT m.box_id, m.private_message_id, m.owner_user_id, m.peer_type, m.peer_id, m.from_user_id, m.message_date, m.ttl_period, m.expires_at, m.edit_date, m.hide_edited, m.outgoing, m.body, m.entities::text AS entities_json, m.silent, m.noforwards, m.reply_to_msg_id, m.reply_to_peer_type, m.reply_to_peer_id, m.reply_to_top_id, m.reply_to_story_id, m.quote_text, m.quote_entities::text AS quote_entities_json, m.quote_offset, m.reply_external::text AS reply_external_json, m.fwd_from_peer_type, m.fwd_from_peer_id, m.fwd_from_name, m.fwd_date, m.fwd_saved_from_peer_type, m.fwd_saved_from_peer_id, m.fwd_saved_from_msg_id, m.saved_peer_type, m.saved_peer_id, m.pts, m.media::text AS media_json, m.media_unread, m.reaction_unread, m.pinned, m.via_bot_id, m.grouped_id, m.effect, m.reply_markup::text AS reply_markup_json, m.rich_message::text AS rich_message_json, COALESCE(peer_u.id, 0)::bigint AS peer_user_id, COALESCE(peer_u.access_hash, 0)::bigint AS peer_access_hash, COALESCE(peer_u.phone, '')::text AS peer_phone, COALESCE(peer_u.first_name, '')::text AS peer_first_name, COALESCE(peer_u.last_name, '')::text AS peer_last_name, COALESCE(peer_u.username, '')::text AS peer_username, COALESCE(peer_u.country_code, '')::text AS peer_country_code, COALESCE(peer_u.verified, false)::boolean AS peer_verified, COALESCE(peer_u.support, false)::boolean AS peer_support, COALESCE(peer_u.is_bot, false)::boolean AS peer_is_bot, COALESCE(peer_u.bot_info_version, 0)::int AS peer_bot_info_version, COALESCE(EXTRACT(EPOCH FROM peer_u.premium_expires_at), 0)::bigint AS peer_premium_until, COALESCE(peer_u.emoji_status_document_id, 0)::bigint AS peer_emoji_status_document_id, COALESCE(peer_u.emoji_status_until, 0)::bigint AS peer_emoji_status_until, COALESCE(peer_u.last_seen_at, 0)::bigint AS peer_last_seen_at, COALESCE(from_u.id, 0)::bigint AS from_user_user_id, COALESCE(from_u.access_hash, 0)::bigint AS from_user_access_hash, COALESCE(from_u.phone, '')::text AS from_user_phone, COALESCE(from_u.first_name, '')::text AS from_user_first_name, COALESCE(from_u.last_name, '')::text AS from_user_last_name, COALESCE(from_u.username, '')::text AS from_user_username, COALESCE(from_u.country_code, '')::text AS from_user_country_code, COALESCE(from_u.verified, false)::boolean AS from_user_verified, COALESCE(from_u.support, false)::boolean AS from_user_support, COALESCE(from_u.is_bot, false)::boolean AS from_user_is_bot, COALESCE(from_u.bot_info_version, 0)::int AS from_user_bot_info_version, COALESCE(EXTRACT(EPOCH FROM from_u.premium_expires_at), 0)::bigint AS from_user_premium_until, COALESCE(from_u.emoji_status_document_id, 0)::bigint AS from_user_emoji_status_document_id, COALESCE(from_u.emoji_status_until, 0)::bigint AS from_user_emoji_status_until, COALESCE(from_u.last_seen_at, 0)::bigint AS from_user_last_seen_at FROM message_boxes m LEFT JOIN users peer_u ON m.peer_type = 'user' AND peer_u.id = m.peer_id LEFT JOIN users from_u ON from_u.id = m.from_user_id WHERE m.owner_user_id = $1::bigint AND NOT m.deleted AND ($2::bigint = 0 OR m.from_user_id = $2::bigint) AND ( NOT $3::boolean OR (m.peer_type = $4::text AND m.peer_id = $5::bigint) ) AND ( NOT $6::boolean OR (m.peer_type = 'user' AND m.peer_id = ANY($7::bigint[])) ) AND ( $8::text = '' OR m.body ILIKE ('%' || $8::text || '%') ) AND ($9::int <= 0 OR m.message_date > $9::int) AND ($10::int <= 0 OR m.message_date < $10::int) AND ($11::int <= 0 OR m.box_id < $11::int) AND ($12::int <= 0 OR m.box_id > $12::int) AND (NOT $13::boolean OR m.pinned) AND ( NOT $14::boolean OR ( m.media->>'kind' = 'document' AND EXISTS ( SELECT 1 FROM jsonb_array_elements(COALESCE(m.media #> '{document,attributes}', '[]'::jsonb)) AS attr WHERE attr->>'kind' = 'audio' AND COALESCE((attr->>'voice')::boolean, false) = false ) ) ) AND ( NOT $15::boolean OR m.media #>> '{service_action,kind}' = 'phone_call' ) AND ( NOT $16::boolean OR ( NOT m.outgoing AND m.media #>> '{service_action,kind}' = 'phone_call' AND m.media #>> '{service_action,call,reason}' = 'missed' ) ) AND ( $17::text = '' OR (m.saved_peer_type = $17::text AND m.saved_peer_id = $18::bigint) ) AND ( cardinality($19::text[]) = 0 OR EXISTS ( SELECT 1 FROM saved_message_reaction_tags tag WHERE tag.user_id = m.owner_user_id AND tag.message_box_id = m.box_id AND (tag.reaction_type || ':' || tag.reaction_value) = ANY($19::text[]) ) ) AND ( ($20::int > 0 AND m.message_date < $20::int) OR ($20::int <= 0 AND ($21::int <= 0 OR m.box_id < $21::int)) ) ORDER BY m.box_id DESC OFFSET GREATEST($22::int, 0) LIMIT $23::int ` type ListMessagesBackwardParams struct { OwnerUserID int64 SenderUserID int64 HasPeer bool PeerType string PeerID int64 RestrictPeerIds bool PeerIds []int64 Query string MinDate int32 MaxDate int32 MaxID int32 MinID int32 PinnedOnly bool MusicOnly bool PhoneCallsOnly bool MissedPhoneCallsOnly bool SavedPeerType string SavedPeerID int64 SavedReactionKeys []string OffsetDate int32 OffsetID int32 RowOffset int32 LimitCount int32 } type ListMessagesBackwardRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string PeerUserID int64 PeerAccessHash int64 PeerPhone string PeerFirstName string PeerLastName string PeerUsername string PeerCountryCode string PeerVerified bool PeerSupport bool PeerIsBot bool PeerBotInfoVersion int32 PeerPremiumUntil int64 PeerEmojiStatusDocumentID int64 PeerEmojiStatusUntil int64 PeerLastSeenAt int64 FromUserUserID int64 FromUserAccessHash int64 FromUserPhone string FromUserFirstName string FromUserLastName string FromUserUsername string FromUserCountryCode string FromUserVerified bool FromUserSupport bool FromUserIsBot bool FromUserBotInfoVersion int32 FromUserPremiumUntil int64 FromUserEmojiStatusDocumentID int64 FromUserEmojiStatusUntil int64 FromUserLastSeenAt int64 } // backward 热路径(add_offset>=0:初始加载/上滑翻页)的扁平静态查询。 // 与 ListMessagesByUser 的 backward 分支逐位等价(相同 base 过滤 + 相同 anchor + // ORDER BY box_id DESC + OFFSET GREATEST(add_offset,0) + LIMIT),但只规划单次 // index scan + 2 LEFT JOIN,避免大 CTE 把 4 个分支全树规划。total 走 // 独立 CountMessagesByUser,仅 NeedTotalCount 时发。 func (q *Queries) ListMessagesBackward(ctx context.Context, arg ListMessagesBackwardParams) ([]ListMessagesBackwardRow, error) { rows, err := q.db.Query(ctx, listMessagesBackward, arg.OwnerUserID, arg.SenderUserID, arg.HasPeer, arg.PeerType, arg.PeerID, arg.RestrictPeerIds, arg.PeerIds, arg.Query, arg.MinDate, arg.MaxDate, arg.MaxID, arg.MinID, arg.PinnedOnly, arg.MusicOnly, arg.PhoneCallsOnly, arg.MissedPhoneCallsOnly, arg.SavedPeerType, arg.SavedPeerID, arg.SavedReactionKeys, arg.OffsetDate, arg.OffsetID, arg.RowOffset, arg.LimitCount, ) if err != nil { return nil, err } defer rows.Close() var items []ListMessagesBackwardRow for rows.Next() { var i ListMessagesBackwardRow if err := rows.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, &i.PeerUserID, &i.PeerAccessHash, &i.PeerPhone, &i.PeerFirstName, &i.PeerLastName, &i.PeerUsername, &i.PeerCountryCode, &i.PeerVerified, &i.PeerSupport, &i.PeerIsBot, &i.PeerBotInfoVersion, &i.PeerPremiumUntil, &i.PeerEmojiStatusDocumentID, &i.PeerEmojiStatusUntil, &i.PeerLastSeenAt, &i.FromUserUserID, &i.FromUserAccessHash, &i.FromUserPhone, &i.FromUserFirstName, &i.FromUserLastName, &i.FromUserUsername, &i.FromUserCountryCode, &i.FromUserVerified, &i.FromUserSupport, &i.FromUserIsBot, &i.FromUserBotInfoVersion, &i.FromUserPremiumUntil, &i.FromUserEmojiStatusDocumentID, &i.FromUserEmojiStatusUntil, &i.FromUserLastSeenAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listMessagesByUser = `-- name: ListMessagesByUser :many WITH load_params AS ( SELECT $2::int AS offset_id, $3::int AS offset_date, $4::int AS add_offset, $5::int AS limit_count, CASE WHEN $4::int >= 0 THEN 'backward' WHEN $4::int + $5::int > 0 THEN 'around' ELSE 'forward' END::text AS load_type ), base AS NOT MATERIALIZED ( SELECT m.box_id, m.private_message_id, m.owner_user_id, m.peer_type, m.peer_id, m.from_user_id, m.message_date, m.ttl_period, m.expires_at, m.edit_date, m.hide_edited, m.outgoing, m.body, m.entities::text AS entities_json, m.silent, m.noforwards, m.reply_to_msg_id, m.reply_to_peer_type, m.reply_to_peer_id, m.reply_to_top_id, m.reply_to_story_id, m.quote_text, m.quote_entities::text AS quote_entities_json, m.quote_offset, m.reply_external::text AS reply_external_json, m.fwd_from_peer_type, m.fwd_from_peer_id, m.fwd_from_name, m.fwd_date, m.fwd_saved_from_peer_type, m.fwd_saved_from_peer_id, m.fwd_saved_from_msg_id, m.saved_peer_type, m.saved_peer_id, m.pts, m.media::text AS media_json, m.media_unread, m.reaction_unread, m.pinned, m.via_bot_id, m.grouped_id, m.effect, m.reply_markup::text AS reply_markup_json, m.rich_message::text AS rich_message_json, COALESCE(peer_u.id, 0)::bigint AS peer_user_id, COALESCE(peer_u.access_hash, 0)::bigint AS peer_access_hash, COALESCE(peer_u.phone, '')::text AS peer_phone, COALESCE(peer_u.first_name, '')::text AS peer_first_name, COALESCE(peer_u.last_name, '')::text AS peer_last_name, COALESCE(peer_u.username, '')::text AS peer_username, COALESCE(peer_u.country_code, '')::text AS peer_country_code, COALESCE(peer_u.verified, false)::boolean AS peer_verified, COALESCE(peer_u.support, false)::boolean AS peer_support, COALESCE(peer_u.is_bot, false)::boolean AS peer_is_bot, COALESCE(peer_u.bot_info_version, 0)::int AS peer_bot_info_version, COALESCE(EXTRACT(EPOCH FROM peer_u.premium_expires_at), 0)::bigint AS peer_premium_until, COALESCE(peer_u.emoji_status_document_id, 0)::bigint AS peer_emoji_status_document_id, COALESCE(peer_u.emoji_status_until, 0)::bigint AS peer_emoji_status_until, COALESCE(peer_u.last_seen_at, 0)::bigint AS peer_last_seen_at, COALESCE(from_u.id, 0)::bigint AS from_user_user_id, COALESCE(from_u.access_hash, 0)::bigint AS from_user_access_hash, COALESCE(from_u.phone, '')::text AS from_user_phone, COALESCE(from_u.first_name, '')::text AS from_user_first_name, COALESCE(from_u.last_name, '')::text AS from_user_last_name, COALESCE(from_u.username, '')::text AS from_user_username, COALESCE(from_u.country_code, '')::text AS from_user_country_code, COALESCE(from_u.verified, false)::boolean AS from_user_verified, COALESCE(from_u.support, false)::boolean AS from_user_support, COALESCE(from_u.is_bot, false)::boolean AS from_user_is_bot, COALESCE(from_u.bot_info_version, 0)::int AS from_user_bot_info_version, COALESCE(EXTRACT(EPOCH FROM from_u.premium_expires_at), 0)::bigint AS from_user_premium_until, COALESCE(from_u.emoji_status_document_id, 0)::bigint AS from_user_emoji_status_document_id, COALESCE(from_u.emoji_status_until, 0)::bigint AS from_user_emoji_status_until, COALESCE(from_u.last_seen_at, 0)::bigint AS from_user_last_seen_at FROM message_boxes m LEFT JOIN users peer_u ON m.peer_type = 'user' AND peer_u.id = m.peer_id LEFT JOIN users from_u ON from_u.id = m.from_user_id WHERE m.owner_user_id = $1 AND NOT m.deleted AND ($6::bigint = 0 OR m.from_user_id = $6::bigint) AND ( NOT $7::boolean OR (m.peer_type = $8::text AND m.peer_id = $9::bigint) ) AND ( NOT $10::boolean OR (m.peer_type = 'user' AND m.peer_id = ANY($11::bigint[])) ) AND ( $12::text = '' OR m.body ILIKE ('%' || $12::text || '%') ) AND ($13::int <= 0 OR m.message_date > $13::int) AND ($14::int <= 0 OR m.message_date < $14::int) AND ($15::int <= 0 OR m.box_id < $15::int) AND ($16::int <= 0 OR m.box_id > $16::int) AND (NOT $17::boolean OR m.pinned) AND ( NOT $18::boolean OR ( m.media->>'kind' = 'document' AND EXISTS ( SELECT 1 FROM jsonb_array_elements(COALESCE(m.media #> '{document,attributes}', '[]'::jsonb)) AS attr WHERE attr->>'kind' = 'audio' AND COALESCE((attr->>'voice')::boolean, false) = false ) ) ) AND ( NOT $19::boolean OR m.media #>> '{service_action,kind}' = 'phone_call' ) AND ( NOT $20::boolean OR ( NOT m.outgoing AND m.media #>> '{service_action,kind}' = 'phone_call' AND m.media #>> '{service_action,call,reason}' = 'missed' ) ) AND ( $21::text = '' OR (m.saved_peer_type = $21::text AND m.saved_peer_id = $22::bigint) ) AND ( cardinality($23::text[]) = 0 OR EXISTS ( SELECT 1 FROM saved_message_reaction_tags tag WHERE tag.user_id = m.owner_user_id AND tag.message_box_id = m.box_id AND (tag.reaction_type || ':' || tag.reaction_value) = ANY($23::text[]) ) ) ), backward AS ( SELECT b.box_id, b.private_message_id, b.owner_user_id, b.peer_type, b.peer_id, b.from_user_id, b.message_date, b.ttl_period, b.expires_at, b.edit_date, b.hide_edited, b.outgoing, b.body, b.entities_json, b.silent, b.noforwards, b.reply_to_msg_id, b.reply_to_peer_type, b.reply_to_peer_id, b.reply_to_top_id, b.reply_to_story_id, b.quote_text, b.quote_entities_json, b.quote_offset, b.reply_external_json, b.fwd_from_peer_type, b.fwd_from_peer_id, b.fwd_from_name, b.fwd_date, b.fwd_saved_from_peer_type, b.fwd_saved_from_peer_id, b.fwd_saved_from_msg_id, b.saved_peer_type, b.saved_peer_id, b.pts, b.media_json, b.media_unread, b.reaction_unread, b.pinned, b.via_bot_id, b.grouped_id, b.effect, b.reply_markup_json, b.rich_message_json, b.peer_user_id, b.peer_access_hash, b.peer_phone, b.peer_first_name, b.peer_last_name, b.peer_username, b.peer_country_code, b.peer_verified, b.peer_support, b.peer_is_bot, b.peer_bot_info_version, b.peer_premium_until, b.peer_emoji_status_document_id, b.peer_emoji_status_until, b.peer_last_seen_at, b.from_user_user_id, b.from_user_access_hash, b.from_user_phone, b.from_user_first_name, b.from_user_last_name, b.from_user_username, b.from_user_country_code, b.from_user_verified, b.from_user_support, b.from_user_is_bot, b.from_user_bot_info_version, b.from_user_premium_until, b.from_user_emoji_status_document_id, b.from_user_emoji_status_until, b.from_user_last_seen_at FROM base b CROSS JOIN load_params p WHERE p.load_type = 'backward' AND ( (p.offset_date > 0 AND b.message_date < p.offset_date) OR (p.offset_date <= 0 AND (p.offset_id <= 0 OR b.box_id < p.offset_id)) ) ORDER BY b.box_id DESC OFFSET GREATEST((SELECT add_offset FROM load_params), 0) LIMIT (SELECT limit_count FROM load_params) ), around_forward AS ( SELECT f.box_id, f.private_message_id, f.owner_user_id, f.peer_type, f.peer_id, f.from_user_id, f.message_date, f.ttl_period, f.expires_at, f.edit_date, f.hide_edited, f.outgoing, f.body, f.entities_json, f.silent, f.noforwards, f.reply_to_msg_id, f.reply_to_peer_type, f.reply_to_peer_id, f.reply_to_top_id, f.reply_to_story_id, f.quote_text, f.quote_entities_json, f.quote_offset, f.reply_external_json, f.fwd_from_peer_type, f.fwd_from_peer_id, f.fwd_from_name, f.fwd_date, f.fwd_saved_from_peer_type, f.fwd_saved_from_peer_id, f.fwd_saved_from_msg_id, f.saved_peer_type, f.saved_peer_id, f.pts, f.media_json, f.media_unread, f.reaction_unread, f.pinned, f.via_bot_id, f.grouped_id, f.effect, f.reply_markup_json, f.rich_message_json, f.peer_user_id, f.peer_access_hash, f.peer_phone, f.peer_first_name, f.peer_last_name, f.peer_username, f.peer_country_code, f.peer_verified, f.peer_support, f.peer_is_bot, f.peer_bot_info_version, f.peer_premium_until, f.peer_emoji_status_document_id, f.peer_emoji_status_until, f.peer_last_seen_at, f.from_user_user_id, f.from_user_access_hash, f.from_user_phone, f.from_user_first_name, f.from_user_last_name, f.from_user_username, f.from_user_country_code, f.from_user_verified, f.from_user_support, f.from_user_is_bot, f.from_user_bot_info_version, f.from_user_premium_until, f.from_user_emoji_status_document_id, f.from_user_emoji_status_until, f.from_user_last_seen_at FROM ( SELECT b.box_id, b.private_message_id, b.owner_user_id, b.peer_type, b.peer_id, b.from_user_id, b.message_date, b.ttl_period, b.expires_at, b.edit_date, b.hide_edited, b.outgoing, b.body, b.entities_json, b.silent, b.noforwards, b.reply_to_msg_id, b.reply_to_peer_type, b.reply_to_peer_id, b.reply_to_top_id, b.reply_to_story_id, b.quote_text, b.quote_entities_json, b.quote_offset, b.reply_external_json, b.fwd_from_peer_type, b.fwd_from_peer_id, b.fwd_from_name, b.fwd_date, b.fwd_saved_from_peer_type, b.fwd_saved_from_peer_id, b.fwd_saved_from_msg_id, b.saved_peer_type, b.saved_peer_id, b.pts, b.media_json, b.media_unread, b.reaction_unread, b.pinned, b.via_bot_id, b.grouped_id, b.effect, b.reply_markup_json, b.rich_message_json, b.peer_user_id, b.peer_access_hash, b.peer_phone, b.peer_first_name, b.peer_last_name, b.peer_username, b.peer_country_code, b.peer_verified, b.peer_support, b.peer_is_bot, b.peer_bot_info_version, b.peer_premium_until, b.peer_emoji_status_document_id, b.peer_emoji_status_until, b.peer_last_seen_at, b.from_user_user_id, b.from_user_access_hash, b.from_user_phone, b.from_user_first_name, b.from_user_last_name, b.from_user_username, b.from_user_country_code, b.from_user_verified, b.from_user_support, b.from_user_is_bot, b.from_user_bot_info_version, b.from_user_premium_until, b.from_user_emoji_status_document_id, b.from_user_emoji_status_until, b.from_user_last_seen_at FROM base b CROSS JOIN load_params p WHERE p.load_type = 'around' AND ( (p.offset_date > 0 AND b.message_date >= p.offset_date) OR (p.offset_date <= 0 AND p.offset_id > 0 AND b.box_id >= p.offset_id) ) ORDER BY b.box_id ASC LIMIT LEAST(-(SELECT add_offset FROM load_params), (SELECT limit_count FROM load_params)) ) f ), around_backward AS ( SELECT b.box_id, b.private_message_id, b.owner_user_id, b.peer_type, b.peer_id, b.from_user_id, b.message_date, b.ttl_period, b.expires_at, b.edit_date, b.hide_edited, b.outgoing, b.body, b.entities_json, b.silent, b.noforwards, b.reply_to_msg_id, b.reply_to_peer_type, b.reply_to_peer_id, b.reply_to_top_id, b.reply_to_story_id, b.quote_text, b.quote_entities_json, b.quote_offset, b.reply_external_json, b.fwd_from_peer_type, b.fwd_from_peer_id, b.fwd_from_name, b.fwd_date, b.fwd_saved_from_peer_type, b.fwd_saved_from_peer_id, b.fwd_saved_from_msg_id, b.saved_peer_type, b.saved_peer_id, b.pts, b.media_json, b.media_unread, b.reaction_unread, b.pinned, b.via_bot_id, b.grouped_id, b.effect, b.reply_markup_json, b.rich_message_json, b.peer_user_id, b.peer_access_hash, b.peer_phone, b.peer_first_name, b.peer_last_name, b.peer_username, b.peer_country_code, b.peer_verified, b.peer_support, b.peer_is_bot, b.peer_bot_info_version, b.peer_premium_until, b.peer_emoji_status_document_id, b.peer_emoji_status_until, b.peer_last_seen_at, b.from_user_user_id, b.from_user_access_hash, b.from_user_phone, b.from_user_first_name, b.from_user_last_name, b.from_user_username, b.from_user_country_code, b.from_user_verified, b.from_user_support, b.from_user_is_bot, b.from_user_bot_info_version, b.from_user_premium_until, b.from_user_emoji_status_document_id, b.from_user_emoji_status_until, b.from_user_last_seen_at FROM base b CROSS JOIN load_params p WHERE p.load_type = 'around' AND ( (p.offset_date > 0 AND b.message_date < p.offset_date) OR (p.offset_date <= 0 AND (p.offset_id <= 0 OR b.box_id < p.offset_id)) ) ORDER BY b.box_id DESC LIMIT GREATEST((SELECT limit_count + add_offset FROM load_params), 0) ), forward AS ( SELECT f.box_id, f.private_message_id, f.owner_user_id, f.peer_type, f.peer_id, f.from_user_id, f.message_date, f.ttl_period, f.expires_at, f.edit_date, f.hide_edited, f.outgoing, f.body, f.entities_json, f.silent, f.noforwards, f.reply_to_msg_id, f.reply_to_peer_type, f.reply_to_peer_id, f.reply_to_top_id, f.reply_to_story_id, f.quote_text, f.quote_entities_json, f.quote_offset, f.reply_external_json, f.fwd_from_peer_type, f.fwd_from_peer_id, f.fwd_from_name, f.fwd_date, f.fwd_saved_from_peer_type, f.fwd_saved_from_peer_id, f.fwd_saved_from_msg_id, f.saved_peer_type, f.saved_peer_id, f.pts, f.media_json, f.media_unread, f.reaction_unread, f.pinned, f.via_bot_id, f.grouped_id, f.effect, f.reply_markup_json, f.rich_message_json, f.peer_user_id, f.peer_access_hash, f.peer_phone, f.peer_first_name, f.peer_last_name, f.peer_username, f.peer_country_code, f.peer_verified, f.peer_support, f.peer_is_bot, f.peer_bot_info_version, f.peer_premium_until, f.peer_emoji_status_document_id, f.peer_emoji_status_until, f.peer_last_seen_at, f.from_user_user_id, f.from_user_access_hash, f.from_user_phone, f.from_user_first_name, f.from_user_last_name, f.from_user_username, f.from_user_country_code, f.from_user_verified, f.from_user_support, f.from_user_is_bot, f.from_user_bot_info_version, f.from_user_premium_until, f.from_user_emoji_status_document_id, f.from_user_emoji_status_until, f.from_user_last_seen_at FROM ( SELECT b.box_id, b.private_message_id, b.owner_user_id, b.peer_type, b.peer_id, b.from_user_id, b.message_date, b.ttl_period, b.expires_at, b.edit_date, b.hide_edited, b.outgoing, b.body, b.entities_json, b.silent, b.noforwards, b.reply_to_msg_id, b.reply_to_peer_type, b.reply_to_peer_id, b.reply_to_top_id, b.reply_to_story_id, b.quote_text, b.quote_entities_json, b.quote_offset, b.reply_external_json, b.fwd_from_peer_type, b.fwd_from_peer_id, b.fwd_from_name, b.fwd_date, b.fwd_saved_from_peer_type, b.fwd_saved_from_peer_id, b.fwd_saved_from_msg_id, b.saved_peer_type, b.saved_peer_id, b.pts, b.media_json, b.media_unread, b.reaction_unread, b.pinned, b.via_bot_id, b.grouped_id, b.effect, b.reply_markup_json, b.rich_message_json, b.peer_user_id, b.peer_access_hash, b.peer_phone, b.peer_first_name, b.peer_last_name, b.peer_username, b.peer_country_code, b.peer_verified, b.peer_support, b.peer_is_bot, b.peer_bot_info_version, b.peer_premium_until, b.peer_emoji_status_document_id, b.peer_emoji_status_until, b.peer_last_seen_at, b.from_user_user_id, b.from_user_access_hash, b.from_user_phone, b.from_user_first_name, b.from_user_last_name, b.from_user_username, b.from_user_country_code, b.from_user_verified, b.from_user_support, b.from_user_is_bot, b.from_user_bot_info_version, b.from_user_premium_until, b.from_user_emoji_status_document_id, b.from_user_emoji_status_until, b.from_user_last_seen_at FROM base b CROSS JOIN load_params p WHERE p.load_type = 'forward' AND ( (p.offset_date > 0 AND b.message_date >= p.offset_date) OR (p.offset_date <= 0 AND p.offset_id > 0 AND b.box_id >= p.offset_id) ) ORDER BY b.box_id ASC OFFSET GREATEST((SELECT -add_offset - limit_count FROM load_params), 0) LIMIT (SELECT limit_count FROM load_params) ) f ), paged AS ( SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities_json, quote_offset, reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup_json, rich_message_json, peer_user_id, peer_access_hash, peer_phone, peer_first_name, peer_last_name, peer_username, 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, from_user_user_id, from_user_access_hash, from_user_phone, from_user_first_name, from_user_last_name, from_user_username, from_user_country_code, from_user_verified, from_user_support, from_user_is_bot, from_user_bot_info_version, from_user_premium_until, from_user_emoji_status_document_id, from_user_emoji_status_until, from_user_last_seen_at FROM backward UNION ALL SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities_json, quote_offset, reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup_json, rich_message_json, peer_user_id, peer_access_hash, peer_phone, peer_first_name, peer_last_name, peer_username, 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, from_user_user_id, from_user_access_hash, from_user_phone, from_user_first_name, from_user_last_name, from_user_username, from_user_country_code, from_user_verified, from_user_support, from_user_is_bot, from_user_bot_info_version, from_user_premium_until, from_user_emoji_status_document_id, from_user_emoji_status_until, from_user_last_seen_at FROM around_forward UNION ALL SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities_json, quote_offset, reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup_json, rich_message_json, peer_user_id, peer_access_hash, peer_phone, peer_first_name, peer_last_name, peer_username, 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, from_user_user_id, from_user_access_hash, from_user_phone, from_user_first_name, from_user_last_name, from_user_username, from_user_country_code, from_user_verified, from_user_support, from_user_is_bot, from_user_bot_info_version, from_user_premium_until, from_user_emoji_status_document_id, from_user_emoji_status_until, from_user_last_seen_at FROM around_backward UNION ALL SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities_json, quote_offset, reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup_json, rich_message_json, peer_user_id, peer_access_hash, peer_phone, peer_first_name, peer_last_name, peer_username, 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, from_user_user_id, from_user_access_hash, from_user_phone, from_user_first_name, from_user_last_name, from_user_username, from_user_country_code, from_user_verified, from_user_support, from_user_is_bot, from_user_bot_info_version, from_user_premium_until, from_user_emoji_status_document_id, from_user_emoji_status_until, from_user_last_seen_at FROM forward ) SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities_json, quote_offset, reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup_json, rich_message_json, peer_user_id, peer_access_hash, peer_phone, peer_first_name, peer_last_name, peer_username, 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, from_user_user_id, from_user_access_hash, from_user_phone, from_user_first_name, from_user_last_name, from_user_username, from_user_country_code, from_user_verified, from_user_support, from_user_is_bot, from_user_bot_info_version, from_user_premium_until, from_user_emoji_status_document_id, from_user_emoji_status_until, from_user_last_seen_at FROM paged ORDER BY box_id DESC ` type ListMessagesByUserParams struct { OwnerUserID int64 OffsetID int32 OffsetDate int32 AddOffset int32 LimitCount int32 SenderUserID int64 HasPeer bool PeerType string PeerID int64 RestrictPeerIds bool PeerIds []int64 Query string MinDate int32 MaxDate int32 MaxID int32 MinID int32 PinnedOnly bool MusicOnly bool PhoneCallsOnly bool MissedPhoneCallsOnly bool SavedPeerType string SavedPeerID int64 SavedReactionKeys []string } type ListMessagesByUserRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string PeerUserID int64 PeerAccessHash int64 PeerPhone string PeerFirstName string PeerLastName string PeerUsername string PeerCountryCode string PeerVerified bool PeerSupport bool PeerIsBot bool PeerBotInfoVersion int32 PeerPremiumUntil int64 PeerEmojiStatusDocumentID int64 PeerEmojiStatusUntil int64 PeerLastSeenAt int64 FromUserUserID int64 FromUserAccessHash int64 FromUserPhone string FromUserFirstName string FromUserLastName string FromUserUsername string FromUserCountryCode string FromUserVerified bool FromUserSupport bool FromUserIsBot bool FromUserBotInfoVersion int32 FromUserPremiumUntil int64 FromUserEmojiStatusDocumentID int64 FromUserEmojiStatusUntil int64 FromUserLastSeenAt int64 } func (q *Queries) ListMessagesByUser(ctx context.Context, arg ListMessagesByUserParams) ([]ListMessagesByUserRow, error) { rows, err := q.db.Query(ctx, listMessagesByUser, arg.OwnerUserID, arg.OffsetID, arg.OffsetDate, arg.AddOffset, arg.LimitCount, arg.SenderUserID, arg.HasPeer, arg.PeerType, arg.PeerID, arg.RestrictPeerIds, arg.PeerIds, arg.Query, arg.MinDate, arg.MaxDate, arg.MaxID, arg.MinID, arg.PinnedOnly, arg.MusicOnly, arg.PhoneCallsOnly, arg.MissedPhoneCallsOnly, arg.SavedPeerType, arg.SavedPeerID, arg.SavedReactionKeys, ) if err != nil { return nil, err } defer rows.Close() var items []ListMessagesByUserRow for rows.Next() { var i ListMessagesByUserRow if err := rows.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, &i.PeerUserID, &i.PeerAccessHash, &i.PeerPhone, &i.PeerFirstName, &i.PeerLastName, &i.PeerUsername, &i.PeerCountryCode, &i.PeerVerified, &i.PeerSupport, &i.PeerIsBot, &i.PeerBotInfoVersion, &i.PeerPremiumUntil, &i.PeerEmojiStatusDocumentID, &i.PeerEmojiStatusUntil, &i.PeerLastSeenAt, &i.FromUserUserID, &i.FromUserAccessHash, &i.FromUserPhone, &i.FromUserFirstName, &i.FromUserLastName, &i.FromUserUsername, &i.FromUserCountryCode, &i.FromUserVerified, &i.FromUserSupport, &i.FromUserIsBot, &i.FromUserBotInfoVersion, &i.FromUserPremiumUntil, &i.FromUserEmojiStatusDocumentID, &i.FromUserEmojiStatusUntil, &i.FromUserLastSeenAt, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listUnreadReactionMessageBoxes = `-- name: ListUnreadReactionMessageBoxes :many SELECT box_id, private_message_id, owner_user_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities::text AS entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities::text AS quote_entities_json, quote_offset, reply_external::text AS reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media::text AS media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup::text AS reply_markup_json, rich_message::text AS rich_message_json FROM message_boxes WHERE owner_user_id = $1 AND peer_type = $2 AND peer_id = $3 AND NOT deleted AND reaction_unread ORDER BY box_id DESC LIMIT $4 ` type ListUnreadReactionMessageBoxesParams struct { OwnerUserID int64 PeerType string PeerID int64 PageLimit int32 } type ListUnreadReactionMessageBoxesRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string } func (q *Queries) ListUnreadReactionMessageBoxes(ctx context.Context, arg ListUnreadReactionMessageBoxesParams) ([]ListUnreadReactionMessageBoxesRow, error) { rows, err := q.db.Query(ctx, listUnreadReactionMessageBoxes, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.PageLimit, ) if err != nil { return nil, err } defer rows.Close() var items []ListUnreadReactionMessageBoxesRow for rows.Next() { var i ListUnreadReactionMessageBoxesRow if err := rows.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const listVisibleMessageBoxesByPrivateMessage = `-- name: ListVisibleMessageBoxesByPrivateMessage :many SELECT box_id, private_message_id, owner_user_id, message_sender_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities::text AS entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities::text AS quote_entities_json, quote_offset, reply_external::text AS reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media::text AS media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup::text AS reply_markup_json, rich_message::text AS rich_message_json FROM message_boxes WHERE owner_user_id = ANY($1::bigint[]) AND message_sender_id = $2::bigint AND private_message_id = $3::bigint AND NOT deleted ORDER BY owner_user_id ASC, box_id ASC FOR UPDATE ` type ListVisibleMessageBoxesByPrivateMessageParams struct { OwnerUserIds []int64 MessageSenderID int64 PrivateMessageID int64 } type ListVisibleMessageBoxesByPrivateMessageRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 MessageSenderID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string } func (q *Queries) ListVisibleMessageBoxesByPrivateMessage(ctx context.Context, arg ListVisibleMessageBoxesByPrivateMessageParams) ([]ListVisibleMessageBoxesByPrivateMessageRow, error) { rows, err := q.db.Query(ctx, listVisibleMessageBoxesByPrivateMessage, arg.OwnerUserIds, arg.MessageSenderID, arg.PrivateMessageID) if err != nil { return nil, err } defer rows.Close() var items []ListVisibleMessageBoxesByPrivateMessageRow for rows.Next() { var i ListVisibleMessageBoxesByPrivateMessageRow if err := rows.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.MessageSenderID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, ); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const maxMessageBoxID = `-- name: MaxMessageBoxID :one SELECT COALESCE(MAX(box_id), 0)::int AS max_box_id FROM message_boxes WHERE owner_user_id = $1 ` func (q *Queries) MaxMessageBoxID(ctx context.Context, ownerUserID int64) (int32, error) { row := q.db.QueryRow(ctx, maxMessageBoxID, ownerUserID) var max_box_id int32 err := row.Scan(&max_box_id) return max_box_id, err } const setMessageBoxPinned = `-- name: SetMessageBoxPinned :execrows UPDATE message_boxes SET pinned = $1::boolean WHERE owner_user_id = $2::bigint AND box_id = $3::int AND NOT deleted AND pinned <> $1::boolean ` type SetMessageBoxPinnedParams struct { Pinned bool OwnerUserID int64 BoxID int32 } func (q *Queries) SetMessageBoxPinned(ctx context.Context, arg SetMessageBoxPinnedParams) (int64, error) { result, err := q.db.Exec(ctx, setMessageBoxPinned, arg.Pinned, arg.OwnerUserID, arg.BoxID) if err != nil { return 0, err } return result.RowsAffected(), nil } const topVisibleMessageBoxByPeer = `-- name: TopVisibleMessageBoxByPeer :one SELECT box_id, message_date FROM message_boxes WHERE owner_user_id = $1 AND peer_type = $2 AND peer_id = $3 AND NOT deleted ORDER BY box_id DESC LIMIT 1 ` type TopVisibleMessageBoxByPeerParams struct { OwnerUserID int64 PeerType string PeerID int64 } type TopVisibleMessageBoxByPeerRow struct { BoxID int32 MessageDate int32 } func (q *Queries) TopVisibleMessageBoxByPeer(ctx context.Context, arg TopVisibleMessageBoxByPeerParams) (TopVisibleMessageBoxByPeerRow, error) { row := q.db.QueryRow(ctx, topVisibleMessageBoxByPeer, arg.OwnerUserID, arg.PeerType, arg.PeerID) var i TopVisibleMessageBoxByPeerRow err := row.Scan(&i.BoxID, &i.MessageDate) return i, err } const unpinAllMessageBoxesByPeer = `-- name: UnpinAllMessageBoxesByPeer :many WITH target AS ( SELECT m.owner_user_id, m.box_id FROM message_boxes m WHERE m.owner_user_id = $1::bigint AND m.peer_type = $2::text AND m.peer_id = $3::bigint AND m.pinned AND NOT m.deleted ORDER BY m.box_id DESC LIMIT $4::int FOR UPDATE ) UPDATE message_boxes m SET pinned = false FROM target t WHERE m.owner_user_id = t.owner_user_id AND m.box_id = t.box_id RETURNING m.box_id, m.private_message_id, m.message_sender_id ` type UnpinAllMessageBoxesByPeerParams struct { OwnerUserID int64 PeerType string PeerID int64 LimitCount int32 } type UnpinAllMessageBoxesByPeerRow struct { BoxID int32 PrivateMessageID int64 MessageSenderID int64 } // 按批清除(affectedHistory.offset 续清语义),单条 updatePinnedMessages // 的 messages 向量随之有界。 func (q *Queries) UnpinAllMessageBoxesByPeer(ctx context.Context, arg UnpinAllMessageBoxesByPeerParams) ([]UnpinAllMessageBoxesByPeerRow, error) { rows, err := q.db.Query(ctx, unpinAllMessageBoxesByPeer, arg.OwnerUserID, arg.PeerType, arg.PeerID, arg.LimitCount, ) if err != nil { return nil, err } defer rows.Close() var items []UnpinAllMessageBoxesByPeerRow for rows.Next() { var i UnpinAllMessageBoxesByPeerRow if err := rows.Scan(&i.BoxID, &i.PrivateMessageID, &i.MessageSenderID); err != nil { return nil, err } items = append(items, i) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const unpinMessageBoxesByPrivateMessages = `-- name: UnpinMessageBoxesByPrivateMessages :many WITH requested AS ( SELECT ($2::bigint[])[i] AS message_sender_id, ($3::bigint[])[i] AS private_message_id FROM generate_subscripts($3::bigint[], 1) AS g(i) WHERE i <= cardinality($2::bigint[]) ) UPDATE message_boxes m SET pinned = false FROM requested r WHERE m.owner_user_id = $1::bigint AND m.message_sender_id = r.message_sender_id AND m.private_message_id = r.private_message_id AND m.pinned AND NOT m.deleted RETURNING m.box_id ` type UnpinMessageBoxesByPrivateMessagesParams struct { OwnerUserID int64 MessageSenderIds []int64 PrivateMessageIds []int64 } func (q *Queries) UnpinMessageBoxesByPrivateMessages(ctx context.Context, arg UnpinMessageBoxesByPrivateMessagesParams) ([]int32, error) { rows, err := q.db.Query(ctx, unpinMessageBoxesByPrivateMessages, arg.OwnerUserID, arg.MessageSenderIds, arg.PrivateMessageIds) if err != nil { return nil, err } defer rows.Close() var items []int32 for rows.Next() { var box_id int32 if err := rows.Scan(&box_id); err != nil { return nil, err } items = append(items, box_id) } if err := rows.Err(); err != nil { return nil, err } return items, nil } const updateDialogReadInbox = `-- name: UpdateDialogReadInbox :one UPDATE dialogs d SET read_inbox_max_id = GREATEST(d.read_inbox_max_id, $1::int), 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, $1::int) ), unread_mark = false, unread_mentions_count = 0, updated_at = now() WHERE d.user_id = $2::bigint AND d.peer_type = $3::text AND d.peer_id = $4::bigint RETURNING d.read_inbox_max_id, d.unread_count ` type UpdateDialogReadInboxParams struct { ReadInboxMaxID int32 UserID int64 PeerType string PeerID int64 } type UpdateDialogReadInboxRow struct { ReadInboxMaxID int32 UnreadCount int32 } func (q *Queries) UpdateDialogReadInbox(ctx context.Context, arg UpdateDialogReadInboxParams) (UpdateDialogReadInboxRow, error) { row := q.db.QueryRow(ctx, updateDialogReadInbox, arg.ReadInboxMaxID, arg.UserID, arg.PeerType, arg.PeerID, ) var i UpdateDialogReadInboxRow err := row.Scan(&i.ReadInboxMaxID, &i.UnreadCount) return i, err } const updateDialogReadOutbox = `-- name: UpdateDialogReadOutbox :one UPDATE dialogs SET read_outbox_max_id = GREATEST(read_outbox_max_id, $1::int), updated_at = now() WHERE user_id = $2::bigint AND peer_type = $3::text AND peer_id = $4::bigint AND read_outbox_max_id < $1::int RETURNING read_outbox_max_id ` type UpdateDialogReadOutboxParams struct { ReadOutboxMaxID int32 UserID int64 PeerType string PeerID int64 } func (q *Queries) UpdateDialogReadOutbox(ctx context.Context, arg UpdateDialogReadOutboxParams) (int32, error) { row := q.db.QueryRow(ctx, updateDialogReadOutbox, arg.ReadOutboxMaxID, arg.UserID, arg.PeerType, arg.PeerID, ) var read_outbox_max_id int32 err := row.Scan(&read_outbox_max_id) return read_outbox_max_id, err } const updateMessageBoxEdit = `-- name: UpdateMessageBoxEdit :one UPDATE message_boxes SET body = $1::text, entities = $2::jsonb, edit_date = $3::int, hide_edited = $4::boolean, pts = $5::int, reply_markup = CASE WHEN $6::boolean THEN $7::jsonb ELSE reply_markup END, rich_message = CASE WHEN $8::boolean THEN $9::jsonb ELSE rich_message END WHERE owner_user_id = $10::bigint AND box_id = $11::int AND NOT deleted RETURNING box_id, private_message_id, owner_user_id, message_sender_id, peer_type, peer_id, from_user_id, message_date, ttl_period, expires_at, edit_date, hide_edited, outgoing, body, entities::text AS entities_json, silent, noforwards, reply_to_msg_id, reply_to_peer_type, reply_to_peer_id, reply_to_top_id, reply_to_story_id, quote_text, quote_entities::text AS quote_entities_json, quote_offset, reply_external::text AS reply_external_json, fwd_from_peer_type, fwd_from_peer_id, fwd_from_name, fwd_date, fwd_saved_from_peer_type, fwd_saved_from_peer_id, fwd_saved_from_msg_id, saved_peer_type, saved_peer_id, pts, media::text AS media_json, media_unread, reaction_unread, pinned, via_bot_id, grouped_id, effect, reply_markup::text AS reply_markup_json, rich_message::text AS rich_message_json ` type UpdateMessageBoxEditParams struct { Body string EntitiesJson []byte EditDate int32 HideEdited bool Pts int32 SetReplyMarkup bool ReplyMarkupJson []byte SetRichMessage bool RichMessageJson []byte OwnerUserID int64 BoxID int32 } type UpdateMessageBoxEditRow struct { BoxID int32 PrivateMessageID int64 OwnerUserID int64 MessageSenderID int64 PeerType string PeerID int64 FromUserID int64 MessageDate int32 TtlPeriod int32 ExpiresAt int32 EditDate int32 HideEdited bool Outgoing bool Body string EntitiesJson string Silent bool Noforwards bool ReplyToMsgID int32 ReplyToPeerType string ReplyToPeerID int64 ReplyToTopID int32 ReplyToStoryID int32 QuoteText string QuoteEntitiesJson string QuoteOffset int32 ReplyExternalJson string FwdFromPeerType string FwdFromPeerID int64 FwdFromName string FwdDate int32 FwdSavedFromPeerType string FwdSavedFromPeerID int64 FwdSavedFromMsgID int32 SavedPeerType string SavedPeerID int64 Pts int32 MediaJson string MediaUnread bool ReactionUnread bool Pinned bool ViaBotID int64 GroupedID int64 Effect int64 ReplyMarkupJson string RichMessageJson string } func (q *Queries) UpdateMessageBoxEdit(ctx context.Context, arg UpdateMessageBoxEditParams) (UpdateMessageBoxEditRow, error) { row := q.db.QueryRow(ctx, updateMessageBoxEdit, arg.Body, arg.EntitiesJson, arg.EditDate, arg.HideEdited, arg.Pts, arg.SetReplyMarkup, arg.ReplyMarkupJson, arg.SetRichMessage, arg.RichMessageJson, arg.OwnerUserID, arg.BoxID, ) var i UpdateMessageBoxEditRow err := row.Scan( &i.BoxID, &i.PrivateMessageID, &i.OwnerUserID, &i.MessageSenderID, &i.PeerType, &i.PeerID, &i.FromUserID, &i.MessageDate, &i.TtlPeriod, &i.ExpiresAt, &i.EditDate, &i.HideEdited, &i.Outgoing, &i.Body, &i.EntitiesJson, &i.Silent, &i.Noforwards, &i.ReplyToMsgID, &i.ReplyToPeerType, &i.ReplyToPeerID, &i.ReplyToTopID, &i.ReplyToStoryID, &i.QuoteText, &i.QuoteEntitiesJson, &i.QuoteOffset, &i.ReplyExternalJson, &i.FwdFromPeerType, &i.FwdFromPeerID, &i.FwdFromName, &i.FwdDate, &i.FwdSavedFromPeerType, &i.FwdSavedFromPeerID, &i.FwdSavedFromMsgID, &i.SavedPeerType, &i.SavedPeerID, &i.Pts, &i.MediaJson, &i.MediaUnread, &i.ReactionUnread, &i.Pinned, &i.ViaBotID, &i.GroupedID, &i.Effect, &i.ReplyMarkupJson, &i.RichMessageJson, ) return i, err } const updatePrivateMessageEdit = `-- name: UpdatePrivateMessageEdit :exec UPDATE private_messages SET body = $1::text, entities = $2::jsonb, edit_date = $3::int, hide_edited = $4::boolean, reply_markup = CASE WHEN $5::boolean THEN $6::jsonb ELSE reply_markup END, rich_message = CASE WHEN $7::boolean THEN $8::jsonb ELSE rich_message END WHERE sender_user_id = $9::bigint AND id = $10::bigint ` type UpdatePrivateMessageEditParams struct { Body string EntitiesJson []byte EditDate int32 HideEdited bool SetReplyMarkup bool ReplyMarkupJson []byte SetRichMessage bool RichMessageJson []byte SenderUserID int64 PrivateMessageID int64 } func (q *Queries) UpdatePrivateMessageEdit(ctx context.Context, arg UpdatePrivateMessageEditParams) error { _, err := q.db.Exec(ctx, updatePrivateMessageEdit, arg.Body, arg.EntitiesJson, arg.EditDate, arg.HideEdited, arg.SetReplyMarkup, arg.ReplyMarkupJson, arg.SetRichMessage, arg.RichMessageJson, arg.SenderUserID, arg.PrivateMessageID, ) return err }