Loggest thy 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.

144 lines
3.4 KiB

3 years ago
  1. package mysql
  2. import (
  3. "context"
  4. "database/sql"
  5. "encoding/json"
  6. "git.aiterp.net/stufflog3/stufflog3-api/internal/database/mysql/mysqlcore"
  7. "git.aiterp.net/stufflog3/stufflog3-api/internal/models"
  8. "git.aiterp.net/stufflog3/stufflog3-api/internal/slerrors"
  9. "git.aiterp.net/stufflog3/stufflog3-api/internal/sqltypes"
  10. )
  11. type statsRepository struct {
  12. db *sql.DB
  13. q *mysqlcore.Queries
  14. scopeID int
  15. }
  16. func (r *statsRepository) Find(ctx context.Context, id int) (*models.Stat, error) {
  17. row, err := r.q.GetStat(ctx, mysqlcore.GetStatParams{ScopeID: r.scopeID, ID: id})
  18. if err != nil {
  19. if err == sql.ErrNoRows {
  20. return nil, slerrors.NotFound("Stat")
  21. }
  22. return nil, err
  23. }
  24. return r.rowToStat(row), nil
  25. }
  26. func (r *statsRepository) List(ctx context.Context) ([]models.Stat, error) {
  27. rows, err := r.q.ListStats(ctx, r.scopeID)
  28. if err != nil && err != sql.ErrNoRows {
  29. return nil, err
  30. }
  31. stats := make([]models.Stat, 0, len(rows))
  32. for _, row := range rows {
  33. stats = append(stats, *r.rowToStat(mysqlcore.GetStatRow(row)))
  34. }
  35. return stats, nil
  36. }
  37. func (r *statsRepository) Create(ctx context.Context, stat models.Stat) (*models.Stat, error) {
  38. allowedAmounts := sqltypes.NullRawMessage{}
  39. if stat.AllowedAmounts != nil && len(stat.AllowedAmounts) > 0 {
  40. allowedAmounts.Valid = true
  41. allowedAmounts.RawMessage, _ = json.Marshal(stat.AllowedAmounts)
  42. }
  43. res, err := r.q.InsertStat(ctx, mysqlcore.InsertStatParams{
  44. ScopeID: r.scopeID,
  45. Name: stat.Name,
  46. Description: stat.Description,
  47. Weight: stat.Weight,
  48. AllowedAmounts: allowedAmounts,
  49. })
  50. if err != nil {
  51. return nil, err
  52. }
  53. id, err := res.LastInsertId()
  54. if err != nil {
  55. return nil, err
  56. }
  57. return r.Find(ctx, int(id))
  58. }
  59. func (r *statsRepository) Update(ctx context.Context, stat models.Stat, update models.StatUpdate) (*models.Stat, error) {
  60. stat.Update(update)
  61. allowedAmounts := sqltypes.NullRawMessage{}
  62. if stat.AllowedAmounts != nil && len(stat.AllowedAmounts) > 0 {
  63. allowedAmounts.Valid = true
  64. allowedAmounts.RawMessage, _ = json.Marshal(stat.AllowedAmounts)
  65. }
  66. err := r.q.UpdateStat(ctx, mysqlcore.UpdateStatParams{
  67. Name: stat.Name,
  68. Description: stat.Description,
  69. Weight: stat.Weight,
  70. AllowedAmounts: allowedAmounts,
  71. ID: stat.ID,
  72. ScopeID: r.scopeID,
  73. })
  74. if err != nil {
  75. return nil, err
  76. }
  77. return &stat, nil
  78. }
  79. func (r *statsRepository) Delete(ctx context.Context, stat models.Stat) error {
  80. tx, err := r.db.BeginTx(ctx, nil)
  81. if err != nil {
  82. return err
  83. }
  84. defer tx.Rollback()
  85. q := r.q.WithTx(tx)
  86. err = q.DeleteStat(ctx, mysqlcore.DeleteStatParams{ScopeID: r.scopeID, ID: stat.ID})
  87. if err == sql.ErrNoRows {
  88. return slerrors.NotFound("Stat")
  89. }
  90. if err != nil {
  91. return err
  92. }
  93. err = q.CLearItemStatProgressByStat(ctx, stat.ID)
  94. if err != nil {
  95. return err
  96. }
  97. err = q.DeleteAllProjectRequirementStatsByStat(ctx, stat.ID)
  98. if err != nil {
  99. return err
  100. }
  101. // TODO: delete from Sprints
  102. return tx.Commit()
  103. }
  104. func (r *statsRepository) rowToStat(row mysqlcore.GetStatRow) *models.Stat {
  105. stat := models.Stat{
  106. StatEntry: models.StatEntry{
  107. ID: row.ID,
  108. Name: row.Name,
  109. Weight: row.Weight,
  110. },
  111. Description: row.Description,
  112. AllowedAmounts: nil,
  113. }
  114. if row.AllowedAmounts.Valid {
  115. stat.AllowedAmounts = make(map[string]int)
  116. _ = json.Unmarshal(row.AllowedAmounts.RawMessage, &stat)
  117. if len(stat.AllowedAmounts) == 0 {
  118. stat.AllowedAmounts = nil
  119. }
  120. }
  121. return &stat
  122. }