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 }