package repositories //go:generate mkdir -p mocks //go:generate rm -rf ./mocks/*_minimock.go //go:generate minimock -i github.com/dmitriygnatenko/internal/interfaces.TagRepository -o ./mocks/ -s "_minimock.go" import ( "context" "database/sql" sq "github.com/Masterminds/squirrel" "github.com/dmitriygnatenko/internal/interfaces" "github.com/dmitriygnatenko/internal/models" ) const tagTableName = "tag" type tagRepository struct { db *sql.DB } func InitTagRepository(db *sql.DB) interfaces.TagRepository { return tagRepository{db: db} } func (t tagRepository) GetAllUsed(ctx context.Context) ([]models.Tag, error) { var res []models.Tag query := "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" rows, err := t.db.QueryContext(ctx, query) if err != nil { return nil, err } defer rows.Close() for rows.Next() { row := models.Tag{} err = rows.Scan(&row.ID, &row.URL, &row.Tag) if err != nil { return nil, err } res = append(res, row) } if err = rows.Err(); err != nil { return nil, err } return res, nil } func (t tagRepository) GetByURL(ctx context.Context, url string) (*models.Tag, error) { query, args, err := sq.Select("id", "url", "tag"). From(tagTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"url": url}). Limit(1). ToSql() if err != nil { return nil, err } var res models.Tag err = t.db.QueryRowContext(ctx, query, args...). Scan(&res.ID, &res.URL, &res.Tag) if err != nil { return nil, err } return &res, nil } func (t tagRepository) GetByID(ctx context.Context, id int) (*models.Tag, error) { query, args, err := sq.Select("id", "url", "tag"). From(tagTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"id": id}). Limit(1). ToSql() if err != nil { return nil, err } var res models.Tag err = t.db.QueryRowContext(ctx, query, args...). Scan(&res.ID, &res.URL, &res.Tag) if err != nil { return nil, err } return &res, nil } func (t tagRepository) GetAll(ctx context.Context) ([]models.Tag, error) { var res []models.Tag query, args, err := sq.Select("id", "url", "tag"). From(tagTableName). ToSql() if err != nil { return nil, err } rows, err := t.db.QueryContext(ctx, query, args...) if err != nil { return nil, err } defer rows.Close() for rows.Next() { row := models.Tag{} err = rows.Scan(&row.ID, &row.URL, &row.Tag) if err != nil { return nil, err } res = append(res, row) } if err = rows.Err(); err != nil { return nil, err } return res, nil } func (t tagRepository) GetByArticleID(ctx context.Context, id int) ([]models.Tag, error) { var res []models.Tag query := "SELECT t.id, t.url, t.tag " + "FROM " + articleTagTableName + " at, " + tagTableName + " t " + "WHERE t.id = at.tag_id AND at.article_id = ?" rows, err := t.db.QueryContext(ctx, query, id) if err != nil { return nil, err } defer rows.Close() for rows.Next() { row := models.Tag{} err = rows.Scan(&row.ID, &row.URL, &row.Tag) if err != nil { return nil, err } res = append(res, row) } if err = rows.Err(); err != nil { return nil, err } return res, nil } func (t tagRepository) IsUsed(ctx context.Context, id int) (bool, error) { var count int query := "SELECT COUNT(tag_id) FROM " + articleTagTableName + " WHERE tag_id = ?" if err := t.db.QueryRowContext(ctx, query, id).Scan(&count); err != nil { return false, err } return count > 0, nil } func (t tagRepository) Add(ctx context.Context, req models.Tag) error { query, args, err := sq.Insert(tagTableName). PlaceholderFormat(sq.Dollar). Columns("tag", "url"). Values(req.Tag, req.URL). ToSql() if err != nil { return err } _, err = t.db.ExecContext(ctx, query, args...) return err } func (t tagRepository) Update(ctx context.Context, req models.Tag) error { query, args, 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 err } _, err = t.db.ExecContext(ctx, query, args...) return err } func (t tagRepository) Delete(ctx context.Context, id int) error { query, args, err := sq.Delete(tagTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"id": id}). ToSql() if err != nil { return err } _, err = t.db.ExecContext(ctx, query, args...) return err }