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.
69 lines
1.9 KiB
69 lines
1.9 KiB
package posts
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"git.aiterp.net/rpdata/api/models"
|
|
"github.com/globalsign/mgo/bson"
|
|
)
|
|
|
|
// Move the post
|
|
func Move(post models.Post, toPosition int) ([]models.Post, error) {
|
|
if toPosition < 1 {
|
|
return nil, errors.New("Invalid position")
|
|
}
|
|
|
|
mutex.Lock()
|
|
defer mutex.Unlock()
|
|
|
|
// To avoid problems, only allow target indices that are allowed. If it's 1, then there is bound to
|
|
// be a post at the position.
|
|
if toPosition > 1 {
|
|
existing := models.Post{}
|
|
err := collection.Find(bson.M{"logId": post.LogID, "position": toPosition}).One(&existing)
|
|
|
|
if err != nil || existing.Position != toPosition {
|
|
return nil, errors.New("No post found at the position")
|
|
}
|
|
}
|
|
|
|
query := bson.M{"logId": post.LogID}
|
|
operation := bson.M{"$inc": bson.M{"position": 1}}
|
|
|
|
if toPosition < post.Position {
|
|
query["$and"] = []bson.M{
|
|
bson.M{"position": bson.M{"$gte": toPosition}},
|
|
bson.M{"position": bson.M{"$lt": post.Position}},
|
|
}
|
|
} else {
|
|
query["$and"] = []bson.M{
|
|
bson.M{"position": bson.M{"$gt": post.Position}},
|
|
bson.M{"position": bson.M{"$lte": toPosition}},
|
|
}
|
|
|
|
operation["$inc"] = bson.M{"position": -1}
|
|
}
|
|
|
|
_, err := collection.UpdateAll(query, operation)
|
|
if err != nil {
|
|
return nil, errors.New("Moving others failed: " + err.Error())
|
|
}
|
|
|
|
err = collection.UpdateId(post.ID, bson.M{"$set": bson.M{"position": toPosition}})
|
|
if err != nil {
|
|
return nil, errors.New("Moving failed: " + err.Error() + " (If you see this on the page, please let me know ASAP)")
|
|
}
|
|
|
|
from, to := post.Position, toPosition
|
|
if to < from {
|
|
from, to = to, from
|
|
}
|
|
|
|
posts := make([]models.Post, 0, (to-from)+1)
|
|
err = collection.Find(bson.M{"logId": post.LogID, "position": bson.M{"$gte": from, "$lte": to}}).Sort("position").All(&posts)
|
|
if err != nil {
|
|
return nil, errors.New("The move completed successfully, but finding the moved posts failed: " + err.Error())
|
|
}
|
|
|
|
return posts, nil
|
|
}
|