package repositories import ( "context" "fmt" sq "github.com/Masterminds/squirrel" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/helpers/errors" "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/models" ) const articleTableName = "article" var articleTableColumns = []string{ "id", "url", "publish_time", "title", "image", "text", "preview_text", "meta_keywords", "meta_desc", "is_active", "language", } type ArticleRepository struct { db DB } func InitArticleRepository(db DB) *ArticleRepository { return &ArticleRepository{db: db} } func (a ArticleRepository) GetAllPreview( // TESTED ctx context.Context, lang models.LanguageID, ) ([]models.ArticlePreview, error) { var res []models.ArticlePreview q, v, err := sq.Select("id", "url", "publish_time", "title", "preview_text", "image"). From(articleTableName). PlaceholderFormat(sq.Question). Where(sq.Eq{"is_active": true, "language": uint64(lang)}). OrderBy("publish_time DESC"). ToSql() if err != nil { return nil, errors.Wrap(err, "build query") } err = a.db.SelectContext(ctx, &res, q, v...) if err != nil { return nil, errors.Wrap(err, "select") } return res, nil } func (a ArticleRepository) GetAll(ctx context.Context) ([]models.Article, error) { // TESTED var res []models.Article q, v, err := sq.Select(articleTableColumns...). From(articleTableName). OrderBy("publish_time DESC"). ToSql() if err != nil { return nil, errors.Wrap(err, "build query") } err = a.db.SelectContext(ctx, &res, q, v...) if err != nil { return nil, errors.Wrap(err, "select") } return res, nil } func (a ArticleRepository) GetPreviewByTagID( // TESTED ctx context.Context, tagID uint64, lang models.LanguageID, ) ([]models.ArticlePreview, error) { var res []models.ArticlePreview q := "SELECT a.id, a.url, a.publish_time, a.title, a.preview_text, a.image " + "FROM " + articleTableName + " a, " + articleTagTableName + " at " + "WHERE a.is_active = true AND a.language = ? AND at.article_id = a.id AND at.tag_id = ? " + "ORDER BY a.publish_time DESC" err := a.db.SelectContext(ctx, &res, q, uint64(lang), tagID) if err != nil { return nil, errors.Wrap(err, "select") } return res, nil } func (a ArticleRepository) GetByURL( // TESTED ctx context.Context, url string, ) (*models.Article, error) { var res models.Article q, v, err := sq.Select(articleTableColumns...). From(articleTableName). PlaceholderFormat(sq.Question). Where(sq.Eq{"url": url}). Limit(1). ToSql() if err != nil { return nil, errors.Wrap(err, "build query") } err = a.db.GetContext(ctx, &res, q, v...) if err != nil { return nil, errors.Wrap(err, "get") } return &res, nil } func (a ArticleRepository) GetByID( // TESTED ctx context.Context, id uint64, ) (*models.Article, error) { var res models.Article q, v, err := sq.Select(articleTableColumns...). From(articleTableName). PlaceholderFormat(sq.Question). Where(sq.Eq{"id": id}). Limit(1). ToSql() if err != nil { return nil, errors.Wrap(err, "build query") } err = a.db.GetContext(ctx, &res, q, v...) if err != nil { return nil, errors.Wrap(err, "get") } return &res, nil } func (a ArticleRepository) Add( ctx context.Context, m models.Article, ) (uint64, error) { q, v, err := sq.Insert(articleTableName). PlaceholderFormat(sq.Question). Columns( "url", "publish_time", "title", "image", "text", "preview_text", "meta_keywords", "meta_desc", "is_active", "language", ).Values( m.URL, m.PublishTime, m.Title, m.Image, m.Text, m.PreviewText, m.MetaKeywords, m.MetaDescription, m.IsActive, m.Language, ). Suffix("RETURNING id"). ToSql() if err != nil { return 0, fmt.Errorf("build query: %w", err) } var id uint64 err = a.db.QueryRowContext(ctx, q, v...).Scan(&id) if err != nil { return 0, fmt.Errorf("query row: %w", err) } return id, nil } func (a ArticleRepository) Update(ctx context.Context, req models.Article) error { q, v, err := sq.Update(articleTableName). PlaceholderFormat(sq.Question). Set("url", req.URL). Set("publish_time", req.PublishTime). Set("title", req.Title). Set("image", req.Image). Set("text", req.Text). Set("preview_text", req.PreviewText). Set("meta_keywords", req.MetaKeywords). Set("meta_desc", req.MetaDescription). Set("is_active", req.IsActive). Where(sq.Eq{"id": req.ID}). ToSql() if err != nil { return fmt.Errorf("build query: %w", err) } _, err = a.db.ExecContext(ctx, q, v...) if err != nil { return fmt.Errorf("exec: %w", err) } return nil } func (a ArticleRepository) Delete(ctx context.Context, id uint64) error { q, v, err := sq.Delete(articleTableName). PlaceholderFormat(sq.Question). Where(sq.Eq{"id": id}). ToSql() if err != nil { return fmt.Errorf("build query: %w", err) } _, err = a.db.ExecContext(ctx, q, v...) if err != nil { return fmt.Errorf("exec: %w", err) } return nil }