mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
[chore] Tidy up status deletion, remove from cache too (#845)
* add func for deleting status from db + cache * move deletes entirely back to processor and also only do a delete if the requesting account owns the item being deleted * tidy up unboost processing * delete status more efficiently * fix wrong account id on remote test attachments * fix federator test
This commit is contained in:
@@ -57,7 +57,6 @@ import (
|
||||
// 18. Delete account itself
|
||||
func (p *processor) Delete(ctx context.Context, account *gtsmodel.Account, origin string) gtserror.WithCode {
|
||||
fields := kv.Fields{
|
||||
|
||||
{"username", account.Username},
|
||||
}
|
||||
if account.Domain != "" {
|
||||
@@ -163,7 +162,7 @@ selectStatusesLoop:
|
||||
// pass the status delete through the client api channel for processing
|
||||
s.Account = account
|
||||
|
||||
l.Debug("putting status in the client api channel")
|
||||
l.Debug("putting status delete in the client api channel")
|
||||
p.clientWorker.Queue(messages.FromClientAPI{
|
||||
APObjectType: ap.ObjectNote,
|
||||
APActivityType: ap.ActivityDelete,
|
||||
@@ -172,50 +171,26 @@ selectStatusesLoop:
|
||||
TargetAccount: account,
|
||||
})
|
||||
|
||||
if err := p.db.DeleteByID(ctx, s.ID, s); err != nil {
|
||||
if !errors.Is(err, db.ErrNoEntries) {
|
||||
// actual error has occurred
|
||||
l.Errorf("Delete: db error deleting status %s for account %s: %s", s.ID, account.Username, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// if there are any boosts of this status, delete them as well
|
||||
boosts := []*gtsmodel.Status{}
|
||||
if err := p.db.GetWhere(ctx, []db.Where{{Key: "boost_of_id", Value: s.ID}}, &boosts); err != nil {
|
||||
if !errors.Is(err, db.ErrNoEntries) {
|
||||
// an actual error has occurred
|
||||
l.Errorf("Delete: db error selecting boosts of status %s for account %s: %s", s.ID, account.Username, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
for _, b := range boosts {
|
||||
if b.Account == nil {
|
||||
bAccount, err := p.db.GetAccountByID(ctx, b.AccountID)
|
||||
if err != nil {
|
||||
l.Errorf("Delete: db error populating boosted status account: %v", err)
|
||||
continue
|
||||
if boosts, err := p.db.GetStatusReblogs(ctx, s); err == nil {
|
||||
for _, b := range boosts {
|
||||
if b.Account == nil {
|
||||
bAccount, err := p.db.GetAccountByID(ctx, b.AccountID)
|
||||
if err != nil {
|
||||
l.Errorf("Delete: db error populating boosted status account: %v", err)
|
||||
continue
|
||||
}
|
||||
b.Account = bAccount
|
||||
}
|
||||
|
||||
b.Account = bAccount
|
||||
}
|
||||
|
||||
l.Debug("putting boost undo in the client api channel")
|
||||
p.clientWorker.Queue(messages.FromClientAPI{
|
||||
APObjectType: ap.ActivityAnnounce,
|
||||
APActivityType: ap.ActivityUndo,
|
||||
GTSModel: s,
|
||||
OriginAccount: b.Account,
|
||||
TargetAccount: account,
|
||||
})
|
||||
|
||||
if err := p.db.DeleteByID(ctx, b.ID, b); err != nil {
|
||||
if err != db.ErrNoEntries {
|
||||
// actual error has occurred
|
||||
l.Errorf("Delete: db error deleting boost with id %s: %s", b.ID, err)
|
||||
continue
|
||||
}
|
||||
l.Debug("putting boost undo in the client api channel")
|
||||
p.clientWorker.Queue(messages.FromClientAPI{
|
||||
APObjectType: ap.ActivityAnnounce,
|
||||
APActivityType: ap.ActivityUndo,
|
||||
GTSModel: s,
|
||||
OriginAccount: b.Account,
|
||||
TargetAccount: account,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -288,6 +288,10 @@ func (p *processor) processUndoAnnounceFromClientAPI(ctx context.Context, client
|
||||
return errors.New("undo was not parseable as *gtsmodel.Status")
|
||||
}
|
||||
|
||||
if err := p.db.DeleteStatusByID(ctx, boost.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := p.deleteStatusFromTimelines(ctx, boost); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -469,29 +469,27 @@ func (p *processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Sta
|
||||
}
|
||||
}
|
||||
|
||||
// delete all mentions for this status
|
||||
// delete all mention entries generated by this status
|
||||
for _, m := range statusToDelete.MentionIDs {
|
||||
if err := p.db.DeleteByID(ctx, m, >smodel.Mention{}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// delete all notifications for this status
|
||||
// delete all notification entries generated by this status
|
||||
if err := p.db.DeleteWhere(ctx, []db.Where{{Key: "status_id", Value: statusToDelete.ID}}, &[]*gtsmodel.Notification{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// delete all boosts for this status + remove them from timelines
|
||||
boosts, err := p.db.GetStatusReblogs(ctx, statusToDelete)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, b := range boosts {
|
||||
if err := p.deleteStatusFromTimelines(ctx, b); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.db.DeleteByID(ctx, b.ID, b); err != nil {
|
||||
return err
|
||||
if boosts, err := p.db.GetStatusReblogs(ctx, statusToDelete); err == nil {
|
||||
for _, b := range boosts {
|
||||
if err := p.deleteStatusFromTimelines(ctx, b); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := p.db.DeleteStatusByID(ctx, b.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -500,5 +498,10 @@ func (p *processor) wipeStatus(ctx context.Context, statusToDelete *gtsmodel.Sta
|
||||
return err
|
||||
}
|
||||
|
||||
// delete the status itself
|
||||
if err := p.db.DeleteStatusByID(ctx, statusToDelete.ID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@@ -368,9 +368,12 @@ func (suite *FromFederatorTestSuite) TestProcessAccountDelete() {
|
||||
suite.False(zorkFollowsSatan)
|
||||
|
||||
// no statuses from foss satan should be left in the database
|
||||
dbStatuses, err := suite.db.GetAccountStatuses(ctx, deletedAccount.ID, 0, false, false, "", "", false, false, false)
|
||||
suite.ErrorIs(err, db.ErrNoEntries)
|
||||
suite.Empty(dbStatuses)
|
||||
if !testrig.WaitFor(func() bool {
|
||||
s, err := suite.db.GetAccountStatuses(ctx, deletedAccount.ID, 0, false, false, "", "", false, false, false)
|
||||
return s == nil && err == db.ErrNoEntries
|
||||
}) {
|
||||
suite.FailNow("timeout waiting for statuses to be deleted")
|
||||
}
|
||||
|
||||
dbAccount, err := suite.db.GetAccountByID(ctx, deletedAccount.ID)
|
||||
suite.NoError(err)
|
||||
|
@@ -48,11 +48,7 @@ func (p *processor) Delete(ctx context.Context, requestingAccount *gtsmodel.Acco
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error converting status %s to frontend representation: %s", targetStatus.ID, err))
|
||||
}
|
||||
|
||||
if err := p.db.DeleteByID(ctx, targetStatus.ID, >smodel.Status{}); err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error deleting status from the database: %s", err))
|
||||
}
|
||||
|
||||
// send it back to the processor for async processing
|
||||
// send the status back to the processor for async processing
|
||||
p.clientWorker.Queue(messages.FromClientAPI{
|
||||
APObjectType: ap.ObjectNote,
|
||||
APActivityType: ap.ActivityDelete,
|
||||
|
@@ -78,14 +78,8 @@ func (p *processor) Unboost(ctx context.Context, requestingAccount *gtsmodel.Acc
|
||||
}
|
||||
|
||||
if toUnboost {
|
||||
// we had a boost, so take some action to get rid of it
|
||||
if err := p.db.DeleteWhere(ctx, where, >smodel.Status{}); err != nil {
|
||||
return nil, gtserror.NewErrorInternalError(fmt.Errorf("error unboosting status: %s", err))
|
||||
}
|
||||
|
||||
// pin some stuff onto the boost while we have it out of the db
|
||||
gtsBoost.Account = requestingAccount
|
||||
|
||||
gtsBoost.BoostOf = targetStatus
|
||||
gtsBoost.BoostOfAccount = targetStatus.Account
|
||||
gtsBoost.BoostOf.Account = targetStatus.Account
|
||||
|
Reference in New Issue
Block a user