Delete likes on replies / topics properly when their parent is deleted.

This commit is contained in:
Azareal 2020-01-15 14:16:10 +10:00
parent 8bdd1c8787
commit 7ec2037f5f
4 changed files with 64 additions and 12 deletions

View File

@ -63,6 +63,9 @@ type ReplyStmts struct {
delete *sql.Stmt delete *sql.Stmt
addLikesToReply *sql.Stmt addLikesToReply *sql.Stmt
removeRepliesFromTopic *sql.Stmt removeRepliesFromTopic *sql.Stmt
deleteLikesForReply *sql.Stmt
deleteActivity *sql.Stmt
deleteActivitySubs *sql.Stmt
updateTopicReplies *sql.Stmt updateTopicReplies *sql.Stmt
updateTopicReplies2 *sql.Stmt updateTopicReplies2 *sql.Stmt
@ -79,6 +82,9 @@ func init() {
delete: acc.Delete(re).Where("rid=?").Prepare(), delete: acc.Delete(re).Where("rid=?").Prepare(),
addLikesToReply: acc.Update(re).Set("likeCount=likeCount+?").Where("rid=?").Prepare(), addLikesToReply: acc.Update(re).Set("likeCount=likeCount+?").Where("rid=?").Prepare(),
removeRepliesFromTopic: acc.Update("topics").Set("postCount=postCount-?").Where("tid=?").Prepare(), removeRepliesFromTopic: acc.Update("topics").Set("postCount=postCount-?").Where("tid=?").Prepare(),
deleteLikesForReply: acc.Delete("likes").Where("targetItem=? AND targetType='replies'").Prepare(),
deleteActivity: acc.Delete("activity_stream").Where("elementID=? AND elementType='post'").Prepare(),
deleteActivitySubs: acc.Delete("activity_subscriptions").Where("targetID=? AND targetType='post'").Prepare(),
// TODO: Optimise this to avoid firing an update if it's not the last reply in a topic. We will need to set lastReplyID properly in other places and in the patcher first so we can use it here. // TODO: Optimise this to avoid firing an update if it's not the last reply in a topic. We will need to set lastReplyID properly in other places and in the patcher first so we can use it here.
updateTopicReplies: acc.RawPrepare("UPDATE topics t INNER JOIN replies r ON t.tid = r.tid SET t.lastReplyBy = r.createdBy, t.lastReplyAt = r.createdAt, t.lastReplyID = r.rid WHERE t.tid = ?"), updateTopicReplies: acc.RawPrepare("UPDATE topics t INNER JOIN replies r ON t.tid = r.tid SET t.lastReplyBy = r.createdBy, t.lastReplyAt = r.createdAt, t.lastReplyID = r.rid WHERE t.tid = ?"),
@ -114,9 +120,20 @@ func (r *Reply) Like(uid int) (err error) {
} }
// TODO: Refresh topic list? // TODO: Refresh topic list?
// TODO: Remove alerts. // TODO: Restructure alerts so we can delete the "x replied to topic" ones too.
func (r *Reply) Delete() error { func (r *Reply) Delete() error {
_, err := replyStmts.delete.Exec(r.ID) creator, err := Users.Get(r.CreatedBy)
if err == nil {
wcount := WordCount(r.Content)
err = creator.DecreasePostStats(wcount, false)
if err != nil {
return err
}
} else if err != ErrNoRows {
return err
}
_, err = replyStmts.delete.Exec(r.ID)
if err != nil { if err != nil {
return err return err
} }
@ -135,6 +152,18 @@ func (r *Reply) Delete() error {
tc.Remove(r.ParentID) tc.Remove(r.ParentID)
} }
_ = Rstore.GetCache().Remove(r.ID) _ = Rstore.GetCache().Remove(r.ID)
if err != nil {
return err
}
_, err = replyStmts.deleteLikesForReply.Exec(r.ID)
if err != nil {
return err
}
_, err = replyStmts.deleteActivitySubs.Exec(r.ID)
if err != nil {
return err
}
_, err = replyStmts.deleteActivity.Exec(r.ID)
return err return err
} }

View File

@ -197,6 +197,7 @@ type TopicStmts struct {
createLike *sql.Stmt createLike *sql.Stmt
addLikesToTopic *sql.Stmt addLikesToTopic *sql.Stmt
delete *sql.Stmt delete *sql.Stmt
deleteLikesForTopic *sql.Stmt
deleteActivity *sql.Stmt deleteActivity *sql.Stmt
deleteActivitySubs *sql.Stmt deleteActivitySubs *sql.Stmt
edit *sql.Stmt edit *sql.Stmt
@ -226,6 +227,7 @@ func init() {
createLike: acc.Insert("likes").Columns("weight, targetItem, targetType, sentBy, createdAt").Fields("?,?,?,?,UTC_TIMESTAMP()").Prepare(), createLike: acc.Insert("likes").Columns("weight, targetItem, targetType, sentBy, createdAt").Fields("?,?,?,?,UTC_TIMESTAMP()").Prepare(),
addLikesToTopic: acc.Update(t).Set("likeCount=likeCount+?").Where("tid = ?").Prepare(), addLikesToTopic: acc.Update(t).Set("likeCount=likeCount+?").Where("tid = ?").Prepare(),
delete: acc.Delete(t).Where("tid = ?").Prepare(), delete: acc.Delete(t).Where("tid = ?").Prepare(),
deleteLikesForTopic: acc.Delete("likes").Where("targetItem=? AND targetType='topics'").Prepare(),
deleteActivity: acc.Delete("activity_stream").Where("elementID=? AND elementType='topic'").Prepare(), deleteActivity: acc.Delete("activity_stream").Where("elementID=? AND elementType='topic'").Prepare(),
deleteActivitySubs: acc.Delete("activity_subscriptions").Where("targetID=? AND targetType='topic'").Prepare(), deleteActivitySubs: acc.Delete("activity_subscriptions").Where("targetID=? AND targetType='topic'").Prepare(),
edit: acc.Update(t).Set("title=?,content=?,parsed_content=?").Where("tid=?").Prepare(), // TODO: Only run the content update bits on non-polls, does this matter? edit: acc.Update(t).Set("title=?,content=?,parsed_content=?").Where("tid=?").Prepare(), // TODO: Only run the content update bits on non-polls, does this matter?
@ -328,10 +330,10 @@ func (t *Topic) Unlike(uid int) error {
// TODO: Use a transaction here // TODO: Use a transaction here
func (t *Topic) Delete() error { func (t *Topic) Delete() error {
topicCreator, err := Users.Get(t.CreatedBy) creator, err := Users.Get(t.CreatedBy)
if err == nil { if err == nil {
wcount := WordCount(t.Content) wcount := WordCount(t.Content)
err = topicCreator.DecreasePostStats(wcount, true) err = creator.DecreasePostStats(wcount, true)
if err != nil { if err != nil {
return err return err
} }
@ -349,6 +351,10 @@ func (t *Topic) Delete() error {
if err != nil && err != ErrNoRows { if err != nil && err != ErrNoRows {
return err return err
} }
_, err = topicStmts.deleteLikesForTopic.Exec(t.ID)
if err != nil {
return err
}
_, err = topicStmts.deleteActivitySubs.Exec(t.ID) _, err = topicStmts.deleteActivitySubs.Exec(t.ID)
if err != nil { if err != nil {
return err return err

View File

@ -346,6 +346,10 @@ func (u *User) DeletePosts() error {
} }
updatedForums[parentID] = updatedForums[parentID] + 1 updatedForums[parentID] = updatedForums[parentID] + 1
_, err = topicStmts.deleteLikesForTopic.Exec(tid)
if err != nil {
return err
}
_, err = topicStmts.deleteActivitySubs.Exec(tid) _, err = topicStmts.deleteActivitySubs.Exec(tid)
if err != nil { if err != nil {
return err return err
@ -401,7 +405,7 @@ func (u *User) DeletePosts() error {
rc := Rstore.GetCache() rc := Rstore.GetCache()
for rows.Next() { for rows.Next() {
var rid, tid int var rid, tid int
err := rows.Scan(&rid,&tid) err := rows.Scan(&rid, &tid)
if err != nil { if err != nil {
return err return err
} }
@ -426,7 +430,20 @@ func (u *User) DeletePosts() error {
if err != nil { if err != nil {
return err return err
} }
// TODO: Remove alerts.
_, err = replyStmts.deleteLikesForReply.Exec(rid)
if err != nil {
return err
}
_, err = replyStmts.deleteActivitySubs.Exec(rid)
if err != nil {
return err
}
_, err = replyStmts.deleteActivity.Exec(rid)
if err != nil {
return err
}
// TODO: Restructure alerts so we can delete the "x replied to topic" ones too.
} }
return rows.Err() return rows.Err()
} }

View File

@ -327,7 +327,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
} }
// ? - What happens if an error fires after a redirect...? // ? - What happens if an error fires after a redirect...?
replyCreator, err := c.Users.Get(reply.CreatedBy) /*replyCreator, err := c.Users.Get(reply.CreatedBy)
if err == nil { if err == nil {
err = replyCreator.DecreasePostStats(c.WordCount(reply.Content), false) err = replyCreator.DecreasePostStats(c.WordCount(reply.Content), false)
if err != nil { if err != nil {
@ -335,7 +335,7 @@ func ReplyDeleteSubmit(w http.ResponseWriter, r *http.Request, user c.User, srid
} }
} else if err != sql.ErrNoRows { } else if err != sql.ErrNoRows {
return c.InternalErrorJSQ(err, w, r, js) return c.InternalErrorJSQ(err, w, r, js)
} }*/
err = c.ModLogs.Create("delete", reply.ParentID, "reply", user.GetIP(), user.ID) err = c.ModLogs.Create("delete", reply.ParentID, "reply", user.GetIP(), user.ID)
if err != nil { if err != nil {