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.

137 lines
3.2 KiB

  1. package mongodb
  2. import (
  3. "context"
  4. "git.aiterp.net/rpdata/api/internal/generate"
  5. "git.aiterp.net/rpdata/api/models"
  6. "git.aiterp.net/rpdata/api/repositories"
  7. "github.com/globalsign/mgo"
  8. "github.com/globalsign/mgo/bson"
  9. "log"
  10. )
  11. type chapterRepository struct {
  12. chapters *mgo.Collection
  13. comments *mgo.Collection
  14. }
  15. func newChapterRepository(db *mgo.Database) (repositories.ChapterRepository, error) {
  16. collection := db.C("story.chapters")
  17. err := collection.EnsureIndexKey("storyId")
  18. if err != nil {
  19. return nil, err
  20. }
  21. err = collection.EnsureIndexKey("author")
  22. if err != nil {
  23. return nil, err
  24. }
  25. err = collection.EnsureIndexKey("createdDate")
  26. if err != nil {
  27. return nil, err
  28. }
  29. return &chapterRepository{
  30. chapters: collection,
  31. comments: db.C("story.comments"),
  32. }, nil
  33. }
  34. func (r *chapterRepository) Find(ctx context.Context, id string) (*models.Chapter, error) {
  35. chapter := new(models.Chapter)
  36. err := r.chapters.FindId(id).One(chapter)
  37. if err != nil {
  38. return nil, err
  39. }
  40. return chapter, nil
  41. }
  42. func (r *chapterRepository) List(ctx context.Context, filter models.ChapterFilter) ([]*models.Chapter, error) {
  43. query := bson.M{}
  44. if filter.StoryID != nil {
  45. query["storyId"] = *filter.StoryID
  46. }
  47. chapters := make([]*models.Chapter, 0, 32)
  48. err := r.chapters.Find(query).Sort("createdDate").Limit(filter.Limit).All(&chapters)
  49. if err != nil {
  50. if err == mgo.ErrNotFound {
  51. return chapters, nil
  52. }
  53. return nil, err
  54. }
  55. return chapters, nil
  56. }
  57. func (r *chapterRepository) Insert(ctx context.Context, chapter models.Chapter) (*models.Chapter, error) {
  58. chapter.ID = generate.StoryID()
  59. err := r.chapters.Insert(chapter)
  60. if err != nil {
  61. return nil, err
  62. }
  63. return &chapter, nil
  64. }
  65. func (r *chapterRepository) Update(ctx context.Context, chapter models.Chapter, update models.ChapterUpdate) (*models.Chapter, error) {
  66. updateBson := bson.M{}
  67. if update.Title != nil {
  68. updateBson["title"] = *update.Title
  69. chapter.Title = *update.Title
  70. }
  71. if update.Source != nil {
  72. updateBson["source"] = *update.Source
  73. chapter.Source = *update.Source
  74. }
  75. if update.FictionalDate != nil {
  76. updateBson["fictionalDate"] = *update.FictionalDate
  77. chapter.FictionalDate = *update.FictionalDate
  78. }
  79. if update.CommentMode != nil {
  80. updateBson["commentMode"] = *update.CommentMode
  81. chapter.CommentMode = *update.CommentMode
  82. }
  83. if update.CommentsLocked != nil {
  84. updateBson["commentsLocked"] = *update.CommentsLocked
  85. chapter.CommentsLocked = *update.CommentsLocked
  86. }
  87. err := r.chapters.UpdateId(chapter.ID, bson.M{"$set": updateBson})
  88. if err != nil {
  89. return nil, err
  90. }
  91. return &chapter, nil
  92. }
  93. func (r *chapterRepository) Move(ctx context.Context, chapter models.Chapter, from, to models.Story) (*models.Chapter, error) {
  94. err := r.chapters.UpdateId(chapter.ID, bson.M{"$set": bson.M{"storyId": to.ID}})
  95. if err != nil {
  96. return nil, err
  97. }
  98. chapter.StoryID = to.ID
  99. return &chapter, nil
  100. }
  101. func (r *chapterRepository) Delete(ctx context.Context, chapter models.Chapter) error {
  102. err := r.chapters.RemoveId(chapter.ID)
  103. if err != nil {
  104. return err
  105. }
  106. c, err := r.comments.RemoveAll(bson.M{"chapterId": chapter.ID})
  107. if err != nil {
  108. log.Println("Failed to remove comments:", err)
  109. return nil
  110. }
  111. log.Printf("Removed chapter %s (%d comments)", chapter.ID, c.Removed)
  112. return nil
  113. }