Files
tgex-backend/tg_parser/internal/adapter/database/get_tracked_posts.go
2026-01-18 13:38:25 +03:00

91 lines
2.0 KiB
Go

package database
import (
"context"
"fmt"
"github.com/jackc/pgx/v5/pgtype"
"github.com/TelegramExchange/tgex-parser/internal/domain"
"github.com/TelegramExchange/tgex-parser/pkg/transaction"
)
func (d *Database) GetTrackedPosts(ctx context.Context, channel domain.Channel) ([]domain.Post, error) {
query := `SELECT DISTINCT
p.id,
p.channel_id,
p.message_id,
p.text,
CASE
WHEN c.username IS NOT NULL THEN CONCAT('https://t.me/', c.username, '/', p.message_id)
ELSE ''
END as link,
COALESCE(
(SELECT pvh.views_count
FROM post_views_history pvh
WHERE pvh.post_id = p.id
ORDER BY pvh.fetched_at DESC
LIMIT 1),
0
) as views
FROM post p
INNER JOIN channel c ON c.id = p.channel_id
INNER JOIN placement_post pp ON pp.post_id = p.id
WHERE p.channel_id = $1
AND p.deleted_from_channel_at IS NULL;`
txOrPool := transaction.TryExtractTX(ctx)
rows, err := txOrPool.Query(ctx, query, pgtype.UUID{Bytes: channel.ID, Valid: true})
if err != nil {
return nil, fmt.Errorf("txOrPool.Query: %w", err)
}
defer rows.Close()
posts := make([]domain.Post, 0)
for rows.Next() {
var dto getTrackedPostsDTO
err = rows.Scan(dto.destination()...)
if err != nil {
return nil, fmt.Errorf("rows.Scan: %w", err)
}
posts = append(posts, dto.toDomain())
}
return posts, nil
}
type getTrackedPostsDTO struct {
ID pgtype.UUID
ChannelID pgtype.UUID
MessageID pgtype.Int4
Text pgtype.Text
Link pgtype.Text
Views pgtype.Int4
}
func (dto *getTrackedPostsDTO) destination() []any {
return []any{
&dto.ID,
&dto.ChannelID,
&dto.MessageID,
&dto.Text,
&dto.Link,
&dto.Views,
}
}
func (dto *getTrackedPostsDTO) toDomain() domain.Post {
return domain.Post{
ID: dto.ID.Bytes,
ChannelID: dto.ChannelID.Bytes,
MessageID: int(dto.MessageID.Int32),
Text: dto.Text.String,
Link: dto.Link.String,
Views: int(dto.Views.Int32),
}
}