package repository import ( "context" "database/sql" "errors" "fmt" "tailly_back_v2/internal/domain" ) var ( ErrPostNotFound = errors.New("post not found") ) type PostRepository interface { Create(ctx context.Context, post *domain.Post) error GetByID(ctx context.Context, id int) (*domain.Post, error) GetAll(ctx context.Context) ([]*domain.Post, error) GetByAuthorID(ctx context.Context, authorID int) ([]*domain.Post, error) Update(ctx context.Context, post *domain.Post) error Delete(ctx context.Context, id int) error } type postRepository struct { db *sql.DB } func (r *postRepository) GetByAuthorID(ctx context.Context, authorID int) ([]*domain.Post, error) { query := ` SELECT id, title, content, author_id, created_at, updated_at FROM posts WHERE author_id = $1 ORDER BY created_at DESC ` rows, err := r.db.QueryContext(ctx, query, authorID) if err != nil { return nil, err } defer rows.Close() var posts []*domain.Post for rows.Next() { post := &domain.Post{} err := rows.Scan( &post.ID, &post.Title, &post.Content, &post.AuthorID, &post.CreatedAt, &post.UpdatedAt, ) if err != nil { return nil, err } posts = append(posts, post) } return posts, nil } func (r *postRepository) Update(ctx context.Context, post *domain.Post) error { //TODO implement me panic("implement me") } func (r *postRepository) Delete(ctx context.Context, id int) error { query := ` DELETE FROM posts WHERE id = $1 ` result, err := r.db.ExecContext(ctx, query, id) if err != nil { return fmt.Errorf("failed to delete post: %w", err) } rowsAffected, err := result.RowsAffected() if err != nil { return fmt.Errorf("failed to get rows affected: %w", err) } if rowsAffected == 0 { return ErrPostNotFound } return nil } func NewPostRepository(db *sql.DB) *postRepository { return &postRepository{db: db} } func (r *postRepository) Create(ctx context.Context, post *domain.Post) error { query := ` INSERT INTO posts (title, content, author_id, created_at, updated_at) VALUES ($1, $2, $3, $4, $5) RETURNING id ` err := r.db.QueryRowContext(ctx, query, post.Title, post.Content, post.AuthorID, post.CreatedAt, post.UpdatedAt, ).Scan(&post.ID) return err } func (r *postRepository) GetByID(ctx context.Context, id int) (*domain.Post, error) { query := ` SELECT id, title, content, author_id, created_at, updated_at FROM posts WHERE id = $1 ` post := &domain.Post{} err := r.db.QueryRowContext(ctx, query, id).Scan( &post.ID, &post.Title, &post.Content, &post.AuthorID, &post.CreatedAt, &post.UpdatedAt, ) if err == sql.ErrNoRows { return nil, ErrPostNotFound } return post, err } func (r *postRepository) GetAll(ctx context.Context) ([]*domain.Post, error) { query := ` SELECT id, title, content, author_id, created_at, updated_at FROM posts ORDER BY created_at DESC ` rows, err := r.db.QueryContext(ctx, query) if err != nil { return nil, err } defer rows.Close() var posts []*domain.Post for rows.Next() { post := &domain.Post{} err := rows.Scan( &post.ID, &post.Title, &post.Content, &post.AuthorID, &post.CreatedAt, &post.UpdatedAt, ) if err != nil { return nil, err } posts = append(posts, post) } return posts, nil }