owpengram-server/internal/store/postgres/sqlcgen/media.sql.go
2026-09-03 08:33:06 +03:00

1965 lines
51 KiB
Go

// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.31.1
// source: media.sql
package sqlcgen
import (
"context"
"github.com/jackc/pgx/v5/pgtype"
)
const addProfilePhoto = `-- name: AddProfilePhoto :exec
INSERT INTO profile_photos (owner_peer_type, owner_peer_id, photo_id, date, active, sort_order)
VALUES (
$1::text,
$2::bigint,
$3::bigint,
$4::int,
true,
$5::bigint
)
ON CONFLICT (owner_peer_type, owner_peer_id, photo_id) DO UPDATE SET
date = EXCLUDED.date,
active = true,
sort_order = EXCLUDED.sort_order
`
type AddProfilePhotoParams struct {
OwnerPeerType string
OwnerPeerID int64
PhotoID int64
Date int32
SortOrder int64
}
// profile_photos --------------------------------------------------------------
func (q *Queries) AddProfilePhoto(ctx context.Context, arg AddProfilePhotoParams) error {
_, err := q.db.Exec(ctx, addProfilePhoto,
arg.OwnerPeerType,
arg.OwnerPeerID,
arg.PhotoID,
arg.Date,
arg.SortOrder,
)
return err
}
const clearDocumentOrphan = `-- name: ClearDocumentOrphan :exec
UPDATE documents SET orphaned_at = NULL
WHERE id = $1::bigint AND orphaned_at IS NOT NULL
`
func (q *Queries) ClearDocumentOrphan(ctx context.Context, mediaID int64) error {
_, err := q.db.Exec(ctx, clearDocumentOrphan, mediaID)
return err
}
const clearPhotoOrphan = `-- name: ClearPhotoOrphan :exec
UPDATE photos SET orphaned_at = NULL
WHERE id = $1::bigint AND orphaned_at IS NOT NULL
`
func (q *Queries) ClearPhotoOrphan(ctx context.Context, mediaID int64) error {
_, err := q.db.Exec(ctx, clearPhotoOrphan, mediaID)
return err
}
const countAvailableReactions = `-- name: CountAvailableReactions :one
SELECT count(*)::int AS total FROM available_reactions
`
func (q *Queries) CountAvailableReactions(ctx context.Context) (int32, error) {
row := q.db.QueryRow(ctx, countAvailableReactions)
var total int32
err := row.Scan(&total)
return total, err
}
const countAvatarPhotosForHardRetention = `-- name: CountAvatarPhotosForHardRetention :one
SELECT COUNT(*)::int FROM photos p
WHERE ($1::timestamptz IS NULL OR p.created_at < $1::timestamptz)
AND EXISTS (SELECT 1 FROM profile_photos pp WHERE pp.photo_id = p.id AND pp.active)
AND EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'photo:' || p.id::text
OR fb.location_key LIKE 'photo:' || p.id::text || ':%'
)
`
// Exact-count counterpart of ListAvatarPhotoIDsForHardRetentionOlderThan.
func (q *Queries) CountAvatarPhotosForHardRetention(ctx context.Context, cutoff pgtype.Timestamptz) (int32, error) {
row := q.db.QueryRow(ctx, countAvatarPhotosForHardRetention, cutoff)
var column_1 int32
err := row.Scan(&column_1)
return column_1, err
}
const countDocumentsForHardRetention = `-- name: CountDocumentsForHardRetention :one
SELECT COUNT(*)::int FROM documents d
WHERE ($1::timestamptz IS NULL OR d.created_at < $1::timestamptz)
AND d.category = $2::smallint
AND EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'doc:' || d.id::text
OR fb.location_key LIKE 'doc:' || d.id::text || ':%'
)
`
type CountDocumentsForHardRetentionParams struct {
Cutoff pgtype.Timestamptz
Category int16
}
// Exact-count counterpart of ListDocumentIDsForHardRetentionOlderThan, used
// by the manual purge admin action's dry-run preview: a LIMIT-capped list
// length is not good enough there, the operator needs the real total.
func (q *Queries) CountDocumentsForHardRetention(ctx context.Context, arg CountDocumentsForHardRetentionParams) (int32, error) {
row := q.db.QueryRow(ctx, countDocumentsForHardRetention, arg.Cutoff, arg.Category)
var column_1 int32
err := row.Scan(&column_1)
return column_1, err
}
const countFileBlobRefs = `-- name: CountFileBlobRefs :one
SELECT COUNT(*)::int FROM file_blobs WHERE backend = $1::text AND object_key = $2::text
`
type CountFileBlobRefsParams struct {
Backend string
ObjectKey string
}
func (q *Queries) CountFileBlobRefs(ctx context.Context, arg CountFileBlobRefsParams) (int32, error) {
row := q.db.QueryRow(ctx, countFileBlobRefs, arg.Backend, arg.ObjectKey)
var column_1 int32
err := row.Scan(&column_1)
return column_1, err
}
const countPhotosForHardRetention = `-- name: CountPhotosForHardRetention :one
SELECT COUNT(*)::int FROM photos p
WHERE ($1::timestamptz IS NULL OR p.created_at < $1::timestamptz)
AND NOT EXISTS (SELECT 1 FROM profile_photos pp WHERE pp.photo_id = p.id AND pp.active)
AND EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'photo:' || p.id::text
OR fb.location_key LIKE 'photo:' || p.id::text || ':%'
)
`
// Exact-count counterpart of ListPhotoIDsForHardRetentionOlderThan -- see
// CountDocumentsForHardRetention.
func (q *Queries) CountPhotosForHardRetention(ctx context.Context, cutoff pgtype.Timestamptz) (int32, error) {
row := q.db.QueryRow(ctx, countPhotosForHardRetention, cutoff)
var column_1 int32
err := row.Scan(&column_1)
return column_1, err
}
const countProfilePhotos = `-- name: CountProfilePhotos :one
SELECT count(*)::int AS total
FROM profile_photos
WHERE owner_peer_type = $1::text
AND owner_peer_id = $2::bigint
AND active
`
type CountProfilePhotosParams struct {
OwnerPeerType string
OwnerPeerID int64
}
func (q *Queries) CountProfilePhotos(ctx context.Context, arg CountProfilePhotosParams) (int32, error) {
row := q.db.QueryRow(ctx, countProfilePhotos, arg.OwnerPeerType, arg.OwnerPeerID)
var total int32
err := row.Scan(&total)
return total, err
}
const countStickerSets = `-- name: CountStickerSets :one
SELECT count(*)::int AS total FROM sticker_sets
`
func (q *Queries) CountStickerSets(ctx context.Context) (int32, error) {
row := q.db.QueryRow(ctx, countStickerSets)
var total int32
err := row.Scan(&total)
return total, err
}
const currentProfilePhoto = `-- name: CurrentProfilePhoto :one
SELECT photo_id
FROM profile_photos
WHERE owner_peer_type = $1::text
AND owner_peer_id = $2::bigint
AND active
ORDER BY sort_order DESC
LIMIT 1
`
type CurrentProfilePhotoParams struct {
OwnerPeerType string
OwnerPeerID int64
}
func (q *Queries) CurrentProfilePhoto(ctx context.Context, arg CurrentProfilePhotoParams) (int64, error) {
row := q.db.QueryRow(ctx, currentProfilePhoto, arg.OwnerPeerType, arg.OwnerPeerID)
var photo_id int64
err := row.Scan(&photo_id)
return photo_id, err
}
const currentProfilePhotosForOwners = `-- name: CurrentProfilePhotosForOwners :many
SELECT DISTINCT ON (pp.owner_peer_id)
pp.owner_peer_id,
pp.photo_id,
ph.dc_id,
ph.sizes::text AS sizes_json
FROM profile_photos pp
JOIN photos ph ON ph.id = pp.photo_id
WHERE pp.owner_peer_type = $1::text
AND pp.owner_peer_id = ANY($2::bigint[])
AND pp.active
ORDER BY pp.owner_peer_id, pp.sort_order DESC
`
type CurrentProfilePhotosForOwnersParams struct {
OwnerPeerType string
OwnerIds []int64
}
type CurrentProfilePhotosForOwnersRow struct {
OwnerPeerID int64
PhotoID int64
DcID int32
SizesJson string
}
func (q *Queries) CurrentProfilePhotosForOwners(ctx context.Context, arg CurrentProfilePhotosForOwnersParams) ([]CurrentProfilePhotosForOwnersRow, error) {
rows, err := q.db.Query(ctx, currentProfilePhotosForOwners, arg.OwnerPeerType, arg.OwnerIds)
if err != nil {
return nil, err
}
defer rows.Close()
var items []CurrentProfilePhotosForOwnersRow
for rows.Next() {
var i CurrentProfilePhotosForOwnersRow
if err := rows.Scan(
&i.OwnerPeerID,
&i.PhotoID,
&i.DcID,
&i.SizesJson,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const deactivateProfilePhotos = `-- name: DeactivateProfilePhotos :many
UPDATE profile_photos
SET active = false
WHERE owner_peer_type = $1::text
AND owner_peer_id = $2::bigint
AND photo_id = ANY($3::bigint[])
AND active
RETURNING photo_id
`
type DeactivateProfilePhotosParams struct {
OwnerPeerType string
OwnerPeerID int64
PhotoIds []int64
}
func (q *Queries) DeactivateProfilePhotos(ctx context.Context, arg DeactivateProfilePhotosParams) ([]int64, error) {
rows, err := q.db.Query(ctx, deactivateProfilePhotos, arg.OwnerPeerType, arg.OwnerPeerID, arg.PhotoIds)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var photo_id int64
if err := rows.Scan(&photo_id); err != nil {
return nil, err
}
items = append(items, photo_id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const deleteDocumentRow = `-- name: DeleteDocumentRow :exec
DELETE FROM documents WHERE id = $1::bigint
`
func (q *Queries) DeleteDocumentRow(ctx context.Context, id int64) error {
_, err := q.db.Exec(ctx, deleteDocumentRow, id)
return err
}
const deleteExpiredUploadParts = `-- name: DeleteExpiredUploadParts :many
WITH doomed AS (
SELECT owner_user_id, file_id, part
FROM upload_parts
WHERE created_at < $1::timestamptz
ORDER BY created_at ASC
LIMIT $2::int
)
DELETE FROM upload_parts p
USING doomed d
WHERE p.owner_user_id = d.owner_user_id
AND p.file_id = d.file_id
AND p.part = d.part
RETURNING p.object_key
`
type DeleteExpiredUploadPartsParams struct {
Before pgtype.Timestamptz
BatchLimit int32
}
func (q *Queries) DeleteExpiredUploadParts(ctx context.Context, arg DeleteExpiredUploadPartsParams) ([]string, error) {
rows, err := q.db.Query(ctx, deleteExpiredUploadParts, arg.Before, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []string
for rows.Next() {
var object_key string
if err := rows.Scan(&object_key); err != nil {
return nil, err
}
items = append(items, object_key)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const deleteFileBlobRow = `-- name: DeleteFileBlobRow :exec
DELETE FROM file_blobs WHERE location_key = $1::text
`
func (q *Queries) DeleteFileBlobRow(ctx context.Context, locationKey string) error {
_, err := q.db.Exec(ctx, deleteFileBlobRow, locationKey)
return err
}
const deletePhotoRow = `-- name: DeletePhotoRow :exec
DELETE FROM photos WHERE id = $1::bigint
`
func (q *Queries) DeletePhotoRow(ctx context.Context, id int64) error {
_, err := q.db.Exec(ctx, deletePhotoRow, id)
return err
}
const deleteUploadParts = `-- name: DeleteUploadParts :many
DELETE FROM upload_parts
WHERE owner_user_id = $1::bigint
AND file_id = $2::bigint
RETURNING object_key
`
type DeleteUploadPartsParams struct {
OwnerUserID int64
FileID int64
}
func (q *Queries) DeleteUploadParts(ctx context.Context, arg DeleteUploadPartsParams) ([]string, error) {
rows, err := q.db.Query(ctx, deleteUploadParts, arg.OwnerUserID, arg.FileID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []string
for rows.Next() {
var object_key string
if err := rows.Scan(&object_key); err != nil {
return nil, err
}
items = append(items, object_key)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getDocument = `-- name: GetDocument :one
SELECT id, access_hash, file_reference, date, mime_type, size, dc_id,
attributes::text AS attributes_json,
thumbs::text AS thumbs_json,
owner_user_id
FROM documents
WHERE id = $1::bigint
`
type GetDocumentRow struct {
ID int64
AccessHash int64
FileReference []byte
Date int32
MimeType string
Size int64
DcID int32
AttributesJson string
ThumbsJson string
OwnerUserID int64
}
func (q *Queries) GetDocument(ctx context.Context, id int64) (GetDocumentRow, error) {
row := q.db.QueryRow(ctx, getDocument, id)
var i GetDocumentRow
err := row.Scan(
&i.ID,
&i.AccessHash,
&i.FileReference,
&i.Date,
&i.MimeType,
&i.Size,
&i.DcID,
&i.AttributesJson,
&i.ThumbsJson,
&i.OwnerUserID,
)
return i, err
}
const getDocuments = `-- name: GetDocuments :many
SELECT id, access_hash, file_reference, date, mime_type, size, dc_id,
attributes::text AS attributes_json,
thumbs::text AS thumbs_json,
owner_user_id
FROM documents
WHERE id = ANY($1::bigint[])
`
type GetDocumentsRow struct {
ID int64
AccessHash int64
FileReference []byte
Date int32
MimeType string
Size int64
DcID int32
AttributesJson string
ThumbsJson string
OwnerUserID int64
}
func (q *Queries) GetDocuments(ctx context.Context, ids []int64) ([]GetDocumentsRow, error) {
rows, err := q.db.Query(ctx, getDocuments, ids)
if err != nil {
return nil, err
}
defer rows.Close()
var items []GetDocumentsRow
for rows.Next() {
var i GetDocumentsRow
if err := rows.Scan(
&i.ID,
&i.AccessHash,
&i.FileReference,
&i.Date,
&i.MimeType,
&i.Size,
&i.DcID,
&i.AttributesJson,
&i.ThumbsJson,
&i.OwnerUserID,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const getFileBlob = `-- name: GetFileBlob :one
SELECT location_key, backend, object_key, size, sha256, mime_type
FROM file_blobs
WHERE location_key = $1::text
`
type GetFileBlobRow struct {
LocationKey string
Backend string
ObjectKey string
Size int64
Sha256 []byte
MimeType string
}
func (q *Queries) GetFileBlob(ctx context.Context, locationKey string) (GetFileBlobRow, error) {
row := q.db.QueryRow(ctx, getFileBlob, locationKey)
var i GetFileBlobRow
err := row.Scan(
&i.LocationKey,
&i.Backend,
&i.ObjectKey,
&i.Size,
&i.Sha256,
&i.MimeType,
)
return i, err
}
const getPhoto = `-- name: GetPhoto :one
SELECT id, access_hash, file_reference, date, dc_id, has_stickers,
sizes::text AS sizes_json,
owner_user_id
FROM photos
WHERE id = $1::bigint
`
type GetPhotoRow struct {
ID int64
AccessHash int64
FileReference []byte
Date int32
DcID int32
HasStickers bool
SizesJson string
OwnerUserID int64
}
func (q *Queries) GetPhoto(ctx context.Context, id int64) (GetPhotoRow, error) {
row := q.db.QueryRow(ctx, getPhoto, id)
var i GetPhotoRow
err := row.Scan(
&i.ID,
&i.AccessHash,
&i.FileReference,
&i.Date,
&i.DcID,
&i.HasStickers,
&i.SizesJson,
&i.OwnerUserID,
)
return i, err
}
const getStickerSetByID = `-- name: GetStickerSetByID :one
SELECT
id, access_hash, short_name, title, count, hash, set_kind,
official, animated, videos, emojis, masks, installed, archived, installed_date,
thumb_document_id, thumbs::text AS thumbs_json, thumb_dc_id, thumb_version,
document_ids::text AS document_ids_json, packs::text AS packs_json, sort_order, system_key
FROM sticker_sets
WHERE id = $1::bigint
`
type GetStickerSetByIDRow struct {
ID int64
AccessHash int64
ShortName string
Title string
Count int32
Hash int32
SetKind string
Official bool
Animated bool
Videos bool
Emojis bool
Masks bool
Installed bool
Archived bool
InstalledDate int32
ThumbDocumentID int64
ThumbsJson string
ThumbDcID int32
ThumbVersion int32
DocumentIdsJson string
PacksJson string
SortOrder int32
SystemKey string
}
func (q *Queries) GetStickerSetByID(ctx context.Context, id int64) (GetStickerSetByIDRow, error) {
row := q.db.QueryRow(ctx, getStickerSetByID, id)
var i GetStickerSetByIDRow
err := row.Scan(
&i.ID,
&i.AccessHash,
&i.ShortName,
&i.Title,
&i.Count,
&i.Hash,
&i.SetKind,
&i.Official,
&i.Animated,
&i.Videos,
&i.Emojis,
&i.Masks,
&i.Installed,
&i.Archived,
&i.InstalledDate,
&i.ThumbDocumentID,
&i.ThumbsJson,
&i.ThumbDcID,
&i.ThumbVersion,
&i.DocumentIdsJson,
&i.PacksJson,
&i.SortOrder,
&i.SystemKey,
)
return i, err
}
const getStickerSetByShortName = `-- name: GetStickerSetByShortName :one
SELECT
id, access_hash, short_name, title, count, hash, set_kind,
official, animated, videos, emojis, masks, installed, archived, installed_date,
thumb_document_id, thumbs::text AS thumbs_json, thumb_dc_id, thumb_version,
document_ids::text AS document_ids_json, packs::text AS packs_json, sort_order, system_key
FROM sticker_sets
WHERE short_name = $1::text
`
type GetStickerSetByShortNameRow struct {
ID int64
AccessHash int64
ShortName string
Title string
Count int32
Hash int32
SetKind string
Official bool
Animated bool
Videos bool
Emojis bool
Masks bool
Installed bool
Archived bool
InstalledDate int32
ThumbDocumentID int64
ThumbsJson string
ThumbDcID int32
ThumbVersion int32
DocumentIdsJson string
PacksJson string
SortOrder int32
SystemKey string
}
func (q *Queries) GetStickerSetByShortName(ctx context.Context, shortName string) (GetStickerSetByShortNameRow, error) {
row := q.db.QueryRow(ctx, getStickerSetByShortName, shortName)
var i GetStickerSetByShortNameRow
err := row.Scan(
&i.ID,
&i.AccessHash,
&i.ShortName,
&i.Title,
&i.Count,
&i.Hash,
&i.SetKind,
&i.Official,
&i.Animated,
&i.Videos,
&i.Emojis,
&i.Masks,
&i.Installed,
&i.Archived,
&i.InstalledDate,
&i.ThumbDocumentID,
&i.ThumbsJson,
&i.ThumbDcID,
&i.ThumbVersion,
&i.DocumentIdsJson,
&i.PacksJson,
&i.SortOrder,
&i.SystemKey,
)
return i, err
}
const getStickerSetBySystemKey = `-- name: GetStickerSetBySystemKey :one
SELECT
id, access_hash, short_name, title, count, hash, set_kind,
official, animated, videos, emojis, masks, installed, archived, installed_date,
thumb_document_id, thumbs::text AS thumbs_json, thumb_dc_id, thumb_version,
document_ids::text AS document_ids_json, packs::text AS packs_json, sort_order, system_key
FROM sticker_sets
WHERE system_key = $1::text
`
type GetStickerSetBySystemKeyRow struct {
ID int64
AccessHash int64
ShortName string
Title string
Count int32
Hash int32
SetKind string
Official bool
Animated bool
Videos bool
Emojis bool
Masks bool
Installed bool
Archived bool
InstalledDate int32
ThumbDocumentID int64
ThumbsJson string
ThumbDcID int32
ThumbVersion int32
DocumentIdsJson string
PacksJson string
SortOrder int32
SystemKey string
}
func (q *Queries) GetStickerSetBySystemKey(ctx context.Context, systemKey string) (GetStickerSetBySystemKeyRow, error) {
row := q.db.QueryRow(ctx, getStickerSetBySystemKey, systemKey)
var i GetStickerSetBySystemKeyRow
err := row.Scan(
&i.ID,
&i.AccessHash,
&i.ShortName,
&i.Title,
&i.Count,
&i.Hash,
&i.SetKind,
&i.Official,
&i.Animated,
&i.Videos,
&i.Emojis,
&i.Masks,
&i.Installed,
&i.Archived,
&i.InstalledDate,
&i.ThumbDocumentID,
&i.ThumbsJson,
&i.ThumbDcID,
&i.ThumbVersion,
&i.DocumentIdsJson,
&i.PacksJson,
&i.SortOrder,
&i.SystemKey,
)
return i, err
}
const getUploadPartSlot = `-- name: GetUploadPartSlot :one
SELECT
COALESCE((
SELECT size
FROM upload_parts
WHERE owner_user_id = $1::bigint
AND file_id = $2::bigint
AND part = $3::int
), -1)::bigint AS existing_bytes,
COALESCE((
SELECT object_key
FROM upload_parts
WHERE owner_user_id = $1::bigint
AND file_id = $2::bigint
AND part = $3::int
), '')::text AS object_key,
(
SELECT COUNT(*)::int
FROM upload_parts
WHERE owner_user_id = $1::bigint
AND file_id = $2::bigint
)::int AS file_parts
`
type GetUploadPartSlotParams struct {
OwnerUserID int64
FileID int64
Part int32
}
type GetUploadPartSlotRow struct {
ExistingBytes int64
ObjectKey string
FileParts int32
}
func (q *Queries) GetUploadPartSlot(ctx context.Context, arg GetUploadPartSlotParams) (GetUploadPartSlotRow, error) {
row := q.db.QueryRow(ctx, getUploadPartSlot, arg.OwnerUserID, arg.FileID, arg.Part)
var i GetUploadPartSlotRow
err := row.Scan(&i.ExistingBytes, &i.ObjectKey, &i.FileParts)
return i, err
}
const getUploadPartUsage = `-- name: GetUploadPartUsage :one
SELECT
COALESCE(SUM(size), 0)::bigint AS bytes,
COUNT(*)::int AS parts,
COUNT(DISTINCT file_id)::int AS files
FROM upload_parts
WHERE owner_user_id = $1::bigint
`
type GetUploadPartUsageRow struct {
Bytes int64
Parts int32
Files int32
}
func (q *Queries) GetUploadPartUsage(ctx context.Context, ownerUserID int64) (GetUploadPartUsageRow, error) {
row := q.db.QueryRow(ctx, getUploadPartUsage, ownerUserID)
var i GetUploadPartUsageRow
err := row.Scan(&i.Bytes, &i.Parts, &i.Files)
return i, err
}
const insertMediaReference = `-- name: InsertMediaReference :exec
INSERT INTO media_references (media_kind, media_id, ref_kind, ref_key)
VALUES ($1::text, $2::bigint, $3::text, $4::text)
ON CONFLICT DO NOTHING
`
type InsertMediaReferenceParams struct {
MediaKind string
MediaID int64
RefKind string
RefKey string
}
// media_references / storage retention -----------------------------------------
func (q *Queries) InsertMediaReference(ctx context.Context, arg InsertMediaReferenceParams) error {
_, err := q.db.Exec(ctx, insertMediaReference,
arg.MediaKind,
arg.MediaID,
arg.RefKind,
arg.RefKey,
)
return err
}
const listAvailableReactions = `-- name: ListAvailableReactions :many
SELECT
reaction, title, inactive, premium,
static_icon_id, appear_animation_id, select_animation_id,
activate_animation_id, effect_animation_id, around_animation_id, center_icon_id, sort_order
FROM available_reactions
ORDER BY sort_order ASC, reaction ASC
`
func (q *Queries) ListAvailableReactions(ctx context.Context) ([]AvailableReaction, error) {
rows, err := q.db.Query(ctx, listAvailableReactions)
if err != nil {
return nil, err
}
defer rows.Close()
var items []AvailableReaction
for rows.Next() {
var i AvailableReaction
if err := rows.Scan(
&i.Reaction,
&i.Title,
&i.Inactive,
&i.Premium,
&i.StaticIconID,
&i.AppearAnimationID,
&i.SelectAnimationID,
&i.ActivateAnimationID,
&i.EffectAnimationID,
&i.AroundAnimationID,
&i.CenterIconID,
&i.SortOrder,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listAvatarOrphanedPhotoIDsOlderThan = `-- name: ListAvatarOrphanedPhotoIDsOlderThan :many
SELECT p.id FROM photos p
WHERE p.orphaned_at IS NOT NULL AND p.orphaned_at < $1::timestamptz
AND EXISTS (SELECT 1 FROM profile_photos pp WHERE pp.photo_id = p.id AND pp.active)
ORDER BY p.orphaned_at ASC
LIMIT $2::int
`
type ListAvatarOrphanedPhotoIDsOlderThanParams struct {
Cutoff pgtype.Timestamptz
BatchLimit int32
}
// Same as ListOrphanedPhotoIDsOlderThan but only photos currently active as
// someone's avatar (profile_photos.active) -- lets the Avatar category carry
// its own retention age. In practice a live avatar is never orphaned (an
// active profile_photos row is itself a media_references entry), so this
// bucket is expected to stay empty under "orphan" mode; kept for symmetry
// with the "hard" mode avatar split, which is the one that actually matters.
func (q *Queries) ListAvatarOrphanedPhotoIDsOlderThan(ctx context.Context, arg ListAvatarOrphanedPhotoIDsOlderThanParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listAvatarOrphanedPhotoIDsOlderThan, arg.Cutoff, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var id int64
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listAvatarPhotoIDsForHardRetentionOlderThan = `-- name: ListAvatarPhotoIDsForHardRetentionOlderThan :many
SELECT p.id FROM photos p
WHERE ($1::timestamptz IS NULL OR p.created_at < $1::timestamptz)
AND EXISTS (SELECT 1 FROM profile_photos pp WHERE pp.photo_id = p.id AND pp.active)
AND EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'photo:' || p.id::text
OR fb.location_key LIKE 'photo:' || p.id::text || ':%'
)
ORDER BY p.created_at ASC
LIMIT $2::int
`
type ListAvatarPhotoIDsForHardRetentionOlderThanParams struct {
Cutoff pgtype.Timestamptz
BatchLimit int32
}
// Same as ListPhotoIDsForHardRetentionOlderThan but only photos currently
// active as someone's avatar (profile_photos.active) -- lets the Avatar
// category carry its own retention age, independent of ordinary shared-media
// photos.
func (q *Queries) ListAvatarPhotoIDsForHardRetentionOlderThan(ctx context.Context, arg ListAvatarPhotoIDsForHardRetentionOlderThanParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listAvatarPhotoIDsForHardRetentionOlderThan, arg.Cutoff, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var id int64
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listDocumentIDsForHardRetentionOlderThan = `-- name: ListDocumentIDsForHardRetentionOlderThan :many
SELECT d.id FROM documents d
WHERE ($1::timestamptz IS NULL OR d.created_at < $1::timestamptz)
AND d.category = $2::smallint
AND EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'doc:' || d.id::text
OR fb.location_key LIKE 'doc:' || d.id::text || ':%'
)
ORDER BY d.created_at ASC
LIMIT $3::int
`
type ListDocumentIDsForHardRetentionOlderThanParams struct {
Cutoff pgtype.Timestamptz
Category int16
BatchLimit int32
}
// "Hard" retention mode: candidates are documents older than cutoff (by
// upload/created_at, NOT orphaned_at -- a live reference does not exempt
// them) that still own at least one file_blobs row. The EXISTS check is what
// keeps this sweep from re-selecting the same document forever: once its
// blob bytes are purged (DeleteFileBlobsForDocument removes the file_blobs
// rows but deliberately leaves this documents row in place), it naturally
// drops out of this query on the next pass. category scopes to one
// documents.category bucket per sweep tick -- see
// ListOrphanedDocumentIDsOlderThan for the 0/None fallback note. cutoff is
// nullable: NULL means no age filter at all (every document in the category
// is a candidate, regardless of created_at) -- used by the manual purge admin
// action, which unlike the automatic sweep can target "everything" with no
// age cutoff. The automatic sweep (files.Service.DeleteBlobBytesForMediaOlderThan)
// always passes a real, non-null cutoff.
func (q *Queries) ListDocumentIDsForHardRetentionOlderThan(ctx context.Context, arg ListDocumentIDsForHardRetentionOlderThanParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listDocumentIDsForHardRetentionOlderThan, arg.Cutoff, arg.Category, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var id int64
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listFileBlobsByLocationPrefix = `-- name: ListFileBlobsByLocationPrefix :many
SELECT location_key, backend, object_key, size
FROM file_blobs
WHERE location_key = $1::text
OR location_key LIKE $2::text
`
type ListFileBlobsByLocationPrefixParams struct {
ExactKey string
PrefixPattern string
}
type ListFileBlobsByLocationPrefixRow struct {
LocationKey string
Backend string
ObjectKey string
Size int64
}
// Matches a media's main blob (exact_key, e.g. "doc:123") plus every
// variant keyed off it (prefix_pattern, e.g. "doc:123:%" for thumbnails /
// "photo:456:%" for each rendition size) -- a document/photo can own
// multiple file_blobs rows.
func (q *Queries) ListFileBlobsByLocationPrefix(ctx context.Context, arg ListFileBlobsByLocationPrefixParams) ([]ListFileBlobsByLocationPrefixRow, error) {
rows, err := q.db.Query(ctx, listFileBlobsByLocationPrefix, arg.ExactKey, arg.PrefixPattern)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListFileBlobsByLocationPrefixRow
for rows.Next() {
var i ListFileBlobsByLocationPrefixRow
if err := rows.Scan(
&i.LocationKey,
&i.Backend,
&i.ObjectKey,
&i.Size,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listMediaReferences = `-- name: ListMediaReferences :many
SELECT media_kind, media_id, ref_kind, ref_key
FROM media_references
WHERE media_kind = $1::text AND media_id = $2::bigint
`
type ListMediaReferencesParams struct {
MediaKind string
MediaID int64
}
type ListMediaReferencesRow struct {
MediaKind string
MediaID int64
RefKind string
RefKey string
}
// Every live reference to a document/photo -- used by the storage retention
// sweep to turn a hard-retention/eviction blob purge into a visible notice on
// every message that still embeds the purged media (see
// files.notifyRetentionPurge). profile_photo/sticker_set/gift refs have no
// message to edit and are filtered by the caller, not this query.
func (q *Queries) ListMediaReferences(ctx context.Context, arg ListMediaReferencesParams) ([]ListMediaReferencesRow, error) {
rows, err := q.db.Query(ctx, listMediaReferences, arg.MediaKind, arg.MediaID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListMediaReferencesRow
for rows.Next() {
var i ListMediaReferencesRow
if err := rows.Scan(
&i.MediaKind,
&i.MediaID,
&i.RefKind,
&i.RefKey,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listOldestDocumentsForEviction = `-- name: ListOldestDocumentsForEviction :many
SELECT d.id, d.created_at FROM documents d
WHERE EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'doc:' || d.id::text
OR fb.location_key LIKE 'doc:' || d.id::text || ':%'
)
ORDER BY d.created_at ASC
LIMIT $1::int
`
type ListOldestDocumentsForEvictionRow struct {
ID int64
CreatedAt pgtype.Timestamptz
}
// Active eviction (TELESRV_STORAGE_EVICTION_ENABLE): candidates are every
// document that still owns at least one file_blobs row, oldest-uploaded
// first, REGARDLESS of category or age -- unlike the retention sweeps above,
// eviction only cares about reclaiming bytes once the total physical budget
// (TELESRV_STORAGE_MAX_TOTAL_BYTES) is exceeded. created_at is returned so
// the caller can interleave these with ListOldestPhotosForEviction by actual
// age instead of draining one table before touching the other.
func (q *Queries) ListOldestDocumentsForEviction(ctx context.Context, batchLimit int32) ([]ListOldestDocumentsForEvictionRow, error) {
rows, err := q.db.Query(ctx, listOldestDocumentsForEviction, batchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListOldestDocumentsForEvictionRow
for rows.Next() {
var i ListOldestDocumentsForEvictionRow
if err := rows.Scan(&i.ID, &i.CreatedAt); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listOldestPhotosForEviction = `-- name: ListOldestPhotosForEviction :many
SELECT p.id, p.created_at FROM photos p
WHERE EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'photo:' || p.id::text
OR fb.location_key LIKE 'photo:' || p.id::text || ':%'
)
ORDER BY p.created_at ASC
LIMIT $1::int
`
type ListOldestPhotosForEvictionRow struct {
ID int64
CreatedAt pgtype.Timestamptz
}
// See ListOldestDocumentsForEviction -- same oldest-first eviction candidate
// selection, for photos (avatars included: eviction is bytes-only and does
// not honor the Avatar category's separate retention age).
func (q *Queries) ListOldestPhotosForEviction(ctx context.Context, batchLimit int32) ([]ListOldestPhotosForEvictionRow, error) {
rows, err := q.db.Query(ctx, listOldestPhotosForEviction, batchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListOldestPhotosForEvictionRow
for rows.Next() {
var i ListOldestPhotosForEvictionRow
if err := rows.Scan(&i.ID, &i.CreatedAt); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listOrphanedDocumentIDsOlderThan = `-- name: ListOrphanedDocumentIDsOlderThan :many
SELECT id FROM documents
WHERE orphaned_at IS NOT NULL AND orphaned_at < $1::timestamptz
AND category = $2::smallint
ORDER BY orphaned_at ASC
LIMIT $3::int
`
type ListOrphanedDocumentIDsOlderThanParams struct {
Cutoff pgtype.Timestamptz
Category int16
BatchLimit int32
}
// category selects one documents.category bucket per sweep tick (per-category
// retention age, see internal/app/files/retention.go) -- 0 (MediaCategoryNone)
// covers unclassified documents (e.g. stickers), which always use the shared
// global age since there is no per-category override for that bucket.
func (q *Queries) ListOrphanedDocumentIDsOlderThan(ctx context.Context, arg ListOrphanedDocumentIDsOlderThanParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listOrphanedDocumentIDsOlderThan, arg.Cutoff, arg.Category, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var id int64
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listOrphanedPhotoIDsOlderThan = `-- name: ListOrphanedPhotoIDsOlderThan :many
SELECT p.id FROM photos p
WHERE p.orphaned_at IS NOT NULL AND p.orphaned_at < $1::timestamptz
AND NOT EXISTS (SELECT 1 FROM profile_photos pp WHERE pp.photo_id = p.id AND pp.active)
ORDER BY p.orphaned_at ASC
LIMIT $2::int
`
type ListOrphanedPhotoIDsOlderThanParams struct {
Cutoff pgtype.Timestamptz
BatchLimit int32
}
// Excludes photos currently active as someone's avatar -- see
// ListAvatarOrphanedPhotoIDsOlderThan for that split-off bucket.
func (q *Queries) ListOrphanedPhotoIDsOlderThan(ctx context.Context, arg ListOrphanedPhotoIDsOlderThanParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listOrphanedPhotoIDsOlderThan, arg.Cutoff, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var id int64
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listPhotoIDsForHardRetentionOlderThan = `-- name: ListPhotoIDsForHardRetentionOlderThan :many
SELECT p.id FROM photos p
WHERE ($1::timestamptz IS NULL OR p.created_at < $1::timestamptz)
AND NOT EXISTS (SELECT 1 FROM profile_photos pp WHERE pp.photo_id = p.id AND pp.active)
AND EXISTS (
SELECT 1 FROM file_blobs fb
WHERE fb.location_key = 'photo:' || p.id::text
OR fb.location_key LIKE 'photo:' || p.id::text || ':%'
)
ORDER BY p.created_at ASC
LIMIT $2::int
`
type ListPhotoIDsForHardRetentionOlderThanParams struct {
Cutoff pgtype.Timestamptz
BatchLimit int32
}
// See ListDocumentIDsForHardRetentionOlderThan -- same "hard" retention
// candidate selection (including the nullable cutoff), for photos. Excludes
// photos currently active as someone's avatar -- see
// ListAvatarPhotoIDsForHardRetentionOlderThan.
func (q *Queries) ListPhotoIDsForHardRetentionOlderThan(ctx context.Context, arg ListPhotoIDsForHardRetentionOlderThanParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listPhotoIDsForHardRetentionOlderThan, arg.Cutoff, arg.BatchLimit)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var id int64
if err := rows.Scan(&id); err != nil {
return nil, err
}
items = append(items, id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listProfilePhotos = `-- name: ListProfilePhotos :many
SELECT photo_id
FROM profile_photos
WHERE owner_peer_type = $1::text
AND owner_peer_id = $2::bigint
AND active
AND ($3::bigint <= 0 OR photo_id < $3::bigint)
ORDER BY sort_order DESC
OFFSET $4::int
LIMIT $5::int
`
type ListProfilePhotosParams struct {
OwnerPeerType string
OwnerPeerID int64
MaxID int64
OffsetCount int32
LimitCount int32
}
func (q *Queries) ListProfilePhotos(ctx context.Context, arg ListProfilePhotosParams) ([]int64, error) {
rows, err := q.db.Query(ctx, listProfilePhotos,
arg.OwnerPeerType,
arg.OwnerPeerID,
arg.MaxID,
arg.OffsetCount,
arg.LimitCount,
)
if err != nil {
return nil, err
}
defer rows.Close()
var items []int64
for rows.Next() {
var photo_id int64
if err := rows.Scan(&photo_id); err != nil {
return nil, err
}
items = append(items, photo_id)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listStickerSetsByKind = `-- name: ListStickerSetsByKind :many
SELECT
id, access_hash, short_name, title, count, hash, set_kind,
official, animated, videos, emojis, masks, installed, archived, installed_date,
thumb_document_id, thumbs::text AS thumbs_json, thumb_dc_id, thumb_version,
document_ids::text AS document_ids_json, packs::text AS packs_json, sort_order, system_key
FROM sticker_sets
WHERE set_kind = $1::text
ORDER BY sort_order ASC, id ASC
`
type ListStickerSetsByKindRow struct {
ID int64
AccessHash int64
ShortName string
Title string
Count int32
Hash int32
SetKind string
Official bool
Animated bool
Videos bool
Emojis bool
Masks bool
Installed bool
Archived bool
InstalledDate int32
ThumbDocumentID int64
ThumbsJson string
ThumbDcID int32
ThumbVersion int32
DocumentIdsJson string
PacksJson string
SortOrder int32
SystemKey string
}
func (q *Queries) ListStickerSetsByKind(ctx context.Context, setKind string) ([]ListStickerSetsByKindRow, error) {
rows, err := q.db.Query(ctx, listStickerSetsByKind, setKind)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListStickerSetsByKindRow
for rows.Next() {
var i ListStickerSetsByKindRow
if err := rows.Scan(
&i.ID,
&i.AccessHash,
&i.ShortName,
&i.Title,
&i.Count,
&i.Hash,
&i.SetKind,
&i.Official,
&i.Animated,
&i.Videos,
&i.Emojis,
&i.Masks,
&i.Installed,
&i.Archived,
&i.InstalledDate,
&i.ThumbDocumentID,
&i.ThumbsJson,
&i.ThumbDcID,
&i.ThumbVersion,
&i.DocumentIdsJson,
&i.PacksJson,
&i.SortOrder,
&i.SystemKey,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const listUploadParts = `-- name: ListUploadParts :many
SELECT part, total_parts, is_big, backend, object_key, size, sha256
FROM upload_parts
WHERE owner_user_id = $1::bigint
AND file_id = $2::bigint
ORDER BY part ASC
`
type ListUploadPartsParams struct {
OwnerUserID int64
FileID int64
}
type ListUploadPartsRow struct {
Part int32
TotalParts int32
IsBig bool
Backend string
ObjectKey string
Size int64
Sha256 []byte
}
func (q *Queries) ListUploadParts(ctx context.Context, arg ListUploadPartsParams) ([]ListUploadPartsRow, error) {
rows, err := q.db.Query(ctx, listUploadParts, arg.OwnerUserID, arg.FileID)
if err != nil {
return nil, err
}
defer rows.Close()
var items []ListUploadPartsRow
for rows.Next() {
var i ListUploadPartsRow
if err := rows.Scan(
&i.Part,
&i.TotalParts,
&i.IsBig,
&i.Backend,
&i.ObjectKey,
&i.Size,
&i.Sha256,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const nextProfilePhotoOrder = `-- name: NextProfilePhotoOrder :one
SELECT COALESCE(MAX(sort_order), 0)::bigint AS max_order
FROM profile_photos
WHERE owner_peer_type = $1::text
AND owner_peer_id = $2::bigint
`
type NextProfilePhotoOrderParams struct {
OwnerPeerType string
OwnerPeerID int64
}
func (q *Queries) NextProfilePhotoOrder(ctx context.Context, arg NextProfilePhotoOrderParams) (int64, error) {
row := q.db.QueryRow(ctx, nextProfilePhotoOrder, arg.OwnerPeerType, arg.OwnerPeerID)
var max_order int64
err := row.Scan(&max_order)
return max_order, err
}
const orphanDocumentIfUnreferenced = `-- name: OrphanDocumentIfUnreferenced :exec
UPDATE documents SET orphaned_at = now()
WHERE id = $1::bigint
AND orphaned_at IS NULL
AND NOT EXISTS (
SELECT 1 FROM media_references WHERE media_kind = 'document' AND media_id = $1::bigint
)
`
func (q *Queries) OrphanDocumentIfUnreferenced(ctx context.Context, mediaID int64) error {
_, err := q.db.Exec(ctx, orphanDocumentIfUnreferenced, mediaID)
return err
}
const orphanPhotoIfUnreferenced = `-- name: OrphanPhotoIfUnreferenced :exec
UPDATE photos SET orphaned_at = now()
WHERE id = $1::bigint
AND orphaned_at IS NULL
AND NOT EXISTS (
SELECT 1 FROM media_references WHERE media_kind = 'photo' AND media_id = $1::bigint
)
`
func (q *Queries) OrphanPhotoIfUnreferenced(ctx context.Context, mediaID int64) error {
_, err := q.db.Exec(ctx, orphanPhotoIfUnreferenced, mediaID)
return err
}
const putAvailableReaction = `-- name: PutAvailableReaction :exec
INSERT INTO available_reactions (
reaction, title, inactive, premium,
static_icon_id, appear_animation_id, select_animation_id,
activate_animation_id, effect_animation_id, around_animation_id, center_icon_id, sort_order
) VALUES (
$1::text,
$2::text,
$3::boolean,
$4::boolean,
$5::bigint,
$6::bigint,
$7::bigint,
$8::bigint,
$9::bigint,
$10::bigint,
$11::bigint,
$12::int
)
ON CONFLICT (reaction) DO UPDATE SET
title = EXCLUDED.title,
inactive = EXCLUDED.inactive,
premium = EXCLUDED.premium,
static_icon_id = EXCLUDED.static_icon_id,
appear_animation_id = EXCLUDED.appear_animation_id,
select_animation_id = EXCLUDED.select_animation_id,
activate_animation_id = EXCLUDED.activate_animation_id,
effect_animation_id = EXCLUDED.effect_animation_id,
around_animation_id = EXCLUDED.around_animation_id,
center_icon_id = EXCLUDED.center_icon_id,
sort_order = EXCLUDED.sort_order
`
type PutAvailableReactionParams struct {
Reaction string
Title string
Inactive bool
Premium bool
StaticIconID int64
AppearAnimationID int64
SelectAnimationID int64
ActivateAnimationID int64
EffectAnimationID int64
AroundAnimationID int64
CenterIconID int64
SortOrder int32
}
// available_reactions ---------------------------------------------------------
func (q *Queries) PutAvailableReaction(ctx context.Context, arg PutAvailableReactionParams) error {
_, err := q.db.Exec(ctx, putAvailableReaction,
arg.Reaction,
arg.Title,
arg.Inactive,
arg.Premium,
arg.StaticIconID,
arg.AppearAnimationID,
arg.SelectAnimationID,
arg.ActivateAnimationID,
arg.EffectAnimationID,
arg.AroundAnimationID,
arg.CenterIconID,
arg.SortOrder,
)
return err
}
const putDocument = `-- name: PutDocument :exec
INSERT INTO documents (id, access_hash, file_reference, date, mime_type, size, dc_id, attributes, thumbs, owner_user_id)
VALUES (
$1::bigint,
$2::bigint,
$3::bytea,
$4::int,
$5::text,
$6::bigint,
$7::int,
$8::jsonb,
$9::jsonb,
$10::bigint
)
ON CONFLICT (id) DO UPDATE SET
access_hash = EXCLUDED.access_hash,
file_reference = EXCLUDED.file_reference,
date = EXCLUDED.date,
mime_type = EXCLUDED.mime_type,
size = EXCLUDED.size,
dc_id = EXCLUDED.dc_id,
attributes = EXCLUDED.attributes,
thumbs = EXCLUDED.thumbs
`
type PutDocumentParams struct {
ID int64
AccessHash int64
FileReference []byte
Date int32
MimeType string
Size int64
DcID int32
AttributesJson []byte
ThumbsJson []byte
OwnerUserID int64
}
// documents -------------------------------------------------------------------
// owner_user_id is intentionally NOT in the UPDATE SET list: a document id is
// only ever (re-)upserted by its original uploader's own request replay, and
// keeping the first-write owner sticky avoids any risk of a later call
// (e.g. a forward re-touching the row) reassigning ownership.
func (q *Queries) PutDocument(ctx context.Context, arg PutDocumentParams) error {
_, err := q.db.Exec(ctx, putDocument,
arg.ID,
arg.AccessHash,
arg.FileReference,
arg.Date,
arg.MimeType,
arg.Size,
arg.DcID,
arg.AttributesJson,
arg.ThumbsJson,
arg.OwnerUserID,
)
return err
}
const putFileBlob = `-- name: PutFileBlob :exec
INSERT INTO file_blobs (location_key, backend, object_key, size, sha256, mime_type)
VALUES (
$1::text,
$2::text,
$3::text,
$4::bigint,
$5::bytea,
$6::text
)
ON CONFLICT (location_key) DO UPDATE SET
backend = EXCLUDED.backend,
object_key = EXCLUDED.object_key,
size = EXCLUDED.size,
sha256 = EXCLUDED.sha256,
mime_type = EXCLUDED.mime_type
`
type PutFileBlobParams struct {
LocationKey string
Backend string
ObjectKey string
Size int64
Sha256 []byte
MimeType string
}
// file_blobs ------------------------------------------------------------------
func (q *Queries) PutFileBlob(ctx context.Context, arg PutFileBlobParams) error {
_, err := q.db.Exec(ctx, putFileBlob,
arg.LocationKey,
arg.Backend,
arg.ObjectKey,
arg.Size,
arg.Sha256,
arg.MimeType,
)
return err
}
const putPhoto = `-- name: PutPhoto :exec
INSERT INTO photos (id, access_hash, file_reference, date, dc_id, has_stickers, sizes, owner_user_id)
VALUES (
$1::bigint,
$2::bigint,
$3::bytea,
$4::int,
$5::int,
$6::boolean,
$7::jsonb,
$8::bigint
)
ON CONFLICT (id) DO UPDATE SET
access_hash = EXCLUDED.access_hash,
file_reference = EXCLUDED.file_reference,
date = EXCLUDED.date,
dc_id = EXCLUDED.dc_id,
has_stickers = EXCLUDED.has_stickers,
sizes = EXCLUDED.sizes
`
type PutPhotoParams struct {
ID int64
AccessHash int64
FileReference []byte
Date int32
DcID int32
HasStickers bool
SizesJson []byte
OwnerUserID int64
}
// photos ----------------------------------------------------------------------
// owner_user_id intentionally not updated on conflict, see PutDocument.
func (q *Queries) PutPhoto(ctx context.Context, arg PutPhotoParams) error {
_, err := q.db.Exec(ctx, putPhoto,
arg.ID,
arg.AccessHash,
arg.FileReference,
arg.Date,
arg.DcID,
arg.HasStickers,
arg.SizesJson,
arg.OwnerUserID,
)
return err
}
const putStickerSet = `-- name: PutStickerSet :exec
INSERT INTO sticker_sets (
id, access_hash, short_name, title, count, hash, set_kind,
official, animated, videos, emojis, masks, installed, archived, installed_date,
thumb_document_id, thumbs, thumb_dc_id, thumb_version, document_ids, packs, sort_order, system_key
) VALUES (
$1::bigint,
$2::bigint,
$3::text,
$4::text,
$5::int,
$6::int,
$7::text,
$8::boolean,
$9::boolean,
$10::boolean,
$11::boolean,
$12::boolean,
$13::boolean,
$14::boolean,
$15::int,
$16::bigint,
$17::jsonb,
$18::int,
$19::int,
$20::jsonb,
$21::jsonb,
$22::int,
$23::text
)
ON CONFLICT (id) DO UPDATE SET
access_hash = EXCLUDED.access_hash,
short_name = EXCLUDED.short_name,
title = EXCLUDED.title,
count = EXCLUDED.count,
hash = EXCLUDED.hash,
set_kind = EXCLUDED.set_kind,
official = EXCLUDED.official,
animated = EXCLUDED.animated,
videos = EXCLUDED.videos,
emojis = EXCLUDED.emojis,
masks = EXCLUDED.masks,
installed = EXCLUDED.installed,
archived = EXCLUDED.archived,
installed_date = EXCLUDED.installed_date,
thumb_document_id = EXCLUDED.thumb_document_id,
thumbs = EXCLUDED.thumbs,
thumb_dc_id = EXCLUDED.thumb_dc_id,
thumb_version = EXCLUDED.thumb_version,
document_ids = EXCLUDED.document_ids,
packs = EXCLUDED.packs,
sort_order = EXCLUDED.sort_order,
system_key = EXCLUDED.system_key
`
type PutStickerSetParams struct {
ID int64
AccessHash int64
ShortName string
Title string
Count int32
Hash int32
SetKind string
Official bool
Animated bool
Videos bool
Emojis bool
Masks bool
Installed bool
Archived bool
InstalledDate int32
ThumbDocumentID int64
ThumbsJson []byte
ThumbDcID int32
ThumbVersion int32
DocumentIdsJson []byte
PacksJson []byte
SortOrder int32
SystemKey string
}
// sticker_sets ----------------------------------------------------------------
func (q *Queries) PutStickerSet(ctx context.Context, arg PutStickerSetParams) error {
_, err := q.db.Exec(ctx, putStickerSet,
arg.ID,
arg.AccessHash,
arg.ShortName,
arg.Title,
arg.Count,
arg.Hash,
arg.SetKind,
arg.Official,
arg.Animated,
arg.Videos,
arg.Emojis,
arg.Masks,
arg.Installed,
arg.Archived,
arg.InstalledDate,
arg.ThumbDocumentID,
arg.ThumbsJson,
arg.ThumbDcID,
arg.ThumbVersion,
arg.DocumentIdsJson,
arg.PacksJson,
arg.SortOrder,
arg.SystemKey,
)
return err
}
const removeMediaReference = `-- name: RemoveMediaReference :exec
DELETE FROM media_references
WHERE media_kind = $1::text
AND media_id = $2::bigint
AND ref_kind = $3::text
AND ref_key = $4::text
`
type RemoveMediaReferenceParams struct {
MediaKind string
MediaID int64
RefKind string
RefKey string
}
func (q *Queries) RemoveMediaReference(ctx context.Context, arg RemoveMediaReferenceParams) error {
_, err := q.db.Exec(ctx, removeMediaReference,
arg.MediaKind,
arg.MediaID,
arg.RefKind,
arg.RefKey,
)
return err
}
const saveUploadPart = `-- name: SaveUploadPart :exec
INSERT INTO upload_parts (owner_user_id, file_id, part, total_parts, is_big, backend, object_key, size, sha256)
VALUES (
$1::bigint,
$2::bigint,
$3::int,
$4::int,
$5::boolean,
$6::text,
$7::text,
$8::bigint,
$9::bytea
)
ON CONFLICT (owner_user_id, file_id, part) DO UPDATE SET
total_parts = EXCLUDED.total_parts,
is_big = EXCLUDED.is_big,
backend = EXCLUDED.backend,
object_key = EXCLUDED.object_key,
size = EXCLUDED.size,
sha256 = EXCLUDED.sha256,
created_at = now()
`
type SaveUploadPartParams struct {
OwnerUserID int64
FileID int64
Part int32
TotalParts int32
IsBig bool
Backend string
ObjectKey string
Size int64
Sha256 []byte
}
// upload_parts ----------------------------------------------------------------
func (q *Queries) SaveUploadPart(ctx context.Context, arg SaveUploadPartParams) error {
_, err := q.db.Exec(ctx, saveUploadPart,
arg.OwnerUserID,
arg.FileID,
arg.Part,
arg.TotalParts,
arg.IsBig,
arg.Backend,
arg.ObjectKey,
arg.Size,
arg.Sha256,
)
return err
}
const sumFileBlobBytes = `-- name: SumFileBlobBytes :one
SELECT COALESCE(SUM(size), 0)::bigint FROM file_blobs
`
// Physical bytes actually held by the blob backend (dedup-aware: identical
// content uploaded by different users is one row here). Used by the
// low-space guard's cached usage gauge and the admin panel's "physical
// usage" stat.
func (q *Queries) SumFileBlobBytes(ctx context.Context) (int64, error) {
row := q.db.QueryRow(ctx, sumFileBlobBytes)
var column_1 int64
err := row.Scan(&column_1)
return column_1, err
}