package repositories import ( "context" "fmt" sq "github.com/Masterminds/squirrel" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/models" ) const tagTableName = "tag" type TagRepository struct { db DB } func InitTagRepository(db DB) *TagRepository { return &TagRepository{db: db} } func (t TagRepository) GetAllUsed(ctx context.Context) ([]models.Tag, error) { var res []models.Tag q := "SELECT t.id, t.url, t.tag " + "FROM " + articleTagTableName + " at, " + tagTableName + " t " + "WHERE t.id = at.tag_id AND at.article_id IN " + "(SELECT id FROM " + articleTableName + " " + "WHERE is_active = true) " + "GROUP BY t.id" err := t.db.SelectContext(ctx, &res, q) if err != nil { return nil, fmt.Errorf("select: %w", err) } return res, nil } func (t TagRepository) GetByURL(ctx context.Context, url string) (*models.Tag, error) { var res models.Tag q, v, err := sq.Select("id", "url", "tag"). From(tagTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"url": url}). Limit(1). ToSql() if err != nil { return nil, fmt.Errorf("build query: %w", err) } err = t.db.GetContext(ctx, &res, q, v...) if err != nil { return nil, fmt.Errorf("get: %w", err) } return &res, nil } func (t TagRepository) GetByID(ctx context.Context, id uint64) (*models.Tag, error) { var res models.Tag q, v, err := sq.Select("id", "url", "tag"). From(tagTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"id": id}). Limit(1). ToSql() if err != nil { return nil, fmt.Errorf("build query: %w", err) } err = t.db.GetContext(ctx, &res, q, v...) if err != nil { return nil, fmt.Errorf("get: %w", err) } return &res, nil } func (t TagRepository) GetAll(ctx context.Context) ([]models.Tag, error) { var res []models.Tag q, v, err := sq.Select("id", "url", "tag"). From(tagTableName). ToSql() if err != nil { return nil, fmt.Errorf("build query: %w", err) } err = t.db.SelectContext(ctx, &res, q, v...) if err != nil { return nil, fmt.Errorf("select: %w", err) } return res, nil } func (t TagRepository) GetByArticleID(ctx context.Context, id uint64) ([]models.Tag, error) { var res []models.Tag q := "SELECT t.id, t.url, t.tag " + "FROM " + articleTagTableName + " at, " + tagTableName + " t " + "WHERE t.id = at.tag_id AND at.article_id = $1" err := t.db.SelectContext(ctx, &res, q, id) if err != nil { return nil, fmt.Errorf("select: %w", err) } return res, nil } func (t TagRepository) IsUsed(ctx context.Context, id uint64) (bool, error) { query, args, err := sq.Select("COUNT(tag_id)"). From(articleTagTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"tag_id": id}). ToSql() if err != nil { return false, fmt.Errorf("build query: %w", err) } var count int err = t.db.QueryRowContext(ctx, query, args...).Scan(&count) if err != nil { return false, err } return count > 0, nil } func (t TagRepository) Add(ctx context.Context, req models.Tag) error { q, v, err := sq.Insert(tagTableName). PlaceholderFormat(sq.Dollar). Columns("tag", "url"). Values(req.Tag, req.URL). ToSql() if err != nil { return fmt.Errorf("build query: %w", err) } _, err = t.db.ExecContext(ctx, q, v...) if err != nil { return fmt.Errorf("exec: %w", err) } return nil } func (t TagRepository) Update(ctx context.Context, req models.Tag) error { q, v, err := sq.Update(tagTableName). PlaceholderFormat(sq.Dollar). Set("tag", req.Tag). Set("url", req.URL). Where(sq.Eq{"id": req.ID}). ToSql() if err != nil { return fmt.Errorf("build query: %w", err) } _, err = t.db.ExecContext(ctx, q, v...) if err != nil { return fmt.Errorf("exec: %w", err) } return nil } func (t TagRepository) Delete(ctx context.Context, id uint64) error { q, v, err := sq.Delete(tagTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"id": id}). ToSql() if err != nil { return fmt.Errorf("build query: %w", err) } _, err = t.db.ExecContext(ctx, q, v...) if err != nil { return fmt.Errorf("exec: %w", err) } return nil }