owpengram-server/internal/store/postgres/sqlcgen/dialog.sql.go
A 23a2b2aff7 fix: restore sticker placeholders and media history
(cherry picked from commit 488e409a1898e9c739cc0bd24cb9791636dfd6b3)
2026-06-09 15:00:19 +08:00

1600 lines
40 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: dialog.sql
package sqlcgen
import (
"context"
)
const clearDialogAfterHistoryDelete = `-- name: ClearDialogAfterHistoryDelete :exec
UPDATE dialogs d
SET
top_message_id = 0,
top_message_date = 0,
read_inbox_max_id = GREATEST(d.read_inbox_max_id, d.top_message_id),
read_outbox_max_id = GREATEST(d.read_outbox_max_id, d.top_message_id),
unread_count = 0,
unread_mark = false,
unread_mentions_count = 0,
unread_reactions_count = 0,
updated_at = now()
WHERE d.user_id = $1::bigint
AND d.peer_type = $2::text
AND d.peer_id = $3::bigint
`
type ClearDialogAfterHistoryDeleteParams struct {
UserID int64
PeerType string
PeerID int64
}
func (q *Queries) ClearDialogAfterHistoryDelete(ctx context.Context, arg ClearDialogAfterHistoryDeleteParams) error {
_, err := q.db.Exec(ctx, clearDialogAfterHistoryDelete, arg.UserID, arg.PeerType, arg.PeerID)
return err
}
const clearDialogDrafts = `-- name: ClearDialogDrafts :many
WITH doomed AS (
SELECT d.user_id, d.peer_type, d.peer_id, d.top_message_id
FROM dialog_drafts d
WHERE d.user_id = $1
ORDER BY d.date DESC, d.peer_type ASC, d.peer_id DESC, d.top_message_id DESC
LIMIT $2
),
deleted AS (
DELETE FROM dialog_drafts d
USING doomed
WHERE d.user_id = doomed.user_id
AND d.peer_type = doomed.peer_type
AND d.peer_id = doomed.peer_id
AND d.top_message_id = doomed.top_message_id
RETURNING d.draft::text AS draft_json
)
SELECT draft_json
FROM deleted
`
type ClearDialogDraftsParams struct {
UserID int64
LimitCount int32
}
func (q *Queries) ClearDialogDrafts(ctx context.Context, arg ClearDialogDraftsParams) ([]string, error) {
rows, err := q.db.Query(ctx, clearDialogDrafts, arg.UserID, arg.LimitCount)
if err != nil {
return nil, err
}
defer rows.Close()
var items []string
for rows.Next() {
var draft_json string
if err := rows.Scan(&draft_json); err != nil {
return nil, err
}
items = append(items, draft_json)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const clearPinnedDialogsNotInOrder = `-- name: ClearPinnedDialogsNotInOrder :exec
WITH requested AS (
SELECT
($2::text[])[i] AS peer_type,
($3::bigint[])[i] AS peer_id
FROM generate_subscripts($3::bigint[], 1) AS g(i)
WHERE i <= cardinality($2::text[])
)
UPDATE dialogs d
SET pinned = false,
pinned_order = 0,
updated_at = now()
WHERE d.user_id = $1::bigint
AND d.pinned
AND NOT EXISTS (
SELECT 1
FROM requested r
WHERE r.peer_type = d.peer_type
AND r.peer_id = d.peer_id
)
`
type ClearPinnedDialogsNotInOrderParams struct {
UserID int64
PeerTypes []string
PeerIds []int64
}
func (q *Queries) ClearPinnedDialogsNotInOrder(ctx context.Context, arg ClearPinnedDialogsNotInOrderParams) error {
_, err := q.db.Exec(ctx, clearPinnedDialogsNotInOrder, arg.UserID, arg.PeerTypes, arg.PeerIds)
return err
}
const deleteDialogByPeer = `-- name: DeleteDialogByPeer :exec
DELETE FROM dialogs
WHERE user_id = $1
AND peer_type = $2
AND peer_id = $3
`
type DeleteDialogByPeerParams struct {
UserID int64
PeerType string
PeerID int64
}
func (q *Queries) DeleteDialogByPeer(ctx context.Context, arg DeleteDialogByPeerParams) error {
_, err := q.db.Exec(ctx, deleteDialogByPeer, arg.UserID, arg.PeerType, arg.PeerID)
return err
}
const deleteDialogDraft = `-- name: DeleteDialogDraft :one
WITH deleted AS (
DELETE FROM dialog_drafts
WHERE user_id = $1
AND peer_type = $2
AND peer_id = $3
AND top_message_id = $4
RETURNING user_id
)
SELECT EXISTS (SELECT 1 FROM deleted)::boolean AS changed
`
type DeleteDialogDraftParams struct {
UserID int64
PeerType string
PeerID int64
TopMessageID int32
}
func (q *Queries) DeleteDialogDraft(ctx context.Context, arg DeleteDialogDraftParams) (bool, error) {
row := q.db.QueryRow(ctx, deleteDialogDraft,
arg.UserID,
arg.PeerType,
arg.PeerID,
arg.TopMessageID,
)
var changed bool
err := row.Scan(&changed)
return changed, err
}
const deleteDialogFolder = `-- name: DeleteDialogFolder :exec
DELETE FROM dialog_filters
WHERE user_id = $1
AND filter_id = $2
`
type DeleteDialogFolderParams struct {
UserID int64
FilterID int32
}
func (q *Queries) DeleteDialogFolder(ctx context.Context, arg DeleteDialogFolderParams) error {
_, err := q.db.Exec(ctx, deleteDialogFolder, arg.UserID, arg.FilterID)
return err
}
const editDialogPeerFolders = `-- name: EditDialogPeerFolders :exec
WITH requested AS (
SELECT
($2::text[])[i] AS peer_type,
($3::bigint[])[i] AS peer_id,
($4::int[])[i] AS folder_id
FROM generate_subscripts($3::bigint[], 1) AS g(i)
WHERE i <= cardinality($2::text[])
AND i <= cardinality($4::int[])
),
deduped AS (
SELECT DISTINCT ON (peer_type, peer_id)
peer_type,
peer_id,
folder_id
FROM requested
WHERE folder_id IN (0, 1)
ORDER BY peer_type, peer_id
)
UPDATE dialogs d
SET folder_id = deduped.folder_id,
updated_at = now()
FROM deduped
WHERE d.user_id = $1::bigint
AND d.peer_type = deduped.peer_type
AND d.peer_id = deduped.peer_id
`
type EditDialogPeerFoldersParams struct {
UserID int64
PeerTypes []string
PeerIds []int64
FolderIds []int32
}
func (q *Queries) EditDialogPeerFolders(ctx context.Context, arg EditDialogPeerFoldersParams) error {
_, err := q.db.Exec(ctx, editDialogPeerFolders,
arg.UserID,
arg.PeerTypes,
arg.PeerIds,
arg.FolderIds,
)
return err
}
const getDialogFolder = `-- name: GetDialogFolder :one
SELECT
filter_id,
is_chatlist,
filter::text AS filter_json
FROM dialog_filters
WHERE user_id = $1
AND filter_id = $2
`
type GetDialogFolderParams struct {
UserID int64
FilterID int32
}
type GetDialogFolderRow struct {
FilterID int32
IsChatlist bool
FilterJson string
}
func (q *Queries) GetDialogFolder(ctx context.Context, arg GetDialogFolderParams) (GetDialogFolderRow, error) {
row := q.db.QueryRow(ctx, getDialogFolder, arg.UserID, arg.FilterID)
var i GetDialogFolderRow
err := row.Scan(&i.FilterID, &i.IsChatlist, &i.FilterJson)
return i, err
}
const getDialogFolderTags = `-- name: GetDialogFolderTags :one
SELECT tags_enabled
FROM dialog_filter_settings
WHERE user_id = $1
`
func (q *Queries) GetDialogFolderTags(ctx context.Context, userID int64) (bool, error) {
row := q.db.QueryRow(ctx, getDialogFolderTags, userID)
var tags_enabled bool
err := row.Scan(&tags_enabled)
return tags_enabled, err
}
const getPeerSettingsBarHidden = `-- name: GetPeerSettingsBarHidden :one
SELECT hidden_peer_settings_bar
FROM dialogs
WHERE user_id = $1
AND peer_type = $2
AND peer_id = $3
`
type GetPeerSettingsBarHiddenParams struct {
UserID int64
PeerType string
PeerID int64
}
func (q *Queries) GetPeerSettingsBarHidden(ctx context.Context, arg GetPeerSettingsBarHiddenParams) (bool, error) {
row := q.db.QueryRow(ctx, getPeerSettingsBarHidden, arg.UserID, arg.PeerType, arg.PeerID)
var hidden_peer_settings_bar bool
err := row.Scan(&hidden_peer_settings_bar)
return hidden_peer_settings_bar, err
}
const listDialogDrafts = `-- name: ListDialogDrafts :many
SELECT draft::text AS draft_json
FROM dialog_drafts
WHERE user_id = $1
ORDER BY date DESC, peer_type ASC, peer_id DESC, top_message_id DESC
LIMIT $2
`
type ListDialogDraftsParams struct {
UserID int64
LimitCount int32
}
func (q *Queries) ListDialogDrafts(ctx context.Context, arg ListDialogDraftsParams) ([]string, error) {
rows, err := q.db.Query(ctx, listDialogDrafts, arg.UserID, arg.LimitCount)
if err != nil {
return nil, err
}
defer rows.Close()
var items []string
for rows.Next() {
var draft_json string
if err := rows.Scan(&draft_json); err != nil {
return nil, err
}
items = append(items, draft_json)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listDialogFolders = `-- name: ListDialogFolders :many
SELECT
filter_id,
is_chatlist,
filter::text AS filter_json
FROM dialog_filters
WHERE user_id = $1
ORDER BY order_value ASC, filter_id ASC
`
type ListDialogFoldersRow struct {
FilterID int32
IsChatlist bool
FilterJson string
}
func (q *Queries) ListDialogFolders(ctx context.Context, userID int64) ([]ListDialogFoldersRow, error) {
rows, err := q.db.Query(ctx, listDialogFolders, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListDialogFoldersRow
for rows.Next() {
var i ListDialogFoldersRow
if err := rows.Scan(&i.FilterID, &i.IsChatlist, &i.FilterJson); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listDialogSummaryByUser = `-- name: ListDialogSummaryByUser :many
SELECT
d.peer_type,
d.peer_id,
d.folder_id,
d.top_message_id,
d.top_message_date,
d.read_inbox_max_id,
d.read_outbox_max_id,
d.unread_count,
d.unread_mentions_count,
d.unread_reactions_count,
d.pinned,
d.pinned_order,
d.unread_mark,
d.hidden_peer_settings_bar
FROM dialogs d
LEFT JOIN contacts c ON d.peer_type = 'user' AND c.user_id = d.user_id AND c.contact_user_id = d.peer_id
WHERE d.user_id = $1
AND (
NOT $2::boolean
OR (
$3::int < 2
AND d.folder_id = $3::int
)
OR (
$3::int >= 2
AND NOT ($4::boolean AND d.folder_id = 1)
AND NOT ($5::boolean AND d.unread_count = 0 AND NOT d.unread_mark)
AND NOT EXISTS (
SELECT 1
FROM (
SELECT fpt.peer_type, fpi.peer_id
FROM unnest($6::text[]) WITH ORDINALITY AS fpt(peer_type, ord)
JOIN unnest($7::bigint[]) WITH ORDINALITY AS fpi(peer_id, ord) USING (ord)
) fp
WHERE fp.peer_type = d.peer_type AND fp.peer_id = d.peer_id
)
AND (
EXISTS (
SELECT 1
FROM (
SELECT fpt.peer_type, fpi.peer_id
FROM unnest($8::text[]) WITH ORDINALITY AS fpt(peer_type, ord)
JOIN unnest($9::bigint[]) WITH ORDINALITY AS fpi(peer_id, ord) USING (ord)
) fp
WHERE fp.peer_type = d.peer_type AND fp.peer_id = d.peer_id
)
OR EXISTS (
SELECT 1
FROM (
SELECT fpt.peer_type, fpi.peer_id
FROM unnest($10::text[]) WITH ORDINALITY AS fpt(peer_type, ord)
JOIN unnest($11::bigint[]) WITH ORDINALITY AS fpi(peer_id, ord) USING (ord)
) fp
WHERE fp.peer_type = d.peer_type AND fp.peer_id = d.peer_id
)
OR ($12::boolean AND c.contact_user_id IS NOT NULL)
OR ($13::boolean AND c.contact_user_id IS NULL)
)
)
)
AND (NOT $14::boolean OR d.pinned)
AND (NOT $15::boolean OR NOT d.pinned)
ORDER BY
d.pinned DESC,
CASE WHEN d.pinned THEN COALESCE(NULLIF(d.pinned_order, 0), 2147483647) ELSE 2147483647 END ASC,
d.top_message_date DESC,
d.top_message_id DESC,
d.peer_id DESC
`
type ListDialogSummaryByUserParams struct {
UserID int64
HasFolderID bool
FolderID int32
FolderExcludeArchived bool
FolderExcludeRead bool
FolderExcludePeerTypes []string
FolderExcludePeerIds []int64
FolderIncludePeerTypes []string
FolderIncludePeerIds []int64
FolderPinnedPeerTypes []string
FolderPinnedPeerIds []int64
FolderContacts bool
FolderNonContacts bool
PinnedOnly bool
ExcludePinned bool
}
type ListDialogSummaryByUserRow struct {
PeerType string
PeerID int64
FolderID int32
TopMessageID int32
TopMessageDate int32
ReadInboxMaxID int32
ReadOutboxMaxID int32
UnreadCount int32
UnreadMentionsCount int32
UnreadReactionsCount int32
Pinned bool
PinnedOrder int32
UnreadMark bool
HiddenPeerSettingsBar bool
}
func (q *Queries) ListDialogSummaryByUser(ctx context.Context, arg ListDialogSummaryByUserParams) ([]ListDialogSummaryByUserRow, error) {
rows, err := q.db.Query(ctx, listDialogSummaryByUser,
arg.UserID,
arg.HasFolderID,
arg.FolderID,
arg.FolderExcludeArchived,
arg.FolderExcludeRead,
arg.FolderExcludePeerTypes,
arg.FolderExcludePeerIds,
arg.FolderIncludePeerTypes,
arg.FolderIncludePeerIds,
arg.FolderPinnedPeerTypes,
arg.FolderPinnedPeerIds,
arg.FolderContacts,
arg.FolderNonContacts,
arg.PinnedOnly,
arg.ExcludePinned,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListDialogSummaryByUserRow
for rows.Next() {
var i ListDialogSummaryByUserRow
if err := rows.Scan(
&i.PeerType,
&i.PeerID,
&i.FolderID,
&i.TopMessageID,
&i.TopMessageDate,
&i.ReadInboxMaxID,
&i.ReadOutboxMaxID,
&i.UnreadCount,
&i.UnreadMentionsCount,
&i.UnreadReactionsCount,
&i.Pinned,
&i.PinnedOrder,
&i.UnreadMark,
&i.HiddenPeerSettingsBar,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listDialogUnreadMarks = `-- name: ListDialogUnreadMarks :many
SELECT
peer_type,
peer_id
FROM dialogs
WHERE user_id = $1
AND unread_mark
ORDER BY top_message_date DESC, top_message_id DESC, peer_id DESC
`
type ListDialogUnreadMarksRow struct {
PeerType string
PeerID int64
}
func (q *Queries) ListDialogUnreadMarks(ctx context.Context, userID int64) ([]ListDialogUnreadMarksRow, error) {
rows, err := q.db.Query(ctx, listDialogUnreadMarks, userID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListDialogUnreadMarksRow
for rows.Next() {
var i ListDialogUnreadMarksRow
if err := rows.Scan(&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 listDialogsByPeers = `-- name: ListDialogsByPeers :many
WITH requested AS (
SELECT
($1::text[])[i] AS peer_type,
($2::bigint[])[i] AS peer_id,
i::int AS ord
FROM generate_subscripts($2::bigint[], 1) AS g(i)
WHERE i <= cardinality($1::text[])
),
deduped AS (
SELECT DISTINCT ON (peer_type, peer_id)
peer_type,
peer_id,
ord
FROM requested
ORDER BY peer_type, peer_id, ord
),
base AS (
SELECT
$3::bigint AS user_id,
r.peer_type,
r.peer_id,
COALESCE(d.folder_id, 0)::int AS folder_id,
COALESCE(d.top_message_id, 0)::int AS top_message_id,
COALESCE(d.top_message_date, 0)::int AS top_message_date,
COALESCE(d.read_inbox_max_id, 0)::int AS read_inbox_max_id,
COALESCE(d.read_outbox_max_id, 0)::int AS read_outbox_max_id,
COALESCE(d.unread_count, 0)::int AS unread_count,
COALESCE(d.unread_mentions_count, 0)::int AS unread_mentions_count,
COALESCE(d.unread_reactions_count, 0)::int AS unread_reactions_count,
COALESCE(d.pinned, false)::boolean AS pinned,
COALESCE(d.pinned_order, 0)::int AS pinned_order,
COALESCE(d.unread_mark, false)::boolean AS unread_mark,
COALESCE(d.hidden_peer_settings_bar, false)::boolean AS hidden_peer_settings_bar,
COALESCE(u.id, 0)::bigint AS peer_user_id,
COALESCE(u.access_hash, 0)::bigint AS peer_access_hash,
COALESCE(NULLIF(c.contact_phone, ''), u.phone, '')::text AS peer_phone,
COALESCE(NULLIF(c.contact_first_name, ''), u.first_name, '')::text AS peer_first_name,
COALESCE(c.contact_last_name, u.last_name, '')::text AS peer_last_name,
COALESCE(u.username, '')::text AS peer_username,
COALESCE(u.country_code, '')::text AS peer_country_code,
COALESCE(u.verified, false)::boolean AS peer_verified,
COALESCE(u.support, false)::boolean AS peer_support,
COALESCE(u.last_seen_at, 0)::bigint AS peer_last_seen_at,
(c.contact_user_id IS NOT NULL)::boolean AS peer_contact,
COALESCE(c.mutual, false)::boolean AS peer_mutual,
COALESCE(m.box_id, 0)::int AS message_id,
COALESCE(m.from_user_id, 0)::bigint AS message_from_user_id,
COALESCE(m.message_date, 0)::int AS message_date,
COALESCE(m.outgoing, false)::boolean AS message_outgoing,
COALESCE(m.body, '')::text AS message_body,
COALESCE(m.entities::text, '[]')::text AS message_entities_json,
COALESCE(m.media::text, '{}')::text AS message_media_json,
r.ord
FROM deduped r
LEFT JOIN dialogs d
ON d.user_id = $3::bigint
AND d.peer_type = r.peer_type
AND d.peer_id = r.peer_id
LEFT JOIN users u ON r.peer_type = 'user' AND u.id = r.peer_id
LEFT JOIN contacts c ON r.peer_type = 'user' AND c.user_id = $3::bigint AND c.contact_user_id = r.peer_id
LEFT JOIN message_boxes m ON m.owner_user_id = $3::bigint AND m.box_id = d.top_message_id AND NOT m.deleted
)
SELECT
user_id,
peer_type::text AS peer_type,
peer_id::bigint AS peer_id,
folder_id,
top_message_id,
top_message_date,
read_inbox_max_id,
read_outbox_max_id,
unread_count,
unread_mentions_count,
unread_reactions_count,
pinned,
pinned_order,
unread_mark,
hidden_peer_settings_bar,
peer_user_id,
peer_access_hash,
peer_phone,
peer_first_name,
peer_last_name,
peer_username,
peer_country_code,
peer_verified,
peer_support,
peer_last_seen_at,
peer_contact,
peer_mutual,
message_id,
message_from_user_id,
message_date,
message_outgoing,
message_body,
message_entities_json,
message_media_json
FROM base
ORDER BY ord
`
type ListDialogsByPeersParams struct {
PeerTypes []string
PeerIds []int64
UserID int64
}
type ListDialogsByPeersRow struct {
UserID int64
PeerType string
PeerID int64
FolderID int32
TopMessageID int32
TopMessageDate int32
ReadInboxMaxID int32
ReadOutboxMaxID int32
UnreadCount int32
UnreadMentionsCount int32
UnreadReactionsCount int32
Pinned bool
PinnedOrder int32
UnreadMark bool
HiddenPeerSettingsBar bool
PeerUserID int64
PeerAccessHash int64
PeerPhone string
PeerFirstName string
PeerLastName string
PeerUsername string
PeerCountryCode string
PeerVerified bool
PeerSupport bool
PeerLastSeenAt int64
PeerContact bool
PeerMutual bool
MessageID int32
MessageFromUserID int64
MessageDate int32
MessageOutgoing bool
MessageBody string
MessageEntitiesJson string
MessageMediaJson string
}
func (q *Queries) ListDialogsByPeers(ctx context.Context, arg ListDialogsByPeersParams) ([]ListDialogsByPeersRow, error) {
rows, err := q.db.Query(ctx, listDialogsByPeers, arg.PeerTypes, arg.PeerIds, arg.UserID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListDialogsByPeersRow
for rows.Next() {
var i ListDialogsByPeersRow
if err := rows.Scan(
&i.UserID,
&i.PeerType,
&i.PeerID,
&i.FolderID,
&i.TopMessageID,
&i.TopMessageDate,
&i.ReadInboxMaxID,
&i.ReadOutboxMaxID,
&i.UnreadCount,
&i.UnreadMentionsCount,
&i.UnreadReactionsCount,
&i.Pinned,
&i.PinnedOrder,
&i.UnreadMark,
&i.HiddenPeerSettingsBar,
&i.PeerUserID,
&i.PeerAccessHash,
&i.PeerPhone,
&i.PeerFirstName,
&i.PeerLastName,
&i.PeerUsername,
&i.PeerCountryCode,
&i.PeerVerified,
&i.PeerSupport,
&i.PeerLastSeenAt,
&i.PeerContact,
&i.PeerMutual,
&i.MessageID,
&i.MessageFromUserID,
&i.MessageDate,
&i.MessageOutgoing,
&i.MessageBody,
&i.MessageEntitiesJson,
&i.MessageMediaJson,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listDialogsByUser = `-- name: ListDialogsByUser :many
WITH base AS (
SELECT
d.user_id,
d.peer_type,
d.peer_id,
d.folder_id,
d.top_message_id,
d.top_message_date,
d.read_inbox_max_id,
d.read_outbox_max_id,
d.unread_count,
d.unread_mentions_count,
d.unread_reactions_count,
d.pinned,
d.pinned_order,
d.unread_mark,
d.hidden_peer_settings_bar,
COALESCE(u.id, 0)::bigint AS peer_user_id,
COALESCE(u.access_hash, 0)::bigint AS peer_access_hash,
COALESCE(NULLIF(c.contact_phone, ''), u.phone, '')::text AS peer_phone,
COALESCE(NULLIF(c.contact_first_name, ''), u.first_name, '')::text AS peer_first_name,
COALESCE(c.contact_last_name, u.last_name, '')::text AS peer_last_name,
COALESCE(u.username, '')::text AS peer_username,
COALESCE(u.country_code, '')::text AS peer_country_code,
COALESCE(u.verified, false)::boolean AS peer_verified,
COALESCE(u.support, false)::boolean AS peer_support,
COALESCE(u.last_seen_at, 0)::bigint AS peer_last_seen_at,
(c.contact_user_id IS NOT NULL)::boolean AS peer_contact,
COALESCE(c.mutual, false)::boolean AS peer_mutual,
COALESCE(m.box_id, 0)::int AS message_id,
COALESCE(m.from_user_id, 0)::bigint AS message_from_user_id,
COALESCE(m.message_date, 0)::int AS message_date,
COALESCE(m.outgoing, false)::boolean AS message_outgoing,
COALESCE(m.body, '')::text AS message_body,
COALESCE(m.entities::text, '[]')::text AS message_entities_json,
COALESCE(m.media::text, '{}')::text AS message_media_json
FROM dialogs d
LEFT JOIN users u ON d.peer_type = 'user' AND u.id = d.peer_id
LEFT JOIN contacts c ON d.peer_type = 'user' AND c.user_id = d.user_id AND c.contact_user_id = d.peer_id
LEFT JOIN message_boxes m ON m.owner_user_id = d.user_id AND m.box_id = d.top_message_id AND NOT m.deleted
WHERE d.user_id = $1
AND (
NOT $3::boolean
OR (
$4::int < 2
AND d.folder_id = $4::int
)
OR (
$4::int >= 2
AND NOT ($5::boolean AND d.folder_id = 1)
AND NOT ($6::boolean AND d.unread_count = 0 AND NOT d.unread_mark)
AND NOT EXISTS (
SELECT 1
FROM (
SELECT fpt.peer_type, fpi.peer_id
FROM unnest($7::text[]) WITH ORDINALITY AS fpt(peer_type, ord)
JOIN unnest($8::bigint[]) WITH ORDINALITY AS fpi(peer_id, ord) USING (ord)
) fp
WHERE fp.peer_type = d.peer_type AND fp.peer_id = d.peer_id
)
AND (
EXISTS (
SELECT 1
FROM (
SELECT fpt.peer_type, fpi.peer_id
FROM unnest($9::text[]) WITH ORDINALITY AS fpt(peer_type, ord)
JOIN unnest($10::bigint[]) WITH ORDINALITY AS fpi(peer_id, ord) USING (ord)
) fp
WHERE fp.peer_type = d.peer_type AND fp.peer_id = d.peer_id
)
OR EXISTS (
SELECT 1
FROM (
SELECT fpt.peer_type, fpi.peer_id
FROM unnest($11::text[]) WITH ORDINALITY AS fpt(peer_type, ord)
JOIN unnest($12::bigint[]) WITH ORDINALITY AS fpi(peer_id, ord) USING (ord)
) fp
WHERE fp.peer_type = d.peer_type AND fp.peer_id = d.peer_id
)
OR ($13::boolean AND c.contact_user_id IS NOT NULL)
OR ($14::boolean AND c.contact_user_id IS NULL)
)
)
)
AND (NOT $15::boolean OR d.pinned)
AND (NOT $16::boolean OR NOT d.pinned)
),
paged AS (
SELECT user_id, peer_type, peer_id, folder_id, top_message_id, top_message_date, read_inbox_max_id, read_outbox_max_id, unread_count, unread_mentions_count, unread_reactions_count, pinned, pinned_order, unread_mark, hidden_peer_settings_bar, peer_user_id, peer_access_hash, peer_phone, peer_first_name, peer_last_name, peer_username, peer_country_code, peer_verified, peer_support, peer_last_seen_at, peer_contact, peer_mutual, message_id, message_from_user_id, message_date, message_outgoing, message_body, message_entities_json, message_media_json
FROM base
WHERE (
($17::int <= 0 AND $18::int <= 0)
OR (
$17::int > 0
AND (
top_message_date < $17::int
OR (
top_message_date = $17::int
AND (
$18::int <= 0
OR top_message_id < $18::int
OR (
top_message_id = $18::int
AND $19::boolean
AND peer_id < $20::bigint
)
)
)
)
)
OR (
$17::int <= 0
AND $18::int > 0
AND (
top_message_id < $18::int
OR (
top_message_id = $18::int
AND $19::boolean
AND peer_id < $20::bigint
)
)
)
)
)
SELECT
user_id,
peer_type::text AS peer_type,
peer_id::bigint AS peer_id,
folder_id,
top_message_id,
top_message_date,
read_inbox_max_id,
read_outbox_max_id,
unread_count,
unread_mentions_count,
unread_reactions_count,
pinned,
pinned_order,
unread_mark,
hidden_peer_settings_bar,
peer_user_id,
peer_access_hash,
peer_phone,
peer_first_name,
peer_last_name,
peer_username,
peer_country_code,
peer_verified,
peer_support,
peer_last_seen_at,
peer_contact,
peer_mutual,
message_id,
message_from_user_id,
message_date,
message_outgoing,
message_body,
message_entities_json,
message_media_json
FROM paged
ORDER BY
pinned DESC,
CASE WHEN pinned THEN COALESCE(NULLIF(pinned_order, 0), 2147483647) ELSE 2147483647 END ASC,
top_message_date DESC,
top_message_id DESC,
peer_id DESC
LIMIT $2
`
type ListDialogsByUserParams struct {
UserID int64
LimitCount int32
HasFolderID bool
FolderID int32
FolderExcludeArchived bool
FolderExcludeRead bool
FolderExcludePeerTypes []string
FolderExcludePeerIds []int64
FolderIncludePeerTypes []string
FolderIncludePeerIds []int64
FolderPinnedPeerTypes []string
FolderPinnedPeerIds []int64
FolderContacts bool
FolderNonContacts bool
PinnedOnly bool
ExcludePinned bool
OffsetDate int32
OffsetID int32
HasOffsetPeer bool
OffsetPeerID int64
}
type ListDialogsByUserRow struct {
UserID int64
PeerType string
PeerID int64
FolderID int32
TopMessageID int32
TopMessageDate int32
ReadInboxMaxID int32
ReadOutboxMaxID int32
UnreadCount int32
UnreadMentionsCount int32
UnreadReactionsCount int32
Pinned bool
PinnedOrder int32
UnreadMark bool
HiddenPeerSettingsBar bool
PeerUserID int64
PeerAccessHash int64
PeerPhone string
PeerFirstName string
PeerLastName string
PeerUsername string
PeerCountryCode string
PeerVerified bool
PeerSupport bool
PeerLastSeenAt int64
PeerContact bool
PeerMutual bool
MessageID int32
MessageFromUserID int64
MessageDate int32
MessageOutgoing bool
MessageBody string
MessageEntitiesJson string
MessageMediaJson string
}
func (q *Queries) ListDialogsByUser(ctx context.Context, arg ListDialogsByUserParams) ([]ListDialogsByUserRow, error) {
rows, err := q.db.Query(ctx, listDialogsByUser,
arg.UserID,
arg.LimitCount,
arg.HasFolderID,
arg.FolderID,
arg.FolderExcludeArchived,
arg.FolderExcludeRead,
arg.FolderExcludePeerTypes,
arg.FolderExcludePeerIds,
arg.FolderIncludePeerTypes,
arg.FolderIncludePeerIds,
arg.FolderPinnedPeerTypes,
arg.FolderPinnedPeerIds,
arg.FolderContacts,
arg.FolderNonContacts,
arg.PinnedOnly,
arg.ExcludePinned,
arg.OffsetDate,
arg.OffsetID,
arg.HasOffsetPeer,
arg.OffsetPeerID,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListDialogsByUserRow
for rows.Next() {
var i ListDialogsByUserRow
if err := rows.Scan(
&i.UserID,
&i.PeerType,
&i.PeerID,
&i.FolderID,
&i.TopMessageID,
&i.TopMessageDate,
&i.ReadInboxMaxID,
&i.ReadOutboxMaxID,
&i.UnreadCount,
&i.UnreadMentionsCount,
&i.UnreadReactionsCount,
&i.Pinned,
&i.PinnedOrder,
&i.UnreadMark,
&i.HiddenPeerSettingsBar,
&i.PeerUserID,
&i.PeerAccessHash,
&i.PeerPhone,
&i.PeerFirstName,
&i.PeerLastName,
&i.PeerUsername,
&i.PeerCountryCode,
&i.PeerVerified,
&i.PeerSupport,
&i.PeerLastSeenAt,
&i.PeerContact,
&i.PeerMutual,
&i.MessageID,
&i.MessageFromUserID,
&i.MessageDate,
&i.MessageOutgoing,
&i.MessageBody,
&i.MessageEntitiesJson,
&i.MessageMediaJson,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const markDialogRead = `-- name: MarkDialogRead :one
WITH target AS (
SELECT
d.user_id,
d.peer_type,
d.peer_id,
d.top_message_id,
d.read_inbox_max_id,
d.unread_count
FROM dialogs d
WHERE d.user_id = $1
AND d.peer_type = $2
AND d.peer_id = $3
),
updated AS (
UPDATE dialogs d
SET
read_inbox_max_id = GREATEST(
d.read_inbox_max_id,
CASE WHEN $4::int > 0 THEN $4::int ELSE d.top_message_id END
),
unread_count = 0,
unread_mark = false,
unread_mentions_count = 0,
unread_reactions_count = 0,
updated_at = now()
FROM target
WHERE d.user_id = target.user_id
AND d.peer_type = target.peer_type
AND d.peer_id = target.peer_id
RETURNING
d.user_id,
d.peer_type,
d.peer_id,
d.read_inbox_max_id,
d.unread_count,
(
target.unread_count > 0
OR (
CASE WHEN $4::int > 0 THEN $4::int ELSE target.top_message_id END
) > target.read_inbox_max_id
)::boolean AS changed
)
SELECT
user_id,
peer_type,
peer_id,
read_inbox_max_id,
unread_count,
changed
FROM updated
`
type MarkDialogReadParams struct {
UserID int64
PeerType string
PeerID int64
MaxID int32
}
type MarkDialogReadRow struct {
UserID int64
PeerType string
PeerID int64
ReadInboxMaxID int32
UnreadCount int32
Changed bool
}
func (q *Queries) MarkDialogRead(ctx context.Context, arg MarkDialogReadParams) (MarkDialogReadRow, error) {
row := q.db.QueryRow(ctx, markDialogRead,
arg.UserID,
arg.PeerType,
arg.PeerID,
arg.MaxID,
)
var i MarkDialogReadRow
err := row.Scan(
&i.UserID,
&i.PeerType,
&i.PeerID,
&i.ReadInboxMaxID,
&i.UnreadCount,
&i.Changed,
)
return i, err
}
const refreshDialogAfterMessageDelete = `-- name: RefreshDialogAfterMessageDelete :exec
UPDATE dialogs d
SET
top_message_id = $1::int,
top_message_date = $2::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 > d.read_inbox_max_id
),
unread_mentions_count = 0,
unread_reactions_count = 0,
updated_at = now()
WHERE d.user_id = $3::bigint
AND d.peer_type = $4::text
AND d.peer_id = $5::bigint
`
type RefreshDialogAfterMessageDeleteParams struct {
TopMessageID int32
TopMessageDate int32
UserID int64
PeerType string
PeerID int64
}
func (q *Queries) RefreshDialogAfterMessageDelete(ctx context.Context, arg RefreshDialogAfterMessageDeleteParams) error {
_, err := q.db.Exec(ctx, refreshDialogAfterMessageDelete,
arg.TopMessageID,
arg.TopMessageDate,
arg.UserID,
arg.PeerType,
arg.PeerID,
)
return err
}
const reorderDialogFolders = `-- name: ReorderDialogFolders :exec
WITH requested AS (
SELECT filter_id, ord::int AS order_value
FROM unnest($2::int[]) WITH ORDINALITY AS t(filter_id, ord)
),
deduped AS (
SELECT DISTINCT ON (filter_id)
filter_id,
order_value
FROM requested
WHERE filter_id >= 2
ORDER BY filter_id, order_value
)
UPDATE dialog_filters f
SET order_value = deduped.order_value,
updated_at = now()
FROM deduped
WHERE f.user_id = $1::bigint
AND f.filter_id = deduped.filter_id
`
type ReorderDialogFoldersParams struct {
UserID int64
FilterIds []int32
}
func (q *Queries) ReorderDialogFolders(ctx context.Context, arg ReorderDialogFoldersParams) error {
_, err := q.db.Exec(ctx, reorderDialogFolders, arg.UserID, arg.FilterIds)
return err
}
const reorderPinnedDialogs = `-- name: ReorderPinnedDialogs :exec
WITH requested AS (
SELECT
($2::text[])[i] AS peer_type,
($3::bigint[])[i] AS peer_id,
i::int AS pos
FROM generate_subscripts($3::bigint[], 1) AS g(i)
WHERE i <= cardinality($2::text[])
),
deduped AS (
SELECT DISTINCT ON (peer_type, peer_id)
peer_type,
peer_id,
pos::int AS ord
FROM requested
ORDER BY peer_type, peer_id, pos
)
UPDATE dialogs d
SET pinned = true,
pinned_order = deduped.ord,
updated_at = now()
FROM deduped
WHERE d.user_id = $1::bigint
AND d.peer_type = deduped.peer_type
AND d.peer_id = deduped.peer_id
`
type ReorderPinnedDialogsParams struct {
UserID int64
PeerTypes []string
PeerIds []int64
}
func (q *Queries) ReorderPinnedDialogs(ctx context.Context, arg ReorderPinnedDialogsParams) error {
_, err := q.db.Exec(ctx, reorderPinnedDialogs, arg.UserID, arg.PeerTypes, arg.PeerIds)
return err
}
const setDialogFolderTags = `-- name: SetDialogFolderTags :exec
INSERT INTO dialog_filter_settings (
user_id,
tags_enabled
) VALUES (
$1,
$2
)
ON CONFLICT (user_id) DO UPDATE SET
tags_enabled = EXCLUDED.tags_enabled,
updated_at = now()
`
type SetDialogFolderTagsParams struct {
UserID int64
TagsEnabled bool
}
func (q *Queries) SetDialogFolderTags(ctx context.Context, arg SetDialogFolderTagsParams) error {
_, err := q.db.Exec(ctx, setDialogFolderTags, arg.UserID, arg.TagsEnabled)
return err
}
const setDialogPinned = `-- name: SetDialogPinned :one
WITH next_order AS (
SELECT COALESCE(MAX(pinned_order), 0)::int + 1 AS value
FROM dialogs
WHERE user_id = $1::bigint
AND pinned
),
updated AS (
UPDATE dialogs d
SET pinned = $2::boolean,
pinned_order = CASE
WHEN $2::boolean THEN
CASE WHEN d.pinned_order > 0 THEN d.pinned_order ELSE next_order.value END
ELSE 0
END,
updated_at = now()
FROM next_order
WHERE d.user_id = $1::bigint
AND d.peer_type = $3::text
AND d.peer_id = $4::bigint
RETURNING d.user_id
)
SELECT EXISTS (SELECT 1 FROM updated)::boolean AS changed
`
type SetDialogPinnedParams struct {
UserID int64
Pinned bool
PeerType string
PeerID int64
}
func (q *Queries) SetDialogPinned(ctx context.Context, arg SetDialogPinnedParams) (bool, error) {
row := q.db.QueryRow(ctx, setDialogPinned,
arg.UserID,
arg.Pinned,
arg.PeerType,
arg.PeerID,
)
var changed bool
err := row.Scan(&changed)
return changed, err
}
const setDialogUnreadMark = `-- name: SetDialogUnreadMark :one
WITH updated AS (
UPDATE dialogs d
SET unread_mark = $1::boolean,
updated_at = now()
WHERE d.user_id = $2::bigint
AND d.peer_type = $3::text
AND d.peer_id = $4::bigint
RETURNING d.user_id
)
SELECT EXISTS (SELECT 1 FROM updated)::boolean AS changed
`
type SetDialogUnreadMarkParams struct {
Unread bool
UserID int64
PeerType string
PeerID int64
}
func (q *Queries) SetDialogUnreadMark(ctx context.Context, arg SetDialogUnreadMarkParams) (bool, error) {
row := q.db.QueryRow(ctx, setDialogUnreadMark,
arg.Unread,
arg.UserID,
arg.PeerType,
arg.PeerID,
)
var changed bool
err := row.Scan(&changed)
return changed, err
}
const setPeerSettingsBarHidden = `-- name: SetPeerSettingsBarHidden :one
WITH updated AS (
UPDATE dialogs d
SET hidden_peer_settings_bar = true,
updated_at = now()
WHERE d.user_id = $1::bigint
AND d.peer_type = $2::text
AND d.peer_id = $3::bigint
RETURNING d.user_id
)
SELECT EXISTS (SELECT 1 FROM updated)::boolean AS changed
`
type SetPeerSettingsBarHiddenParams struct {
UserID int64
PeerType string
PeerID int64
}
func (q *Queries) SetPeerSettingsBarHidden(ctx context.Context, arg SetPeerSettingsBarHiddenParams) (bool, error) {
row := q.db.QueryRow(ctx, setPeerSettingsBarHidden, arg.UserID, arg.PeerType, arg.PeerID)
var changed bool
err := row.Scan(&changed)
return changed, err
}
const upsertDialog = `-- name: UpsertDialog :exec
INSERT INTO dialogs (
user_id,
peer_type,
peer_id,
top_message_id,
top_message_date,
read_inbox_max_id,
read_outbox_max_id,
unread_count,
unread_mentions_count,
unread_reactions_count,
pinned,
unread_mark
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12
)
ON CONFLICT (user_id, peer_type, peer_id) DO UPDATE SET
top_message_id = EXCLUDED.top_message_id,
top_message_date = EXCLUDED.top_message_date,
read_inbox_max_id = EXCLUDED.read_inbox_max_id,
read_outbox_max_id = EXCLUDED.read_outbox_max_id,
unread_count = EXCLUDED.unread_count,
unread_mentions_count = EXCLUDED.unread_mentions_count,
unread_reactions_count = EXCLUDED.unread_reactions_count,
pinned = EXCLUDED.pinned,
unread_mark = EXCLUDED.unread_mark,
updated_at = now()
`
type UpsertDialogParams struct {
UserID int64
PeerType string
PeerID int64
TopMessageID int32
TopMessageDate int32
ReadInboxMaxID int32
ReadOutboxMaxID int32
UnreadCount int32
UnreadMentionsCount int32
UnreadReactionsCount int32
Pinned bool
UnreadMark bool
}
func (q *Queries) UpsertDialog(ctx context.Context, arg UpsertDialogParams) error {
_, err := q.db.Exec(ctx, upsertDialog,
arg.UserID,
arg.PeerType,
arg.PeerID,
arg.TopMessageID,
arg.TopMessageDate,
arg.ReadInboxMaxID,
arg.ReadOutboxMaxID,
arg.UnreadCount,
arg.UnreadMentionsCount,
arg.UnreadReactionsCount,
arg.Pinned,
arg.UnreadMark,
)
return err
}
const upsertDialogDraft = `-- name: UpsertDialogDraft :exec
INSERT INTO dialog_drafts (
user_id,
peer_type,
peer_id,
top_message_id,
date,
draft
) VALUES (
$1,
$2,
$3,
$4,
$5,
$6::jsonb
)
ON CONFLICT (user_id, peer_type, peer_id, top_message_id) DO UPDATE SET
date = EXCLUDED.date,
draft = EXCLUDED.draft,
updated_at = now()
`
type UpsertDialogDraftParams struct {
UserID int64
PeerType string
PeerID int64
TopMessageID int32
Date int32
DraftJson []byte
}
func (q *Queries) UpsertDialogDraft(ctx context.Context, arg UpsertDialogDraftParams) error {
_, err := q.db.Exec(ctx, upsertDialogDraft,
arg.UserID,
arg.PeerType,
arg.PeerID,
arg.TopMessageID,
arg.Date,
arg.DraftJson,
)
return err
}
const upsertDialogFolder = `-- name: UpsertDialogFolder :exec
INSERT INTO dialog_filters (
user_id,
filter_id,
is_chatlist,
filter,
order_value
) VALUES (
$1,
$2,
$3,
$4::jsonb,
COALESCE(
(SELECT order_value FROM dialog_filters WHERE user_id = $1 AND filter_id = $2),
(SELECT COALESCE(MAX(order_value), 0) + 1 FROM dialog_filters WHERE user_id = $1)
)
)
ON CONFLICT (user_id, filter_id) DO UPDATE SET
is_chatlist = EXCLUDED.is_chatlist,
filter = EXCLUDED.filter,
updated_at = now()
`
type UpsertDialogFolderParams struct {
UserID int64
FilterID int32
IsChatlist bool
FilterJson []byte
}
func (q *Queries) UpsertDialogFolder(ctx context.Context, arg UpsertDialogFolderParams) error {
_, err := q.db.Exec(ctx, upsertDialogFolder,
arg.UserID,
arg.FilterID,
arg.IsChatlist,
arg.FilterJson,
)
return err
}
const upsertInboxDialog = `-- name: UpsertInboxDialog :exec
INSERT INTO dialogs (
user_id,
peer_type,
peer_id,
top_message_id,
top_message_date,
unread_count
) VALUES (
$1, $2, $3, $4, $5, 1
)
ON CONFLICT (user_id, peer_type, peer_id) DO UPDATE SET
top_message_id = EXCLUDED.top_message_id,
top_message_date = EXCLUDED.top_message_date,
unread_count = dialogs.unread_count + 1,
updated_at = now()
`
type UpsertInboxDialogParams struct {
UserID int64
PeerType string
PeerID int64
TopMessageID int32
TopMessageDate int32
}
func (q *Queries) UpsertInboxDialog(ctx context.Context, arg UpsertInboxDialogParams) error {
_, err := q.db.Exec(ctx, upsertInboxDialog,
arg.UserID,
arg.PeerType,
arg.PeerID,
arg.TopMessageID,
arg.TopMessageDate,
)
return err
}
const upsertOutboxDialog = `-- name: UpsertOutboxDialog :exec
INSERT INTO dialogs (
user_id,
peer_type,
peer_id,
top_message_id,
top_message_date,
unread_count
) VALUES (
$1, $2, $3, $4, $5, 0
)
ON CONFLICT (user_id, peer_type, peer_id) DO UPDATE SET
top_message_id = EXCLUDED.top_message_id,
top_message_date = EXCLUDED.top_message_date,
updated_at = now()
`
type UpsertOutboxDialogParams struct {
UserID int64
PeerType string
PeerID int64
TopMessageID int32
TopMessageDate int32
}
func (q *Queries) UpsertOutboxDialog(ctx context.Context, arg UpsertOutboxDialogParams) error {
_, err := q.db.Exec(ctx, upsertOutboxDialog,
arg.UserID,
arg.PeerType,
arg.PeerID,
arg.TopMessageID,
arg.TopMessageDate,
)
return err
}