92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
package database
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
|
|
"github.com/TelegramExchange/pkg/transaction"
|
|
"github.com/TelegramExchange/tgex-backend/tg_parser/internal/domain"
|
|
)
|
|
|
|
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)
|
|
WHEN c.telegram_id IS NOT NULL THEN CONCAT('https://t.me/c/', (-c.telegram_id - 1000000000000), '/', 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),
|
|
}
|
|
}
|