package repositories import ( "context" "fmt" sq "github.com/Masterminds/squirrel" "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", } type ArticleRepository struct { db DB } func InitArticleRepository(db DB) *ArticleRepository { return &ArticleRepository{db: db} } func (a ArticleRepository) GetAllPreview(ctx context.Context) ([]models.ArticlePreview, error) { var res []models.ArticlePreview q, v, err := sq.Select("id", "url", "publish_time", "title", "preview_text", "image"). From(articleTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"is_active": true}). OrderBy("publish_time DESC"). ToSql() if err != nil { return nil, fmt.Errorf("build query: %w", err) } err = a.db.SelectContext(ctx, &res, q, v...) if err != nil { return nil, fmt.Errorf("select: %w", err) } return res, nil } func (a ArticleRepository) GetAll(ctx context.Context) ([]models.Article, error) { var res []models.Article q, v, err := sq.Select(articleTableColumns...). From(articleTableName). OrderBy("publish_time DESC"). ToSql() if err != nil { return nil, fmt.Errorf("build query: %w", err) } err = a.db.SelectContext(ctx, &res, q, v...) if err != nil { return nil, fmt.Errorf("select: %w", err) } return res, nil } func (a ArticleRepository) GetPreviewByTagID(ctx context.Context, tagID uint64) ([]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 at.article_id = a.id AND at.tag_id = $1 " + "ORDER BY a.publish_time DESC" err := a.db.SelectContext(ctx, &res, q, tagID) if err != nil { return nil, fmt.Errorf("select: %w", err) } return res, nil } func (a ArticleRepository) GetByURL(ctx context.Context, url string) (*models.Article, error) { var res models.Article q, v, err := sq.Select(articleTableColumns...). From(articleTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"url": url}). Limit(1). ToSql() if err != nil { return nil, fmt.Errorf("build query: %w", err) } err = a.db.GetContext(ctx, &res, q, v...) if err != nil { return nil, fmt.Errorf("get: %w", err) } return &res, nil } func (a ArticleRepository) GetByID(ctx context.Context, id uint64) (*models.Article, error) { var res models.Article q, v, err := sq.Select(articleTableColumns...). From(articleTableName). PlaceholderFormat(sq.Dollar). Where(sq.Eq{"id": id}). Limit(1). ToSql() if err != nil { return nil, fmt.Errorf("build query: %w", err) } err = a.db.GetContext(ctx, &res, q, v...) if err != nil { return nil, fmt.Errorf("get: %w", err) } return &res, nil } func (a ArticleRepository) Add(ctx context.Context, m models.Article) (uint64, error) { q, v, err := sq.Insert(articleTableName). PlaceholderFormat(sq.Dollar). Columns( "url", "publish_time", "title", "image", "text", "preview_text", "meta_keywords", "meta_desc", "is_active", ).Values( m.URL, m.PublishTime, m.Title, m.Image, m.Text, m.PreviewText, m.MetaKeywords, m.MetaDescription, m.IsActive, ). 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.Dollar). 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.Dollar). 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 }