GraphQL API and utilities for the rpdata project
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.3 KiB

  1. package mongodb
  2. import (
  3. "context"
  4. "errors"
  5. "git.aiterp.net/rpdata/api/internal/generate"
  6. "git.aiterp.net/rpdata/api/models"
  7. "git.aiterp.net/rpdata/api/repositories"
  8. "github.com/globalsign/mgo"
  9. "github.com/globalsign/mgo/bson"
  10. "log"
  11. "strings"
  12. )
  13. type commentRepository struct {
  14. restoreIDs bool
  15. comments *mgo.Collection
  16. }
  17. func newCommentRepository(db *mgo.Database, restoreIDs bool) (repositories.CommentRepository, error) {
  18. collection := db.C("story.comments")
  19. err := collection.EnsureIndexKey("chapterId")
  20. if err != nil {
  21. return nil, err
  22. }
  23. err = collection.EnsureIndexKey("author")
  24. if err != nil {
  25. return nil, err
  26. }
  27. err = collection.EnsureIndexKey("createdDate")
  28. if err != nil {
  29. return nil, err
  30. }
  31. r := &commentRepository{
  32. restoreIDs: restoreIDs,
  33. comments: collection,
  34. }
  35. go r.fixFieldTypo()
  36. return r, nil
  37. }
  38. func (r *commentRepository) Find(ctx context.Context, id string) (*models.Comment, error) {
  39. comment := new(models.Comment)
  40. err := r.comments.FindId(id).One(comment)
  41. if err != nil {
  42. return nil, err
  43. }
  44. return comment, nil
  45. }
  46. func (r *commentRepository) List(ctx context.Context, filter models.CommentFilter) ([]*models.Comment, error) {
  47. query := bson.M{}
  48. if filter.ChapterID != nil {
  49. query["chapterId"] = *filter.ChapterID
  50. }
  51. comments := make([]*models.Comment, 0, 32)
  52. err := r.comments.Find(query).Sort("createdDate").Limit(filter.Limit).All(&comments)
  53. if err != nil {
  54. if err == mgo.ErrNotFound {
  55. return comments, nil
  56. }
  57. return nil, err
  58. }
  59. return comments, nil
  60. }
  61. func (r *commentRepository) Insert(ctx context.Context, comment models.Comment) (*models.Comment, error) {
  62. if !r.restoreIDs {
  63. comment.ID = generate.CommentID()
  64. } else {
  65. if len(comment.ID) != len(generate.CommentID()) && strings.HasPrefix(comment.ID, "SSC") {
  66. return nil, errors.New("invalid story id")
  67. }
  68. }
  69. err := r.comments.Insert(comment)
  70. if err != nil {
  71. return nil, err
  72. }
  73. return &comment, nil
  74. }
  75. func (r *commentRepository) Update(ctx context.Context, comment models.Comment, update models.CommentUpdate) (*models.Comment, error) {
  76. updateBson := bson.M{}
  77. if update.Subject != nil {
  78. updateBson["subject"] = *update.Subject
  79. comment.Subject = *update.Subject
  80. }
  81. if update.Source != nil {
  82. updateBson["source"] = *update.Source
  83. comment.Source = *update.Source
  84. }
  85. if update.FictionalDate != nil {
  86. updateBson["fictionalDate"] = *update.FictionalDate
  87. comment.FictionalDate = *update.FictionalDate
  88. }
  89. if update.CharacterID != nil {
  90. updateBson["characterId"] = *update.CharacterID
  91. comment.CharacterID = *update.CharacterID
  92. }
  93. if update.CharacterName != nil {
  94. updateBson["characterName"] = *update.CharacterName
  95. comment.CharacterName = *update.CharacterName
  96. }
  97. err := r.comments.UpdateId(comment.ID, bson.M{"$set": updateBson})
  98. if err != nil {
  99. return nil, err
  100. }
  101. return &comment, nil
  102. }
  103. func (r *commentRepository) Delete(ctx context.Context, comment models.Comment) error {
  104. return r.comments.RemoveId(comment.ID)
  105. }
  106. func (r *commentRepository) fixFieldTypo() {
  107. c, err := r.comments.UpdateAll(bson.M{
  108. "editeddDate": bson.M{"$ne": nil},
  109. }, bson.M{
  110. "$rename": bson.M{"editeddDate": "editedDate"},
  111. })
  112. if err != nil {
  113. if err == mgo.ErrNotFound {
  114. return
  115. }
  116. log.Println("Failed to run name typo fix:", err)
  117. return
  118. }
  119. if c.Updated > 0 {
  120. log.Println("Fixed editeddDate field name typo in", c.Updated, "comments")
  121. }
  122. }