Gisle Aune
5 years ago
22 changed files with 720 additions and 485 deletions
-
3database/database.go
-
2database/mongodb/changes.go
-
137database/mongodb/chapters.go
-
134database/mongodb/comments.go
-
34database/mongodb/db.go
-
8database/mongodb/stories.go
-
1go.mod
-
9graph2/complexity.go
-
2graph2/gqlgen.yml
-
6graph2/graph.go
-
144graph2/resolvers/chapter.go
-
147graph2/resolvers/comment.go
-
167graph2/resolvers/story.go
-
37graph2/types/chapter.go
-
24graph2/types/comment.go
-
23graph2/types/story.go
-
8internal/auth/permitted.go
-
8models/change.go
-
3repositories/chapter.go
-
2repositories/comment.go
-
8services/services.go
-
288services/stories.go
@ -0,0 +1,137 @@ |
|||||
|
package mongodb |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"git.aiterp.net/rpdata/api/internal/generate" |
||||
|
"git.aiterp.net/rpdata/api/models" |
||||
|
"git.aiterp.net/rpdata/api/repositories" |
||||
|
"github.com/globalsign/mgo" |
||||
|
"github.com/globalsign/mgo/bson" |
||||
|
"log" |
||||
|
) |
||||
|
|
||||
|
type chapterRepository struct { |
||||
|
chapters *mgo.Collection |
||||
|
comments *mgo.Collection |
||||
|
} |
||||
|
|
||||
|
func newChapterRepository(db *mgo.Database) (repositories.ChapterRepository, error) { |
||||
|
collection := db.C("story.chapters") |
||||
|
|
||||
|
err := collection.EnsureIndexKey("storyId") |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
err = collection.EnsureIndexKey("author") |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
err = collection.EnsureIndexKey("createdDate") |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return &chapterRepository{ |
||||
|
chapters: collection, |
||||
|
comments: db.C("story.comments"), |
||||
|
}, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Find(ctx context.Context, id string) (*models.Chapter, error) { |
||||
|
chapter := new(models.Chapter) |
||||
|
err := r.chapters.FindId(id).One(chapter) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return chapter, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) List(ctx context.Context, filter models.ChapterFilter) ([]*models.Chapter, error) { |
||||
|
query := bson.M{} |
||||
|
if filter.StoryID != nil { |
||||
|
query["storyId"] = *filter.StoryID |
||||
|
} |
||||
|
|
||||
|
chapters := make([]*models.Chapter, 0, 32) |
||||
|
err := r.chapters.Find(query).Sort("createdDate").Limit(filter.Limit).All(&chapters) |
||||
|
if err != nil { |
||||
|
if err == mgo.ErrNotFound { |
||||
|
return chapters, nil |
||||
|
} |
||||
|
|
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return chapters, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Insert(ctx context.Context, chapter models.Chapter) (*models.Chapter, error) { |
||||
|
chapter.ID = generate.StoryID() |
||||
|
|
||||
|
err := r.chapters.Insert(chapter) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return &chapter, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Update(ctx context.Context, chapter models.Chapter, update models.ChapterUpdate) (*models.Chapter, error) { |
||||
|
updateBson := bson.M{} |
||||
|
if update.Title != nil { |
||||
|
updateBson["title"] = *update.Title |
||||
|
chapter.Title = *update.Title |
||||
|
} |
||||
|
if update.Source != nil { |
||||
|
updateBson["source"] = *update.Source |
||||
|
chapter.Source = *update.Source |
||||
|
} |
||||
|
if update.FictionalDate != nil { |
||||
|
updateBson["fictionalDate"] = *update.FictionalDate |
||||
|
chapter.FictionalDate = *update.FictionalDate |
||||
|
} |
||||
|
if update.CommentMode != nil { |
||||
|
updateBson["commentMode"] = *update.CommentMode |
||||
|
chapter.CommentMode = *update.CommentMode |
||||
|
} |
||||
|
if update.CommentsLocked != nil { |
||||
|
updateBson["commentsLocked"] = *update.CommentsLocked |
||||
|
chapter.CommentsLocked = *update.CommentsLocked |
||||
|
} |
||||
|
|
||||
|
err := r.chapters.UpdateId(chapter.ID, bson.M{"$set": updateBson}) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return &chapter, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Move(ctx context.Context, chapter models.Chapter, from, to models.Story) (*models.Chapter, error) { |
||||
|
err := r.chapters.UpdateId(chapter.ID, bson.M{"$set": bson.M{"storyId": to.ID}}) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
chapter.StoryID = to.ID |
||||
|
|
||||
|
return &chapter, nil |
||||
|
} |
||||
|
|
||||
|
func (r *chapterRepository) Delete(ctx context.Context, chapter models.Chapter) error { |
||||
|
err := r.chapters.RemoveId(chapter.ID) |
||||
|
if err != nil { |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
c, err := r.comments.RemoveAll(bson.M{"chapterId": chapter.ID}) |
||||
|
if err != nil { |
||||
|
log.Println("Failed to remove comments:", err) |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
log.Printf("Removed chapter %s (%d comments)", chapter.ID, c.Removed) |
||||
|
|
||||
|
return nil |
||||
|
} |
@ -0,0 +1,134 @@ |
|||||
|
package mongodb |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"git.aiterp.net/rpdata/api/internal/generate" |
||||
|
"git.aiterp.net/rpdata/api/models" |
||||
|
"git.aiterp.net/rpdata/api/repositories" |
||||
|
"github.com/globalsign/mgo" |
||||
|
"github.com/globalsign/mgo/bson" |
||||
|
"log" |
||||
|
) |
||||
|
|
||||
|
type commentRepository struct { |
||||
|
comments *mgo.Collection |
||||
|
} |
||||
|
|
||||
|
func newCommentRepository(db *mgo.Database) (repositories.CommentRepository, error) { |
||||
|
collection := db.C("story.comments") |
||||
|
|
||||
|
err := collection.EnsureIndexKey("chapterId") |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
err = collection.EnsureIndexKey("author") |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
err = collection.EnsureIndexKey("createdDate") |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
r := &commentRepository{ |
||||
|
comments: collection, |
||||
|
} |
||||
|
|
||||
|
go r.fixFieldTypo() |
||||
|
|
||||
|
return r, nil |
||||
|
} |
||||
|
|
||||
|
func (r *commentRepository) Find(ctx context.Context, id string) (*models.Comment, error) { |
||||
|
comment := new(models.Comment) |
||||
|
err := r.comments.FindId(id).One(comment) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return comment, nil |
||||
|
} |
||||
|
|
||||
|
func (r *commentRepository) List(ctx context.Context, filter models.CommentFilter) ([]*models.Comment, error) { |
||||
|
query := bson.M{} |
||||
|
if filter.ChapterID != nil { |
||||
|
query["chapterId"] = *filter.ChapterID |
||||
|
} |
||||
|
|
||||
|
comments := make([]*models.Comment, 0, 32) |
||||
|
err := r.comments.Find(query).Sort("createdDate").Limit(filter.Limit).All(&comments) |
||||
|
if err != nil { |
||||
|
if err == mgo.ErrNotFound { |
||||
|
return comments, nil |
||||
|
} |
||||
|
|
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return comments, nil |
||||
|
} |
||||
|
|
||||
|
func (r *commentRepository) Insert(ctx context.Context, comment models.Comment) (*models.Comment, error) { |
||||
|
comment.ID = generate.CommentID() |
||||
|
|
||||
|
err := r.comments.Insert(comment) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return &comment, nil |
||||
|
} |
||||
|
|
||||
|
func (r *commentRepository) Update(ctx context.Context, comment models.Comment, update models.CommentUpdate) (*models.Comment, error) { |
||||
|
updateBson := bson.M{} |
||||
|
if update.Subject != nil { |
||||
|
updateBson["subject"] = *update.Subject |
||||
|
comment.Subject = *update.Subject |
||||
|
} |
||||
|
if update.Source != nil { |
||||
|
updateBson["source"] = *update.Source |
||||
|
comment.Source = *update.Source |
||||
|
} |
||||
|
if update.FictionalDate != nil { |
||||
|
updateBson["fictionalDate"] = *update.FictionalDate |
||||
|
comment.FictionalDate = *update.FictionalDate |
||||
|
} |
||||
|
if update.CharacterID != nil { |
||||
|
updateBson["characterId"] = *update.CharacterID |
||||
|
comment.CharacterID = *update.CharacterID |
||||
|
} |
||||
|
if update.CharacterName != nil { |
||||
|
updateBson["characterName"] = *update.CharacterName |
||||
|
comment.CharacterName = *update.CharacterName |
||||
|
} |
||||
|
|
||||
|
err := r.comments.UpdateId(comment.ID, bson.M{"$set": updateBson}) |
||||
|
if err != nil { |
||||
|
return nil, err |
||||
|
} |
||||
|
|
||||
|
return &comment, nil |
||||
|
} |
||||
|
|
||||
|
func (r *commentRepository) Delete(ctx context.Context, comment models.Comment) error { |
||||
|
return r.comments.RemoveId(comment.ID) |
||||
|
} |
||||
|
|
||||
|
func (r *commentRepository) fixFieldTypo() { |
||||
|
c, err := r.comments.UpdateAll(bson.M{ |
||||
|
"editeddDate": bson.M{"$ne": nil}, |
||||
|
}, bson.M{ |
||||
|
"$rename": bson.M{"editeddDate": "editedDate"}, |
||||
|
}) |
||||
|
if err != nil { |
||||
|
if err == mgo.ErrNotFound { |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
log.Println("Failed to run name typo fix:", err) |
||||
|
return |
||||
|
} |
||||
|
if c.Updated > 0 { |
||||
|
log.Println("Fixed editeddDate field name typo in", c.Updated, "comments") |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue