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 pl ON pl.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), } }