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.7 KiB

  1. package postgres
  2. import (
  3. "context"
  4. "database/sql"
  5. "git.aiterp.net/rpdata/api/database/postgres/psqlcore"
  6. "git.aiterp.net/rpdata/api/internal/generate"
  7. "git.aiterp.net/rpdata/api/models"
  8. )
  9. type chapterRepository struct {
  10. insertWithIDs bool
  11. db *sql.DB
  12. }
  13. func (r *chapterRepository) Find(ctx context.Context, id string) (*models.Chapter, error) {
  14. chapter, err := psqlcore.New(r.db).SelectChapter(ctx, id)
  15. if err != nil {
  16. return nil, err
  17. }
  18. return r.chapter(chapter), nil
  19. }
  20. func (r *chapterRepository) List(ctx context.Context, filter models.ChapterFilter) ([]*models.Chapter, error) {
  21. params := psqlcore.SelectChaptersParams{
  22. StoryID: "",
  23. LimitSize: 0,
  24. }
  25. if filter.StoryID != nil {
  26. params.StoryID = *filter.StoryID
  27. }
  28. if filter.Limit > 0 {
  29. params.LimitSize = int32(filter.Limit)
  30. }
  31. chapters, err := psqlcore.New(r.db).SelectChapters(ctx, params)
  32. if err != nil {
  33. return nil, err
  34. }
  35. return r.chapters(chapters), nil
  36. }
  37. func (r *chapterRepository) Insert(ctx context.Context, chapter models.Chapter) (*models.Chapter, error) {
  38. if !r.insertWithIDs || len(chapter.ID) < 8 {
  39. chapter.ID = generate.ChapterID()
  40. }
  41. err := psqlcore.New(r.db).InsertChapter(ctx, psqlcore.InsertChapterParams{
  42. ID: chapter.ID,
  43. StoryID: chapter.StoryID,
  44. Title: chapter.Title,
  45. Author: chapter.Author,
  46. Source: chapter.Source,
  47. CreatedDate: chapter.CreatedDate.UTC(),
  48. FictionalDate: chapter.FictionalDate.UTC(),
  49. EditedDate: chapter.EditedDate.UTC(),
  50. CommentMode: string(chapter.CommentMode),
  51. CommentsLocked: chapter.CommentsLocked,
  52. })
  53. if err != nil {
  54. return nil, err
  55. }
  56. return &chapter, nil
  57. }
  58. func (r *chapterRepository) Update(ctx context.Context, chapter models.Chapter, update models.ChapterUpdate) (*models.Chapter, error) {
  59. chapter.ApplyUpdate(update)
  60. err := psqlcore.New(r.db).UpdateChapter(ctx, psqlcore.UpdateChapterParams{
  61. Title: chapter.Title,
  62. Source: chapter.Source,
  63. FictionalDate: chapter.FictionalDate.UTC(),
  64. CommentMode: string(chapter.CommentMode),
  65. CommentsLocked: chapter.CommentsLocked,
  66. ID: chapter.ID,
  67. })
  68. if err != nil {
  69. return nil, err
  70. }
  71. return &chapter, nil
  72. }
  73. func (r *chapterRepository) Move(ctx context.Context, chapter models.Chapter, _, to models.Story) (*models.Chapter, error) {
  74. err := psqlcore.New(r.db).UpdateChapterStoryID(ctx, psqlcore.UpdateChapterStoryIDParams{
  75. StoryID: to.ID,
  76. ID: chapter.ID,
  77. })
  78. if err != nil {
  79. return nil, err
  80. }
  81. chapter.StoryID = to.ID
  82. return &chapter, nil
  83. }
  84. func (r *chapterRepository) Delete(ctx context.Context, chapter models.Chapter) error {
  85. tx, err := r.db.BeginTx(ctx, nil)
  86. if err != nil {
  87. return err
  88. }
  89. defer func() { _ = tx.Rollback() }()
  90. q := psqlcore.New(tx)
  91. err = q.DeleteCommentsByChapterID(ctx, chapter.ID)
  92. if err != nil {
  93. return err
  94. }
  95. err = q.DeleteChapter(ctx, chapter.ID)
  96. if err != nil {
  97. return err
  98. }
  99. return tx.Commit()
  100. }
  101. func (r *chapterRepository) chapter(chapter psqlcore.StoryChapter) *models.Chapter {
  102. return &models.Chapter{
  103. ID: chapter.ID,
  104. StoryID: chapter.StoryID,
  105. Title: chapter.Title,
  106. Author: chapter.Author,
  107. Source: chapter.Source,
  108. CreatedDate: chapter.CreatedDate,
  109. FictionalDate: chapter.FictionalDate,
  110. EditedDate: chapter.EditedDate,
  111. CommentMode: models.ChapterCommentMode(chapter.CommentMode),
  112. CommentsLocked: chapter.CommentsLocked,
  113. }
  114. }
  115. func (r *chapterRepository) chapters(chapters []psqlcore.StoryChapter) []*models.Chapter {
  116. results := make([]*models.Chapter, 0, len(chapters))
  117. for _, chapter := range chapters {
  118. results = append(results, r.chapter(chapter))
  119. }
  120. return results
  121. }