summaryrefslogtreecommitdiff
path: root/internal/db/bundb/relationship_follow.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/db/bundb/relationship_follow.go')
-rw-r--r--internal/db/bundb/relationship_follow.go101
1 files changed, 64 insertions, 37 deletions
diff --git a/internal/db/bundb/relationship_follow.go b/internal/db/bundb/relationship_follow.go
index fe1f26bf1..39b85075c 100644
--- a/internal/db/bundb/relationship_follow.go
+++ b/internal/db/bundb/relationship_follow.go
@@ -25,6 +25,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtscontext"
+ "github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/log"
"github.com/uptrace/bun"
@@ -149,25 +150,42 @@ func (r *relationshipDB) getFollow(ctx context.Context, lookup string, dbQuery f
return follow, nil
}
- // Set the follow source account
- follow.Account, err = r.state.DB.GetAccountByID(
- gtscontext.SetBarebones(ctx),
- follow.AccountID,
- )
- if err != nil {
- return nil, fmt.Errorf("error getting follow source account: %w", err)
+ if err := r.state.DB.PopulateFollow(ctx, follow); err != nil {
+ return nil, err
}
- // Set the follow target account
- follow.TargetAccount, err = r.state.DB.GetAccountByID(
- gtscontext.SetBarebones(ctx),
- follow.TargetAccountID,
+ return follow, nil
+}
+
+func (r *relationshipDB) PopulateFollow(ctx context.Context, follow *gtsmodel.Follow) error {
+ var (
+ err error
+ errs = make(gtserror.MultiError, 0, 2)
)
- if err != nil {
- return nil, fmt.Errorf("error getting follow target account: %w", err)
+
+ if follow.Account == nil {
+ // Follow account is not set, fetch from the database.
+ follow.Account, err = r.state.DB.GetAccountByID(
+ gtscontext.SetBarebones(ctx),
+ follow.AccountID,
+ )
+ if err != nil {
+ errs.Append(fmt.Errorf("error populating follow account: %w", err))
+ }
}
- return follow, nil
+ if follow.TargetAccount == nil {
+ // Follow target account is not set, fetch from the database.
+ follow.TargetAccount, err = r.state.DB.GetAccountByID(
+ gtscontext.SetBarebones(ctx),
+ follow.TargetAccountID,
+ )
+ if err != nil {
+ errs.Append(fmt.Errorf("error populating follow target account: %w", err))
+ }
+ }
+
+ return errs.Combine()
}
func (r *relationshipDB) PutFollow(ctx context.Context, follow *gtsmodel.Follow) error {
@@ -197,27 +215,40 @@ func (r *relationshipDB) UpdateFollow(ctx context.Context, follow *gtsmodel.Foll
})
}
+func (r *relationshipDB) deleteFollow(ctx context.Context, id string) error {
+ // Delete the follow itself using the given ID.
+ if _, err := r.conn.NewDelete().
+ Table("follows").
+ Where("? = ?", bun.Ident("id"), id).
+ Exec(ctx); err != nil {
+ return r.conn.ProcessError(err)
+ }
+
+ // Delete every list entry that used this followID.
+ if err := r.state.DB.DeleteListEntriesForFollowID(ctx, id); err != nil {
+ return fmt.Errorf("deleteFollow: error deleting list entries: %w", err)
+ }
+
+ return nil
+}
+
func (r *relationshipDB) DeleteFollowByID(ctx context.Context, id string) error {
defer r.state.Caches.GTS.Follow().Invalidate("ID", id)
// Load follow into cache before attempting a delete,
// as we need it cached in order to trigger the invalidate
// callback. This in turn invalidates others.
- _, err := r.GetFollowByID(gtscontext.SetBarebones(ctx), id)
+ follow, err := r.GetFollowByID(gtscontext.SetBarebones(ctx), id)
if err != nil {
if errors.Is(err, db.ErrNoEntries) {
- // not an issue.
- err = nil
+ // Already gone.
+ return nil
}
return err
}
// Finally delete follow from DB.
- _, err = r.conn.NewDelete().
- Table("follows").
- Where("? = ?", bun.Ident("id"), id).
- Exec(ctx)
- return r.conn.ProcessError(err)
+ return r.deleteFollow(ctx, follow.ID)
}
func (r *relationshipDB) DeleteFollowByURI(ctx context.Context, uri string) error {
@@ -226,21 +257,17 @@ func (r *relationshipDB) DeleteFollowByURI(ctx context.Context, uri string) erro
// Load follow into cache before attempting a delete,
// as we need it cached in order to trigger the invalidate
// callback. This in turn invalidates others.
- _, err := r.GetFollowByURI(gtscontext.SetBarebones(ctx), uri)
+ follow, err := r.GetFollowByURI(gtscontext.SetBarebones(ctx), uri)
if err != nil {
if errors.Is(err, db.ErrNoEntries) {
- // not an issue.
- err = nil
+ // Already gone.
+ return nil
}
return err
}
// Finally delete follow from DB.
- _, err = r.conn.NewDelete().
- Table("follows").
- Where("? = ?", bun.Ident("uri"), uri).
- Exec(ctx)
- return r.conn.ProcessError(err)
+ return r.deleteFollow(ctx, follow.ID)
}
func (r *relationshipDB) DeleteAccountFollows(ctx context.Context, accountID string) error {
@@ -272,16 +299,16 @@ func (r *relationshipDB) DeleteAccountFollows(ctx context.Context, accountID str
// but it is the only way we can ensure we invalidate all
// related caches correctly (e.g. visibility).
for _, id := range followIDs {
- _, err := r.GetFollowByID(ctx, id)
+ follow, err := r.GetFollowByID(ctx, id)
if err != nil && !errors.Is(err, db.ErrNoEntries) {
return err
}
+
+ // Delete each follow from DB.
+ if err := r.deleteFollow(ctx, follow.ID); err != nil && !errors.Is(err, db.ErrNoEntries) {
+ return err
+ }
}
- // Finally delete all from DB.
- _, err := r.conn.NewDelete().
- Table("follows").
- Where("? IN (?)", bun.Ident("id"), bun.In(followIDs)).
- Exec(ctx)
- return r.conn.ProcessError(err)
+ return nil
}