|
|
package mysql
import ( "context" "database/sql" "encoding/json" "git.aiterp.net/stufflog3/stufflog3-api/internal/database/mysql/mysqlcore" "git.aiterp.net/stufflog3/stufflog3-api/internal/models" "git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors" "golang.org/x/sync/errgroup" "sort" )
type scopeRepository struct { db *sql.DB q *mysqlcore.Queries }
func (r *scopeRepository) Find(ctx context.Context, id int, full bool) (*models.Scope, error) { scope, err := r.q.GetScope(ctx, id) if err != nil { if err == sql.ErrNoRows { return nil, slerrors.NotFound("Scope") }
return nil, err }
res := &models.Scope{ ScopeEntry: models.ScopeEntry{ ID: scope.ID, Name: scope.Name, Abbreviation: scope.Abbreviation, }, Members: []models.ScopeMember{}, Projects: []models.ProjectEntry{}, Stats: []models.Stat{}, StatusLabels: make(map[models.Status]string), }
eg, ctx := errgroup.WithContext(ctx)
if full { eg.Go(func() error { projects, err := r.q.ListProjectEntries(ctx, id) if err != nil && err != sql.ErrNoRows { return err }
for _, project := range projects { res.Projects = append(res.Projects, models.ProjectEntry{ ID: project.ID, OwnerID: project.AuthorID, CreatedTime: project.CreatedTime, Name: project.Name, Status: models.Status(project.Status), }) }
return nil })
eg.Go(func() error { stats, err := r.q.ListStats(ctx, id) if err != nil && err != sql.ErrNoRows { return err }
for _, stat := range stats { var amounts map[string]int if stat.AllowedAmounts.Valid { amounts = make(map[string]int) err := json.Unmarshal(stat.AllowedAmounts.RawMessage, &amounts) if err != nil { return err } }
res.Stats = append(res.Stats, models.Stat{ StatEntry: models.StatEntry{ ID: stat.ID, Name: stat.Name, Weight: stat.Weight, }, Description: stat.Description, AllowedAmounts: amounts, }) }
return nil }) }
eg.Go(func() error { members, err := r.q.ListScopeMembers(ctx, id) if err != nil && err != sql.ErrNoRows { return err }
for _, member := range members { res.Members = append(res.Members, models.ScopeMember{ ID: member.UserID, Name: member.Name, Owner: member.Owner, }) }
return nil })
err = eg.Wait() if err != nil { return nil, err }
return res, nil }
func (r *scopeRepository) List(ctx context.Context) ([]models.ScopeEntry, error) { scopes, err := r.q.ListScopes(ctx) if err != nil { return nil, err }
res := make([]models.ScopeEntry, 0, len(scopes)) for _, scope := range scopes { res = append(res, models.ScopeEntry{ ID: scope.ID, Name: scope.Name, Abbreviation: scope.Abbreviation, }) }
return res, nil }
func (r *scopeRepository) ListByUser(ctx context.Context, userID string) ([]models.ScopeEntry, error) { scopes, err := r.q.ListScopesByUser(ctx, userID) if err != nil { return nil, err }
res := make([]models.ScopeEntry, 0, len(scopes)) for _, scope := range scopes { res = append(res, models.ScopeEntry{ ID: scope.ID, Name: scope.Name, Abbreviation: scope.Abbreviation, }) }
return res, nil }
func (r *scopeRepository) Create(ctx context.Context, scope models.ScopeEntry, owner models.ScopeMember) (*models.Scope, error) { tx, err := r.db.BeginTx(ctx, nil) if err != nil { return nil, err } defer tx.Rollback()
q := r.q.WithTx(tx) res, err := q.InsertScope(ctx, mysqlcore.InsertScopeParams(scope)) if err != nil { return nil, err } id, err := res.LastInsertId() if err != nil { return nil, err }
err = q.UpdateScopeMember(ctx, mysqlcore.UpdateScopeMemberParams{ ScopeID: int(id), UserID: owner.ID, Name: owner.Name, Owner: true, })
err = tx.Commit() if err != nil { return nil, err }
return &models.Scope{ ScopeEntry: models.ScopeEntry{ ID: int(id), Name: scope.Name, Abbreviation: scope.Abbreviation, }, DisplayName: owner.Name, Members: []models.ScopeMember{ { ID: owner.ID, Name: owner.Name, Owner: true, }, }, Projects: []models.ProjectEntry{}, Stats: []models.Stat{}, }, nil }
func (r *scopeRepository) Update(ctx context.Context, scope models.ScopeEntry) error { return mysqlcore.New(r.db).UpdateScope(ctx, mysqlcore.UpdateScopeParams{ Name: scope.Name, Abbreviation: scope.Abbreviation, ID: scope.ID, }) }
func (r *scopeRepository) Delete(ctx context.Context, scope models.Scope) error { tx, err := r.db.BeginTx(ctx, nil) if err != nil { return err } defer tx.Rollback()
q := r.q.WithTx(tx) err = q.DeleteAllScopeMembers(ctx, scope.ID) if err != nil { return err } err = q.DeleteScope(ctx, scope.ID) if err != nil { return err }
return tx.Commit() }
func (r *scopeRepository) UpdateMember(ctx context.Context, scope models.Scope, member models.ScopeMember) (*models.Scope, error) { err := mysqlcore.New(r.db).UpdateScopeMember(ctx, mysqlcore.UpdateScopeMemberParams{ ScopeID: scope.ID, UserID: member.ID, Name: member.Name, Owner: member.Owner, }) if err != nil { return nil, err }
found := false scope.Members = append(scope.Members[:0:0], scope.Members...) for i, member2 := range scope.Members { if member2.ID == member.ID { scope.Members[i] = member2 found = true } } if !found { scope.Members = append(scope.Members, member) sort.Slice(scope.Members, func(i, j int) bool { return scope.Members[i].Name < scope.Members[j].Name }) }
return &scope, nil }
func (r *scopeRepository) DeleteMember(ctx context.Context, scope models.Scope, userID string) (*models.Scope, error) { err := mysqlcore.New(r.db).DeleteScopeMember(ctx, mysqlcore.DeleteScopeMemberParams{ ScopeID: scope.ID, UserID: userID, }) if err != nil { return nil, err }
newMembers := make([]models.ScopeMember, 0, len(scope.Members)-1) for _, member := range scope.Members { if member.ID != userID { newMembers = append(newMembers, member) } } scope.Members = newMembers
return &scope, nil }
|