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.

278 lines
6.0 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. package mysql
  2. import (
  3. "context"
  4. "database/sql"
  5. "encoding/json"
  6. "git.aiterp.net/stufflog3/stufflog3/entities"
  7. "git.aiterp.net/stufflog3/stufflog3/models"
  8. "git.aiterp.net/stufflog3/stufflog3/ports/mysql/mysqlcore"
  9. )
  10. type scopeRepository struct {
  11. db *sql.DB
  12. q *mysqlcore.Queries
  13. }
  14. func (r *scopeRepository) Find(ctx context.Context, id int) (*entities.Scope, error) {
  15. row, err := r.q.GetScope(ctx, id)
  16. if err != nil {
  17. if err == sql.ErrNoRows {
  18. return nil, models.NotFoundError("Scope")
  19. }
  20. return nil, err
  21. }
  22. customLabels := make(map[string]string, 0)
  23. if row.CustomLabels.Valid {
  24. _ = json.Unmarshal(row.CustomLabels.RawMessage, &customLabels)
  25. }
  26. return &entities.Scope{
  27. ID: row.ID,
  28. Name: row.Name,
  29. Abbreviation: row.Abbreviation,
  30. CustomLabels: customLabels,
  31. }, nil
  32. }
  33. func (r *scopeRepository) List(ctx context.Context) ([]entities.Scope, error) {
  34. rows, err := r.q.ListScopes(ctx)
  35. if err != nil {
  36. if err == sql.ErrNoRows {
  37. return []entities.Scope{}, nil
  38. }
  39. return nil, err
  40. }
  41. res := make([]entities.Scope, 0, len(rows))
  42. for _, row := range rows {
  43. customLabels := make(map[string]string, 0)
  44. if row.CustomLabels.Valid {
  45. _ = json.Unmarshal(row.CustomLabels.RawMessage, &customLabels)
  46. }
  47. res = append(res, entities.Scope{
  48. ID: row.ID,
  49. Name: row.Name,
  50. Abbreviation: row.Abbreviation,
  51. CustomLabels: customLabels,
  52. })
  53. }
  54. return nil, err
  55. }
  56. func (r *scopeRepository) ListUser(ctx context.Context, userID string) ([]entities.Scope, error) {
  57. rows, err := r.q.ListScopesByUser(ctx, userID)
  58. if err != nil {
  59. if err == sql.ErrNoRows {
  60. return []entities.Scope{}, nil
  61. }
  62. return nil, err
  63. }
  64. res := make([]entities.Scope, 0, len(rows))
  65. for _, row := range rows {
  66. customLabels := make(map[string]string, 0)
  67. if row.CustomLabels.Valid {
  68. _ = json.Unmarshal(row.CustomLabels.RawMessage, &customLabels)
  69. }
  70. res = append(res, entities.Scope{
  71. ID: row.ID,
  72. Name: row.Name,
  73. Abbreviation: row.Abbreviation,
  74. CustomLabels: customLabels,
  75. })
  76. }
  77. return res, nil
  78. }
  79. func (r *scopeRepository) Create(ctx context.Context, scope entities.Scope, owner entities.ScopeMember) (*entities.Scope, error) {
  80. tx, err := r.db.BeginTx(ctx, nil)
  81. if err != nil {
  82. return nil, err
  83. }
  84. defer tx.Rollback()
  85. q := r.q.WithTx(tx)
  86. if len(scope.CustomLabels) == 0 {
  87. scope.CustomLabels = nil
  88. }
  89. res, err := q.InsertScope(ctx, mysqlcore.InsertScopeParams{
  90. Name: scope.Name,
  91. Abbreviation: scope.Abbreviation,
  92. CustomLabels: sqlJsonPtr(scope.CustomLabels),
  93. })
  94. if err != nil {
  95. return nil, err
  96. }
  97. id, err := res.LastInsertId()
  98. if err != nil {
  99. return nil, err
  100. }
  101. err = q.ReplaceScopeMember(ctx, mysqlcore.ReplaceScopeMemberParams{
  102. ScopeID: int(id),
  103. UserID: owner.UserID,
  104. Name: owner.Name,
  105. Owner: true,
  106. })
  107. if err != nil {
  108. return nil, err
  109. }
  110. err = tx.Commit()
  111. if err != nil {
  112. return nil, err
  113. }
  114. scope.ID = int(id)
  115. return &scope, nil
  116. }
  117. func (r *scopeRepository) Update(ctx context.Context, scope entities.Scope, update models.ScopeUpdate) error {
  118. scope.ApplyUpdate(update)
  119. return r.q.UpdateScope(ctx, mysqlcore.UpdateScopeParams{
  120. Name: scope.Name,
  121. Abbreviation: scope.Abbreviation,
  122. CustomLabels: sqlJsonPtr(scope.CustomLabels),
  123. ID: scope.ID,
  124. })
  125. }
  126. func (r *scopeRepository) Delete(ctx context.Context, scope entities.Scope) error {
  127. tx, err := r.db.BeginTx(ctx, nil)
  128. if err != nil {
  129. return err
  130. }
  131. defer tx.Rollback()
  132. q := r.q.WithTx(tx)
  133. // Wipe all progress
  134. stats, err := q.ListStats(ctx, scope.ID)
  135. if err != nil {
  136. return err
  137. }
  138. for _, stat := range stats {
  139. err = q.ClearProjectRequirementStatsByStat(ctx, stat.ID)
  140. if err != nil {
  141. return err
  142. }
  143. err = q.ClearItemStatProgressByStat(ctx, stat.ID)
  144. if err != nil {
  145. return err
  146. }
  147. }
  148. // Clean up scoped data
  149. err = q.DeleteAllScopeMembers(ctx, scope.ID)
  150. if err != nil {
  151. return err
  152. }
  153. err = q.DeleteAllScopeItems(ctx, scope.ID)
  154. if err != nil {
  155. return err
  156. }
  157. err = q.DeleteAllScopeProjectRequirements(ctx, scope.ID)
  158. if err != nil {
  159. return err
  160. }
  161. err = q.DeleteAllScopeProjects(ctx, scope.ID)
  162. if err != nil {
  163. return err
  164. }
  165. err = q.DeleteAllScopeSprints(ctx, scope.ID)
  166. if err != nil {
  167. return err
  168. }
  169. err = q.DeleteAllScopeStats(ctx, scope.ID)
  170. if err != nil {
  171. return err
  172. }
  173. err = q.DeleteScope(ctx, scope.ID)
  174. if err != nil {
  175. return err
  176. }
  177. return tx.Commit()
  178. }
  179. func (r *scopeRepository) ListMembers(ctx context.Context, scopeIDs ...int) ([]entities.ScopeMember, error) {
  180. res := make([]entities.ScopeMember, 0, 8)
  181. if len(scopeIDs) == 1 {
  182. rows, err := r.q.ListScopeMembers(ctx, scopeIDs[0])
  183. if err != nil {
  184. if err == sql.ErrNoRows {
  185. return []entities.ScopeMember{}, nil
  186. }
  187. return nil, err
  188. }
  189. for _, row := range rows {
  190. res = append(res, entities.ScopeMember{
  191. ScopeID: row.ScopeID,
  192. UserID: row.UserID,
  193. Name: row.Name,
  194. Owner: row.Owner,
  195. })
  196. }
  197. } else {
  198. for i := 0; i < len(scopeIDs); i += 6 {
  199. ids := []int{-1, -2, -3, -4, -5, -6}
  200. copy(ids, scopeIDs[i:])
  201. rows, err := r.q.ListScopeMembersMulti(ctx, mysqlcore.ListScopeMembersMultiParams{
  202. ScopeID: ids[0],
  203. ScopeID_2: ids[1],
  204. ScopeID_3: ids[2],
  205. ScopeID_4: ids[3],
  206. ScopeID_5: ids[4],
  207. ScopeID_6: ids[5],
  208. })
  209. if err != nil {
  210. if err == sql.ErrNoRows {
  211. return []entities.ScopeMember{}, nil
  212. }
  213. return nil, err
  214. }
  215. for _, row := range rows {
  216. res = append(res, entities.ScopeMember{
  217. ScopeID: row.ScopeID,
  218. UserID: row.UserID,
  219. Name: row.Name,
  220. Owner: row.Owner,
  221. })
  222. }
  223. }
  224. }
  225. return res, nil
  226. }
  227. func (r *scopeRepository) SaveMember(ctx context.Context, member entities.ScopeMember) error {
  228. return r.q.ReplaceScopeMember(ctx, mysqlcore.ReplaceScopeMemberParams{
  229. ScopeID: member.ScopeID,
  230. UserID: member.UserID,
  231. Name: member.Name,
  232. Owner: member.Owner,
  233. })
  234. }
  235. func (r *scopeRepository) DeleteMember(ctx context.Context, member entities.ScopeMember) error {
  236. return r.q.DeleteScopeMember(ctx, mysqlcore.DeleteScopeMemberParams{
  237. ScopeID: member.ScopeID,
  238. UserID: member.UserID,
  239. })
  240. }