2025-04-15 23:49:28 +03:00

210 lines
4.5 KiB
Go

package issue
import (
"context"
"errors"
"fmt"
"log"
"madsky.ru/go-finance/internal/database"
"madsky.ru/go-finance/internal/issue"
"madsky.ru/go-finance/internal/project"
"madsky.ru/go-finance/internal/status"
)
type Repository interface {
Find(ctx context.Context) ([]*issue.Issue, error)
FindOne(ctx context.Context, id uint64) (*issue.Issue, error)
Create(ctx context.Context, dto *issue.CreateIssueDTO) (*uint64, error)
Update(ctx context.Context, id uint64, issue *issue.Issue) error
Remove(ctx context.Context, id uint64) (uint64, error)
UpdatePositions(ctx context.Context, position int, statusId uint32, id uint32) (*uint32, error)
}
type repository struct {
client database.Client
}
func NewRepository(client database.Client) Repository {
return &repository{
client: client,
}
}
func (r *repository) Find(ctx context.Context) ([]*issue.Issue, error) {
q := `select
i."id",
i."name",
i."description",
i."position",
i."created",
i."project_id",
i."status_id",
p."id" as project_id,
p."name" as project_name,
p."description" as project_description,
p."key" as project_key,
s."id" as status_id,
s."name" as status_name,
s."description" as status_description,
s."position" as position
from issues i
join projects p on p.id = project_id
join statuses s on s.id = status_id
order by i.id asc`
rows, err := r.client.Query(ctx, q)
if err != nil {
log.Println("rows", err)
return nil, err
}
issues := make([]*issue.Issue, 0)
for rows.Next() {
var n issue.Issue
var p project.Project
var s status.Status
err = rows.Scan(
&n.ID,
&n.Name,
&n.Description,
&n.Position,
&n.Created,
&n.ProjectID,
&n.StatusID,
&p.ID,
&p.Name,
&p.Description,
&p.Key,
&s.ID,
&s.Name,
&s.Description,
&s.Position,
)
if err != nil {
log.Println("scan", err)
return nil, err
}
n.Project = p
n.Status = s
issues = append(issues, &n)
}
if err = rows.Err(); err != nil {
log.Println("rows err", err)
return nil, err
}
return issues, nil
}
func (r *repository) UpdatePositions(ctx context.Context, position int, statusId uint32, id uint32) (*uint32, error) {
q := `update issues set "position" = $1, "status_id"=$2 where "id"=$3 returning id`
var resultId uint32
if err := r.client.QueryRow(ctx, q, position, statusId, id).Scan(&resultId); err != nil {
fmt.Println(fmt.Sprintf("error %v", err))
return nil, err
}
return &resultId, nil
}
func (r *repository) FindOne(ctx context.Context, id uint64) (*issue.Issue, error) {
q := `select
i."id",
i."name",
i."description",
i."position",
i."created",
i."project_id",
i."status_id",
p."id" as project_id,
p."name" as project_name,
p."description" as project_description,
p."key" as project_key,
s."id" as status_id,
s."name" as status_name,
s."description" as status_description,
s."position" as position
from issues i
join projects p on p.id = project_id
join statuses s on s.id = status_id
where i."id" = $1`
var n issue.Issue
var p project.Project
var s status.Status
if err := r.client.QueryRow(ctx, q, id).Scan(
&n.ID,
&n.Name,
&n.Description,
&n.Position,
&n.Created,
&n.ProjectID,
&n.StatusID,
&p.ID,
&p.Name,
&p.Description,
&p.Key,
&s.ID,
&s.Name,
&s.Description,
&s.Position,
); err != nil {
fmt.Println(err)
return &issue.Issue{}, err
}
n.Project = p
n.Status = s
return &n, nil
}
func (r *repository) Create(ctx context.Context, dto *issue.CreateIssueDTO) (*uint64, error) {
q := `insert into issues (name, description, project_id, status_id, position)
values ($1, $2, $3, $4, $5)
returning id`
var position uint32 = 0
var id uint64
if dto.Position != nil {
position = *dto.Position
}
if err := r.client.QueryRow(ctx, q, dto.Name, dto.Description, dto.ProjectID, dto.StatusID, position).Scan(&id); err != nil {
fmt.Println(fmt.Sprintf("error %v", err))
return nil, err
}
return &id, nil
}
func (r *repository) Update(ctx context.Context, id uint64, issue *issue.Issue) error {
//TODO implement me
fmt.Println("update", id, issue, ctx)
panic("implement me")
}
func (r *repository) Remove(ctx context.Context, id uint64) (uint64, error) {
q := "delete from issues where id=$1"
tag, err := r.client.Exec(ctx, q, id)
if err != nil {
log.Println("exec error", err)
return 0, err
}
rowsAffected := tag.RowsAffected()
if rowsAffected == 0 {
return 0, errors.New("project not found")
}
return uint64(rowsAffected), nil
}