1668 lines
40 KiB
Go
1668 lines
40 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 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 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 listDocumentIDsForHardRetentionOlderThan = `-- name: ListDocumentIDsForHardRetentionOlderThan :many
|
|
SELECT d.id FROM documents d
|
|
WHERE d.created_at < $1::timestamptz
|
|
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 $2::int
|
|
`
|
|
|
|
type ListDocumentIDsForHardRetentionOlderThanParams struct {
|
|
Cutoff pgtype.Timestamptz
|
|
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.
|
|
func (q *Queries) ListDocumentIDsForHardRetentionOlderThan(ctx context.Context, arg ListDocumentIDsForHardRetentionOlderThanParams) ([]int64, error) {
|
|
rows, err := q.db.Query(ctx, listDocumentIDsForHardRetentionOlderThan, 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 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 listOrphanedDocumentIDsOlderThan = `-- name: ListOrphanedDocumentIDsOlderThan :many
|
|
SELECT id FROM documents
|
|
WHERE orphaned_at IS NOT NULL AND orphaned_at < $1::timestamptz
|
|
ORDER BY orphaned_at ASC
|
|
LIMIT $2::int
|
|
`
|
|
|
|
type ListOrphanedDocumentIDsOlderThanParams struct {
|
|
Cutoff pgtype.Timestamptz
|
|
BatchLimit int32
|
|
}
|
|
|
|
func (q *Queries) ListOrphanedDocumentIDsOlderThan(ctx context.Context, arg ListOrphanedDocumentIDsOlderThanParams) ([]int64, error) {
|
|
rows, err := q.db.Query(ctx, listOrphanedDocumentIDsOlderThan, 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 listOrphanedPhotoIDsOlderThan = `-- name: ListOrphanedPhotoIDsOlderThan :many
|
|
SELECT id FROM photos
|
|
WHERE orphaned_at IS NOT NULL AND orphaned_at < $1::timestamptz
|
|
ORDER BY orphaned_at ASC
|
|
LIMIT $2::int
|
|
`
|
|
|
|
type ListOrphanedPhotoIDsOlderThanParams struct {
|
|
Cutoff pgtype.Timestamptz
|
|
BatchLimit int32
|
|
}
|
|
|
|
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 p.created_at < $1::timestamptz
|
|
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, for photos.
|
|
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
|
|
}
|