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.

184 lines
5.3 KiB

  1. package mysqldriver
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "git.aiterp.net/stufflog/server/internal/slerrors"
  7. "git.aiterp.net/stufflog/server/models"
  8. sq "github.com/Masterminds/squirrel"
  9. "github.com/jmoiron/sqlx"
  10. )
  11. type projectRepository struct {
  12. db *sqlx.DB
  13. }
  14. func (r *projectRepository) Find(ctx context.Context, id string) (*models.Project, error) {
  15. project := models.Project{}
  16. err := r.db.GetContext(ctx, &project, "SELECT * FROM project WHERE project_id=?", id)
  17. if err != nil {
  18. if err == sql.ErrNoRows {
  19. return nil, slerrors.NotFound("Project")
  20. }
  21. return nil, err
  22. }
  23. return &project, nil
  24. }
  25. func (r *projectRepository) List(ctx context.Context, filter models.ProjectFilter) ([]*models.Project, error) {
  26. q := sq.Select("project.*").From("project").OrderBy("project_id")
  27. if len(filter.ProjectIDs) > 0 {
  28. q = q.Where(sq.Eq{"project_id": filter.ProjectIDs})
  29. }
  30. if filter.Search != nil {
  31. q = q.Where("MATCH (name, description) AGAINST (?)", *filter.Search)
  32. }
  33. if filter.Permission != nil && filter.Permission.Valid() {
  34. q = q.LeftJoin("project_permission ON project.project_id = project_permission.project_id AND project_permission.user_id = ?", filter.Permission.UserID)
  35. if filter.Permission.MaxLevel >= filter.Permission.MinLevel {
  36. q = q.Where(sq.And{
  37. sq.GtOrEq{"project_permission.access_level": filter.Permission.MinLevel},
  38. sq.LtOrEq{"project_permission.access_level": filter.Permission.MaxLevel},
  39. })
  40. } else {
  41. q = q.Where(sq.GtOrEq{"project_permission.access_level": filter.Permission.MinLevel})
  42. }
  43. }
  44. query, args, err := q.ToSql()
  45. if err != nil {
  46. return nil, err
  47. }
  48. results := make([]*models.Project, 0, 16)
  49. err = r.db.SelectContext(ctx, &results, query, args...)
  50. if err != nil {
  51. if err == sql.ErrNoRows {
  52. return []*models.Project{}, nil
  53. }
  54. return nil, err
  55. }
  56. return results, nil
  57. }
  58. func (r *projectRepository) Insert(ctx context.Context, project models.Project) (*models.Project, error) {
  59. if !project.ValidKey() {
  60. return nil, errors.New("invalid project id")
  61. }
  62. _, err := r.db.NamedExecContext(ctx, `
  63. INSERT INTO project (project_id, name, description, daily_points)
  64. VALUES (:project_id, :name, :description, :daily_points)
  65. `, project)
  66. return &project, err
  67. }
  68. func (r *projectRepository) Save(ctx context.Context, project models.Project) error {
  69. _, err := r.db.NamedExecContext(ctx, `
  70. UPDATE project
  71. SET name=:name, description=:description, daily_points=:daily_points
  72. WHERE project_id=:project_id
  73. `, project)
  74. return err
  75. }
  76. func (r *projectRepository) ListPermissions(ctx context.Context, project models.Project) ([]*models.ProjectPermission, error) {
  77. permissions := make([]*models.ProjectPermission, 0, 4)
  78. err := r.db.SelectContext(ctx, &permissions, "SELECT * FROM project_permission WHERE project_id=?", project.ID)
  79. if err != nil {
  80. return nil, err
  81. }
  82. return permissions, nil
  83. }
  84. func (r *projectRepository) GetPermission(ctx context.Context, project models.Project, user models.User) (*models.ProjectPermission, error) {
  85. permission := models.ProjectPermission{}
  86. err := r.db.GetContext(ctx, &permission, "SELECT * FROM project_permission WHERE project_id=? AND user_id=?", project.ID, user.ID)
  87. if err != nil {
  88. if err == sql.ErrNoRows {
  89. return &models.ProjectPermission{
  90. ProjectID: project.ID,
  91. UserID: user.ID,
  92. Level: models.ProjectPermissionLevelNoAccess,
  93. }, nil
  94. }
  95. return nil, err
  96. }
  97. return &permission, nil
  98. }
  99. func (r *projectRepository) GetUserPermissions(ctx context.Context, user models.User, projectIDs []string) ([]*models.ProjectPermission, error) {
  100. query, args, err := sq.Select("*").From("project_permission").Where(sq.Eq{
  101. "user_id": user.ID,
  102. "project_id": projectIDs,
  103. }).ToSql()
  104. if err != nil {
  105. return nil, err
  106. }
  107. permissions := make([]*models.ProjectPermission, 0, 8)
  108. err = r.db.SelectContext(ctx, &permissions, query, args...)
  109. if err != nil && err != sql.ErrNoRows {
  110. return nil, err
  111. }
  112. filled := make(map[string]bool, len(permissions))
  113. for _, permission := range permissions {
  114. filled[permission.ProjectID] = true
  115. }
  116. for _, projectID := range projectIDs {
  117. if filled[projectID] {
  118. continue
  119. }
  120. permissions = append(permissions, &models.ProjectPermission{
  121. ProjectID: projectID,
  122. UserID: user.ID,
  123. Level: models.ProjectPermissionLevelNoAccess,
  124. })
  125. }
  126. return permissions, nil
  127. }
  128. func (r *projectRepository) GetIssuePermission(ctx context.Context, issue models.Issue, user models.User) (*models.ProjectPermission, error) {
  129. return r.GetPermission(ctx, models.Project{ID: issue.ProjectID}, user)
  130. }
  131. func (r *projectRepository) SetPermission(ctx context.Context, permission models.ProjectPermission) error {
  132. _, err := r.db.NamedExecContext(ctx, `
  133. REPLACE INTO project_permission (project_id, user_id, access_level)
  134. VALUES (:project_id, :user_id, :access_level)
  135. `, permission)
  136. return err
  137. }
  138. func (r *projectRepository) Delete(ctx context.Context, project models.Project) error {
  139. _, err := r.db.ExecContext(ctx, "DELETE FROM project WHERE project_id=?", project.ID)
  140. if err != nil {
  141. return err
  142. }
  143. _, err = r.db.ExecContext(ctx, "DELETE FROM project_permission WHERE project_id=?", project.ID)
  144. if err != nil {
  145. return err
  146. }
  147. _, err = r.db.ExecContext(ctx, "DELETE FROM project_status WHERE project_id=?", project.ID)
  148. if err != nil {
  149. return err
  150. }
  151. return nil
  152. }