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.
 
 
 
 
 
 

246 lines
6.3 KiB

package mysql
import (
"context"
"database/sql"
"git.aiterp.net/stufflog3/stufflog3/entities"
"git.aiterp.net/stufflog3/stufflog3/models"
"git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore"
)
type projectRepository struct {
db *sql.DB
q *mysqlcore.Queries
}
func (r *projectRepository) Find(ctx context.Context, scopeID, projectID int) (*entities.Project, error) {
row, err := r.q.GetProject(ctx, mysqlcore.GetProjectParams{ID: projectID, ScopeID: scopeID})
if err != nil {
if err == sql.ErrNoRows {
return nil, models.NotFoundError("Project")
}
return nil, err
}
return &entities.Project{
ID: row.ID,
ScopeID: row.ScopeID,
OwnerID: row.OwnerID,
CreatedTime: row.CreatedTime,
Name: row.Name,
Description: row.Description,
Status: models.Status(row.Status),
}, nil
}
func (r *projectRepository) List(ctx context.Context, scopeID int) ([]entities.Project, error) {
rows, err := r.q.ListProjects(ctx, scopeID)
if err != nil {
if err == sql.ErrNoRows {
return []entities.Project{}, nil
}
return nil, err
}
res := make([]entities.Project, 0, len(rows))
for _, row := range rows {
res = append(res, entities.Project{
ID: row.ID,
ScopeID: row.ScopeID,
OwnerID: row.OwnerID,
CreatedTime: row.CreatedTime,
Name: row.Name,
Description: row.Description,
Status: models.Status(row.Status),
})
}
return res, nil
}
func (r *projectRepository) Create(ctx context.Context, project entities.Project) (*entities.Project, error) {
res, err := r.q.InsertProject(ctx, mysqlcore.InsertProjectParams{
ScopeID: project.ScopeID,
OwnerID: project.OwnerID,
Name: project.Name,
Status: int(project.Status),
Description: project.Description,
})
if err != nil {
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
project.ID = int(id)
return &project, nil
}
func (r *projectRepository) Update(ctx context.Context, project entities.Project, update models.ProjectUpdate) error {
project.Update(update)
return r.q.UpdateProject(ctx, mysqlcore.UpdateProjectParams{
OwnerID: project.OwnerID,
Name: project.Name,
Status: int(project.Status),
Description: project.Description,
ID: project.ID,
ScopeID: project.ScopeID,
})
}
func (r *projectRepository) Delete(ctx context.Context, project entities.Project) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
q := r.q.WithTx(tx)
reqs, err := q.ListProjectRequirements(ctx, project.ID)
if err != nil {
return err
}
for _, req := range reqs {
err = q.ClearItemProjectRequirement(ctx, sql.NullInt32{Valid: true, Int32: int32(req.ID)})
if err != nil {
return err
}
err = q.DeleteAllProjectRequirementStats(ctx, req.ID)
if err != nil {
return err
}
}
err = q.DeleteAllProjectRequirements(ctx, project.ID)
if err != nil {
return err
}
err = q.DeleteProject(ctx, mysqlcore.DeleteProjectParams{ID: project.ID, ScopeID: project.ScopeID})
if err != nil {
return err
}
return tx.Commit()
}
func (r *projectRepository) ListRequirements(ctx context.Context, projectID int) ([]entities.Requirement, []entities.RequirementStat, error) {
reqRows, err := r.q.ListProjectRequirements(ctx, projectID)
if err != nil && err != sql.ErrNoRows {
return nil, nil, err
}
statsRows, err := r.q.ListProjectRequirementsStats(ctx, projectID)
if err != nil && err != sql.ErrNoRows {
return nil, nil, err
}
requirements := make([]entities.Requirement, 0, len(reqRows))
for _, row := range reqRows {
requirements = append(requirements, entities.Requirement{
ID: row.ID,
ScopeID: row.ScopeID,
ProjectID: row.ProjectID,
Name: row.Name,
Description: row.Description,
Status: models.Status(row.Status),
})
}
stats := make([]entities.RequirementStat, 0, len(statsRows))
for _, row := range statsRows {
stats = append(stats, entities.RequirementStat{
RequirementID: row.ProjectRequirementID,
StatID: row.StatID,
Required: row.Required,
})
}
return requirements, stats, nil
}
func (r *projectRepository) CreateRequirement(ctx context.Context, requirement entities.Requirement) (*entities.Requirement, error) {
res, err := r.q.InsertProjectRequirement(ctx, mysqlcore.InsertProjectRequirementParams{
ScopeID: requirement.ScopeID,
ProjectID: requirement.ProjectID,
Name: requirement.Name,
Status: int(requirement.Status),
Description: requirement.Description,
})
if err != nil {
return nil, err
}
id, err := res.LastInsertId()
if err != nil {
return nil, err
}
requirement.ID = int(id)
return &requirement, nil
}
func (r *projectRepository) UpdateRequirement(ctx context.Context, requirement entities.Requirement, update models.RequirementUpdate) error {
requirement.Update(update)
return r.q.UpdateProjectRequirement(ctx, mysqlcore.UpdateProjectRequirementParams{
Name: requirement.Name,
Status: int(requirement.Status),
Description: requirement.Description,
ID: requirement.ID,
ScopeID: requirement.ScopeID,
})
}
func (r *projectRepository) DeleteRequirement(ctx context.Context, requirement entities.Requirement) error {
tx, err := r.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
q := r.q.WithTx(tx)
err = q.ClearItemProjectRequirement(ctx, sql.NullInt32{Valid: true, Int32: int32(requirement.ID)})
if err != nil {
return err
}
err = q.DeleteAllProjectRequirementStats(ctx, requirement.ID)
if err != nil {
return err
}
err = q.DeleteProjectRequirement(ctx, mysqlcore.DeleteProjectRequirementParams{
ScopeID: requirement.ScopeID,
ID: requirement.ID,
})
if err != nil {
return err
}
return tx.Commit()
}
func (r *projectRepository) UpsertRequirementStat(ctx context.Context, stat entities.RequirementStat) error {
return r.q.ReplaceProjectRequirementStat(ctx, mysqlcore.ReplaceProjectRequirementStatParams{
ProjectRequirementID: stat.RequirementID,
StatID: stat.StatID,
Required: stat.Required,
})
}
func (r *projectRepository) DeleteRequirementStat(ctx context.Context, stat entities.RequirementStat) error {
return r.q.DeleteProjectRequirementStat(ctx, mysqlcore.DeleteProjectRequirementStatParams{
ProjectRequirementID: stat.RequirementID,
StatID: stat.StatID,
})
}