stufflog graphql server
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.

141 lines
3.7 KiB

  1. package mysqldriver
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "git.aiterp.net/stufflog/server/internal/slerrors"
  8. "git.aiterp.net/stufflog/server/models"
  9. sq "github.com/Masterminds/squirrel"
  10. "github.com/jmoiron/sqlx"
  11. )
  12. type issueItemRepository struct {
  13. db *sqlx.DB
  14. }
  15. func (r *issueItemRepository) Find(ctx context.Context, id string) (*models.IssueItem, error) {
  16. issueItem := models.IssueItem{}
  17. err := r.db.GetContext(ctx, &issueItem, "SELECT * FROM issue_item WHERE issue_item_id=?", id)
  18. if err != nil {
  19. if err == sql.ErrNoRows {
  20. return nil, slerrors.NotFound("Issue item")
  21. }
  22. return nil, err
  23. }
  24. return &issueItem, nil
  25. }
  26. func (r *issueItemRepository) List(ctx context.Context, filter models.IssueItemFilter) ([]*models.IssueItem, error) {
  27. q := sq.Select("issue_item.*").From("issue_item").GroupBy("issue_item.issue_item_id")
  28. if len(filter.IssueItemIDs) > 0 {
  29. q = q.Where(sq.Eq{"issue_item_id": filter.IssueIDs})
  30. }
  31. if len(filter.IssueIDs) > 0 {
  32. q = q.Where(sq.Eq{"issue_id": filter.IssueIDs})
  33. }
  34. if len(filter.IssueAssignees) > 0 || len(filter.IssueOwners) > 0 || filter.IssueMinStage != nil || filter.IssueMaxStage != nil {
  35. q = q.Join("issue ON issue.issue_id = issue_item.issue_id")
  36. }
  37. if len(filter.IssueAssignees) > 0 {
  38. q = q.Where(sq.Eq{"issue.assignee_id": filter.IssueAssignees})
  39. }
  40. if len(filter.IssueOwners) > 0 {
  41. q = q.Where(sq.Eq{"issue.owner_id": filter.IssueOwners})
  42. }
  43. if filter.IssueMinStage != nil && filter.IssueMaxStage != nil && *filter.IssueMinStage == *filter.IssueMaxStage {
  44. q = q.Where(sq.Eq{"issue.status_stage": *filter.IssueMinStage})
  45. } else {
  46. if filter.IssueMinStage != nil {
  47. q = q.Where(sq.GtOrEq{"issue.status_stage": *filter.IssueMinStage})
  48. }
  49. if filter.IssueMaxStage != nil {
  50. q = q.Where(sq.LtOrEq{"issue.status_stage": *filter.IssueMaxStage})
  51. }
  52. }
  53. if len(filter.ItemIDs) > 0 {
  54. q = q.Where(sq.Eq{"item_id": filter.IssueIDs})
  55. }
  56. if len(filter.ItemTags) > 0 {
  57. q = q.Join("item_tag ON item_tag.item_id = issue_item.item_id").Where(
  58. sq.Eq{"item_tag.tag": filter.ItemTags},
  59. )
  60. }
  61. if filter.Acquired != nil {
  62. q = q.Where(sq.Eq{"acquired": *filter.Acquired})
  63. }
  64. query, args, err := q.ToSql()
  65. if err != nil {
  66. return nil, err
  67. }
  68. results := make([]*models.IssueItem, 0, 16)
  69. err = r.db.SelectContext(ctx, &results, query, args...)
  70. if err != nil {
  71. if err == sql.ErrNoRows {
  72. return []*models.IssueItem{}, nil
  73. }
  74. return nil, err
  75. }
  76. return results, nil
  77. }
  78. func (r *issueItemRepository) Insert(ctx context.Context, item models.IssueItem) (*models.IssueItem, error) {
  79. if item.IssueID == "" {
  80. return nil, errors.New("missing issue id")
  81. }
  82. tx, err := r.db.BeginTxx(ctx, nil)
  83. if err != nil {
  84. return nil, err
  85. }
  86. nextID, err := incCounter(ctx, tx, counterKindIssueSubID, item.IssueID)
  87. if err != nil {
  88. _ = tx.Rollback()
  89. return nil, err
  90. }
  91. item.ID = fmt.Sprintf("%s-%d", item.IssueID, nextID)
  92. _, err = tx.NamedExecContext(ctx, `
  93. INSERT INTO issue_item (
  94. issue_item_id, issue_id, item_id, quantity, acquired
  95. ) VALUES (
  96. :issue_item_id, :issue_id, :item_id, :quantity, :acquired
  97. );
  98. `, item)
  99. if err != nil {
  100. _ = tx.Rollback()
  101. return nil, err
  102. }
  103. err = tx.Commit()
  104. if err != nil {
  105. _ = tx.Rollback()
  106. return nil, err
  107. }
  108. return &item, nil
  109. }
  110. func (r *issueItemRepository) Save(ctx context.Context, item models.IssueItem) error {
  111. _, err := r.db.NamedExecContext(ctx, `
  112. UPDATE issue_item SET
  113. acquired=:acquired,
  114. quantity=:quantity
  115. WHERE issue_item_id=:issue_item_id
  116. `, item)
  117. return err
  118. }
  119. func (r *issueItemRepository) Delete(ctx context.Context, item models.IssueItem) error {
  120. _, err := r.db.ExecContext(ctx, "DELETE FROM issue_item WHERE issue_item_id=? LIMIT 1;", item.ID)
  121. return err
  122. }