tag.go 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. package repositories
  2. //go:generate mkdir -p mocks
  3. //go:generate rm -rf ./mocks/*_minimock.go
  4. //go:generate minimock -i github.com/dmitriygnatenko/internal/interfaces.TagRepository -o ./mocks/ -s "_minimock.go"
  5. import (
  6. "context"
  7. "database/sql"
  8. sq "github.com/Masterminds/squirrel"
  9. "github.com/dmitriygnatenko/internal/interfaces"
  10. "github.com/dmitriygnatenko/internal/models"
  11. )
  12. const tagTableName = "tag"
  13. type tagRepository struct {
  14. db *sql.DB
  15. }
  16. func InitTagRepository(db *sql.DB) interfaces.TagRepository {
  17. return tagRepository{db: db}
  18. }
  19. func (t tagRepository) GetAllUsed(ctx context.Context) ([]models.Tag, error) {
  20. var res []models.Tag
  21. query := "SELECT t.id, t.url, t.tag " +
  22. "FROM " + articleTagTableName + " at, " + tagTableName + " t " +
  23. "WHERE t.id = at.tag_id AND at.article_id IN " +
  24. "(SELECT id FROM " + articleTableName + " " + "WHERE is_active = true) " +
  25. "GROUP BY t.id"
  26. rows, err := t.db.QueryContext(ctx, query)
  27. if err != nil {
  28. return nil, err
  29. }
  30. defer rows.Close()
  31. for rows.Next() {
  32. row := models.Tag{}
  33. err = rows.Scan(&row.ID, &row.URL, &row.Tag)
  34. if err != nil {
  35. return nil, err
  36. }
  37. res = append(res, row)
  38. }
  39. if err = rows.Err(); err != nil {
  40. return nil, err
  41. }
  42. return res, nil
  43. }
  44. func (t tagRepository) GetByURL(ctx context.Context, url string) (*models.Tag, error) {
  45. query, args, err := sq.Select("id", "url", "tag").
  46. From(tagTableName).
  47. PlaceholderFormat(sq.Dollar).
  48. Where(sq.Eq{"url": url}).
  49. Limit(1).
  50. ToSql()
  51. if err != nil {
  52. return nil, err
  53. }
  54. var res models.Tag
  55. err = t.db.QueryRowContext(ctx, query, args...).
  56. Scan(&res.ID, &res.URL, &res.Tag)
  57. if err != nil {
  58. return nil, err
  59. }
  60. return &res, nil
  61. }
  62. func (t tagRepository) GetByID(ctx context.Context, id int) (*models.Tag, error) {
  63. query, args, err := sq.Select("id", "url", "tag").
  64. From(tagTableName).
  65. PlaceholderFormat(sq.Dollar).
  66. Where(sq.Eq{"id": id}).
  67. Limit(1).
  68. ToSql()
  69. if err != nil {
  70. return nil, err
  71. }
  72. var res models.Tag
  73. err = t.db.QueryRowContext(ctx, query, args...).
  74. Scan(&res.ID, &res.URL, &res.Tag)
  75. if err != nil {
  76. return nil, err
  77. }
  78. return &res, nil
  79. }
  80. func (t tagRepository) GetAll(ctx context.Context) ([]models.Tag, error) {
  81. var res []models.Tag
  82. query, args, err := sq.Select("id", "url", "tag").
  83. From(tagTableName).
  84. ToSql()
  85. if err != nil {
  86. return nil, err
  87. }
  88. rows, err := t.db.QueryContext(ctx, query, args...)
  89. if err != nil {
  90. return nil, err
  91. }
  92. defer rows.Close()
  93. for rows.Next() {
  94. row := models.Tag{}
  95. err = rows.Scan(&row.ID, &row.URL, &row.Tag)
  96. if err != nil {
  97. return nil, err
  98. }
  99. res = append(res, row)
  100. }
  101. if err = rows.Err(); err != nil {
  102. return nil, err
  103. }
  104. return res, nil
  105. }
  106. func (t tagRepository) GetByArticleID(ctx context.Context, id int) ([]models.Tag, error) {
  107. var res []models.Tag
  108. query := "SELECT t.id, t.url, t.tag " +
  109. "FROM " + articleTagTableName + " at, " + tagTableName + " t " +
  110. "WHERE t.id = at.tag_id AND at.article_id = ?"
  111. rows, err := t.db.QueryContext(ctx, query, id)
  112. if err != nil {
  113. return nil, err
  114. }
  115. defer rows.Close()
  116. for rows.Next() {
  117. row := models.Tag{}
  118. err = rows.Scan(&row.ID, &row.URL, &row.Tag)
  119. if err != nil {
  120. return nil, err
  121. }
  122. res = append(res, row)
  123. }
  124. if err = rows.Err(); err != nil {
  125. return nil, err
  126. }
  127. return res, nil
  128. }
  129. func (t tagRepository) IsUsed(ctx context.Context, id int) (bool, error) {
  130. var count int
  131. query := "SELECT COUNT(tag_id) FROM " + articleTagTableName + " WHERE tag_id = ?"
  132. if err := t.db.QueryRowContext(ctx, query, id).Scan(&count); err != nil {
  133. return false, err
  134. }
  135. return count > 0, nil
  136. }
  137. func (t tagRepository) Add(ctx context.Context, req models.Tag) error {
  138. query, args, err := sq.Insert(tagTableName).
  139. PlaceholderFormat(sq.Dollar).
  140. Columns("tag", "url").
  141. Values(req.Tag, req.URL).
  142. ToSql()
  143. if err != nil {
  144. return err
  145. }
  146. _, err = t.db.ExecContext(ctx, query, args...)
  147. return err
  148. }
  149. func (t tagRepository) Update(ctx context.Context, req models.Tag) error {
  150. query, args, err := sq.Update(tagTableName).
  151. PlaceholderFormat(sq.Dollar).
  152. Set("tag", req.Tag).
  153. Set("url", req.URL).
  154. Where(sq.Eq{"id": req.ID}).
  155. ToSql()
  156. if err != nil {
  157. return err
  158. }
  159. _, err = t.db.ExecContext(ctx, query, args...)
  160. return err
  161. }
  162. func (t tagRepository) Delete(ctx context.Context, id int) error {
  163. query, args, err := sq.Delete(tagTableName).
  164. PlaceholderFormat(sq.Dollar).
  165. Where(sq.Eq{"id": id}).
  166. ToSql()
  167. if err != nil {
  168. return err
  169. }
  170. _, err = t.db.ExecContext(ctx, query, args...)
  171. return err
  172. }