Loggest thine Stuff
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

244 lines
6.5 KiB

package mysql
import (
"context"
"database/sql"
"git.aiterp.net/stufflog3/stufflog3/entities"
"git.aiterp.net/stufflog3/stufflog3/internal/genutils"
"git.aiterp.net/stufflog3/stufflog3/models"
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore"
"github.com/Masterminds/squirrel"
"time"
)
type sprintRepository struct {
db *sql.DB
q *mysqlcore.Queries
}
func (r *sprintRepository) Find(ctx context.Context, scopeID, sprintID int) (*entities.Sprint, error) {
row, err := r.q.GetSprint(ctx, mysqlcore.GetSprintParams{ScopeID: scopeID, ID: sprintID})
if err != nil {
if err == sql.ErrNoRows {
return nil, models.NotFoundError("Sprint")
}
return nil, err
}
return &entities.Sprint{
ID: row.ID,
ScopeID: row.ScopeID,
Name: row.Name,
Description: row.Description,
Kind: models.SprintKind(row.Kind),
FromTime: row.FromTime,
ToTime: row.ToTime,
IsTimed: row.IsTimed,
IsCoarse: row.IsCoarse,
IsUnweighted: row.IsUnweighted,
AggregateName: row.AggregateName,
AggregateRequired: row.AggregateRequired,
Tags: csvPtr(row.TagsCsv),
}, nil
}
func (r *sprintRepository) ListAt(ctx context.Context, scopeID int, at time.Time) ([]entities.Sprint, error) {
rows, err := r.q.ListSprintsAt(ctx, mysqlcore.ListSprintsAtParams{ScopeID: scopeID, Time: at})
if err != nil {
if err == sql.ErrNoRows {
return nil, models.NotFoundError("Sprint")
}
return nil, err
}
sprints := make([]entities.Sprint, 0, len(rows))
for _, row := range rows {
sprints = append(sprints, entities.Sprint{
ID: row.ID,
ScopeID: row.ScopeID,
Name: row.Name,
Description: row.Description,
Kind: models.SprintKind(row.Kind),
FromTime: row.FromTime,
ToTime: row.ToTime,
IsTimed: row.IsTimed,
IsCoarse: row.IsCoarse,
IsUnweighted: row.IsUnweighted,
AggregateName: row.AggregateName,
AggregateRequired: row.AggregateRequired,
Tags: csvPtr(row.TagsCsv),
})
}
return sprints, nil
}
func (r *sprintRepository) ListBetween(ctx context.Context, scopeID int, from, to time.Time) ([]entities.Sprint, error) {
rows, err := r.q.ListSprintsBetween(ctx, mysqlcore.ListSprintsBetweenParams{
ScopeID: scopeID,
FromTime: from,
ToTime: to,
})
if err != nil {
if err == sql.ErrNoRows {
return nil, models.NotFoundError("Sprint")
}
return nil, err
}
sprints := make([]entities.Sprint, 0, len(rows))
for _, row := range rows {
sprints = append(sprints, entities.Sprint{
ID: row.ID,
ScopeID: row.ScopeID,
Name: row.Name,
Description: row.Description,
Kind: models.SprintKind(row.Kind),
FromTime: row.FromTime,
ToTime: row.ToTime,
IsTimed: row.IsTimed,
IsCoarse: row.IsCoarse,
IsUnweighted: row.IsUnweighted,
AggregateName: row.AggregateName,
AggregateRequired: row.AggregateRequired,
Tags: csvPtr(row.TagsCsv),
})
}
return sprints, nil
}
func (r *sprintRepository) Insert(ctx context.Context, sprint entities.Sprint) (*entities.Sprint, error) {
res, err := r.q.InsertSprint(ctx, mysqlcore.InsertSprintParams{
ScopeID: sprint.ScopeID,
Name: sprint.Name,
Description: sprint.Description,
Kind: int(sprint.Kind),
FromTime: sprint.FromTime,
ToTime: sprint.ToTime,
IsTimed: sprint.IsTimed,
IsCoarse: sprint.IsCoarse,
AggregateName: sprint.AggregateName,
AggregateRequired: sprint.AggregateRequired,
IsUnweighted: sprint.IsUnweighted,
TagsCsv: sqlCsvPtr(sprint.Tags),
})
if err != nil {
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
sprint.ID = int(id)
return &sprint, nil
}
func (r *sprintRepository) Update(ctx context.Context, sprint entities.Sprint, update models.SprintUpdate) error {
sprint.ApplyUpdate(update)
return r.q.UpdateSprint(ctx, mysqlcore.UpdateSprintParams{
Name: sprint.Name,
Description: sprint.Description,
FromTime: sprint.FromTime,
ToTime: sprint.ToTime,
IsTimed: sprint.IsTimed,
IsCoarse: sprint.IsCoarse,
IsUnweighted: sprint.IsUnweighted,
AggregateName: sprint.AggregateName,
AggregateRequired: sprint.AggregateRequired,
TagsCsv: sqlCsvPtr(sprint.Tags),
ID: sprint.ID,
})
}
func (r *sprintRepository) Delete(ctx context.Context, sprint entities.Sprint) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
q := r.q.WithTx(tx)
err = q.DeleteAllSprintParts(ctx, sprint.ID)
if err != nil {
return err
}
err = q.DeleteSprint(ctx, sprint.ID)
if err != nil {
return err
}
return tx.Commit()
}
func (r *sprintRepository) ListParts(ctx context.Context, sprints ...entities.Sprint) ([]entities.SprintPart, error) {
if len(sprints) == 0 {
return []entities.SprintPart{}, nil
} else if len(sprints) == 1 {
rows, err := r.q.ListSprintParts(ctx, sprints[0].ID)
if err != nil {
return nil, err
}
return genutils.Map(rows, func(row mysqlcore.SprintPart) entities.SprintPart {
return entities.SprintPart{
SprintID: row.SprintID,
PartID: row.ObjectID,
Required: row.Required,
}
}), nil
}
ids := make([]int, 0, len(sprints))
for _, sprint := range sprints {
ids = append(ids, sprint.ID)
}
query, args, err := squirrel.Select("sprint_id, object_id, required").
From("sprint_part").
Where(squirrel.Eq{"sprint_id": ids}).
ToSql()
if err != nil {
return nil, err
}
rows, err := r.db.QueryContext(ctx, query, args...)
if err != nil {
return nil, err
}
res := make([]entities.SprintPart, 0, 16)
for rows.Next() {
part := entities.SprintPart{}
err = rows.Scan(&part.SprintID, &part.PartID, &part.Required)
if err != nil {
return nil, err
}
res = append(res, part)
}
return res, nil
}
func (r *sprintRepository) UpdatePart(ctx context.Context, part entities.SprintPart) error {
return r.q.ReplaceSprintPart(ctx, mysqlcore.ReplaceSprintPartParams{
SprintID: part.SprintID,
ObjectID: part.PartID,
Required: part.Required,
})
}
func (r *sprintRepository) DeletePart(ctx context.Context, part entities.SprintPart) error {
return r.q.DeleteSprintPart(ctx, mysqlcore.DeleteSprintPartParams{
SprintID: part.SprintID,
ObjectID: part.PartID,
})
}