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

package mongodb
import (
"context"
"errors"
"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"
"strings"
)
type commentRepository struct {
restoreIDs bool
comments *mgo.Collection
}
func newCommentRepository(db *mgo.Database, restoreIDs bool) (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{
restoreIDs: restoreIDs,
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) {
if !r.restoreIDs {
comment.ID = generate.CommentID()
} else {
if len(comment.ID) != len(generate.CommentID()) && strings.HasPrefix(comment.ID, "SSC") {
return nil, errors.New("invalid story id")
}
}
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")
}
}