diff --git a/internal/db/account.go b/internal/db/account.go index 15c6839f8..c7c49a9ac 100644 --- a/internal/db/account.go +++ b/internal/db/account.go @@ -35,22 +35,16 @@ type Account interface { // GetAccountByURL returns one account with the given URL, or an error if something goes wrong. GetAccountByURL(uri string) (*gtsmodel.Account, Error) - // GetLocalAccountByUsername is a shortcut for the common action of fetching an account ON THIS INSTANCE - // according to its username, which should be unique. - // The given account pointer will be set to the result of the query, whatever it is. - // In case of no entries, a 'no entries' error will be returned + // GetLocalAccountByUsername returns an account on this instance by its username. GetLocalAccountByUsername(username string) (*gtsmodel.Account, Error) - // GetAccountFollowRequests is a shortcut for the common action of fetching a list of follow requests targeting the given account ID. - // The given slice 'followRequests' will be set to the result of the query, whatever it is. - // In case of no entries, a 'no entries' error will be returned - GetAccountFollowRequests(accountID string, followRequests *[]gtsmodel.FollowRequest) Error + // GetAccountFollowRequests returns all follow requests targeting the given account. + GetAccountFollowRequests(accountID string) ([]gtsmodel.FollowRequest, Error) - // GetAccountFollowing is a shortcut for the common action of fetching a list of accounts that accountID is following. - // The given slice 'following' will be set to the result of the query, whatever it is. - // In case of no entries, a 'no entries' error will be returned - GetAccountFollowing(accountID string, following *[]gtsmodel.Follow) Error + // GetAccountFollows returns a slice of follows owned by the given accountID. + GetAccountFollows(accountID string, following *[]gtsmodel.Follow) Error + // CountAccountFollowing returns the amount of accounts that the given accountID is following. CountAccountFollowing(accountID string, localOnly bool) (int, Error) // GetAccountFollowers is a shortcut for the common action of fetching a list of accounts that accountID is followed by. @@ -60,6 +54,7 @@ type Account interface { // If localOnly is set to true, then only followers from *this instance* will be returned. GetAccountFollowers(accountID string, followers *[]gtsmodel.Follow, localOnly bool) Error + // CountAccountFollowers returns the amounts that the given ID is followed by. CountAccountFollowers(accountID string, localOnly bool) (int, Error) // GetAccountFaves is a shortcut for the common action of fetching a list of faves made by the given accountID. diff --git a/internal/db/instance.go b/internal/db/instance.go index afac8266c..1f7c83e4f 100644 --- a/internal/db/instance.go +++ b/internal/db/instance.go @@ -22,15 +22,15 @@ import "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" // Instance contains functions for instance-level actions (counting instance users etc.). type Instance interface { - // GetUserCountForInstance returns the number of known accounts registered with the given domain. - GetUserCountForInstance(domain string) (int, Error) + // CountInstanceUsers returns the number of known accounts registered with the given domain. + CountInstanceUsers(domain string) (int, Error) - // GetStatusCountForInstance returns the number of known statuses posted from the given domain. - GetStatusCountForInstance(domain string) (int, Error) + // CountInstanceStatuses returns the number of known statuses posted from the given domain. + CountInstanceStatuses(domain string) (int, Error) - // GetDomainCountForInstance returns the number of known instances known that the given domain federates with. - GetDomainCountForInstance(domain string) (int, Error) + // CountInstanceDomains returns the number of known instances known that the given domain federates with. + CountInstanceDomains(domain string) (int, Error) - // GetAccountsForInstance returns a slice of accounts from the given instance, arranged by ID. - GetAccountsForInstance(domain string, maxID string, limit int) ([]*gtsmodel.Account, Error) + // GetInstanceAccounts returns a slice of accounts from the given instance, arranged by ID. + GetInstanceAccounts(domain string, maxID string, limit int) ([]*gtsmodel.Account, Error) } diff --git a/internal/db/notification.go b/internal/db/notification.go index b8e2829e7..576e87825 100644 --- a/internal/db/notification.go +++ b/internal/db/notification.go @@ -22,6 +22,10 @@ import "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" // Notification contains functions for creating and getting notifications. type Notification interface { - // GetNotificationsForAccount returns a list of notifications that pertain to the given accountID. - GetNotificationsForAccount(accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, Error) + // GetNotifications returns a slice of notifications that pertain to the given accountID. + // + // Returned notifications will be ordered ID descending (ie., highest/newest to lowest/oldest). + GetNotifications(accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, Error) + // GetNotification returns one notification according to its id. + GetNotification(id string) (*gtsmodel.Notification, Error) } diff --git a/internal/db/pg/account.go b/internal/db/pg/account.go index 485c66e4f..ea3f1ca23 100644 --- a/internal/db/pg/account.go +++ b/internal/db/pg/account.go @@ -149,14 +149,16 @@ func (a *accountDB) GetLocalAccountByUsername(username string) (*gtsmodel.Accoun return account, err } -func (a *accountDB) GetAccountFollowRequests(accountID string, followRequests *[]gtsmodel.FollowRequest) db.Error { - if err := a.conn.Model(followRequests).Where("target_account_id = ?", accountID).Select(); err != nil { - if err == pg.ErrNoRows { - return nil - } - return err - } - return nil +func (a *accountDB) GetAccountFollowRequests(accountID string) ([]*gtsmodel.FollowRequest, db.Error) { + followRequests := []*gtsmodel.FollowRequest{} + + q := a.conn. + Model(&followRequests). + Where("target_account_id = ?", accountID)] + + err := processErrorResponse(q.Select()) + + return followRequests, err } func (a *accountDB) GetAccountFollowing(accountID string, following *[]gtsmodel.Follow) db.Error { diff --git a/internal/db/pg/instance.go b/internal/db/pg/instance.go index 71ef06e0a..968832ca5 100644 --- a/internal/db/pg/instance.go +++ b/internal/db/pg/instance.go @@ -35,7 +35,7 @@ type instanceDB struct { cancel context.CancelFunc } -func (i *instanceDB) GetUserCountForInstance(domain string) (int, db.Error) { +func (i *instanceDB) CountInstanceUsers(domain string) (int, db.Error) { q := i.conn.Model(&[]*gtsmodel.Account{}) if domain == i.config.Host { @@ -51,7 +51,7 @@ func (i *instanceDB) GetUserCountForInstance(domain string) (int, db.Error) { return q.Count() } -func (i *instanceDB) GetStatusCountForInstance(domain string) (int, db.Error) { +func (i *instanceDB) CountInstanceStatuses(domain string) (int, db.Error) { q := i.conn.Model(&[]*gtsmodel.Status{}) if domain == i.config.Host { @@ -66,7 +66,7 @@ func (i *instanceDB) GetStatusCountForInstance(domain string) (int, db.Error) { return q.Count() } -func (i *instanceDB) GetDomainCountForInstance(domain string) (int, db.Error) { +func (i *instanceDB) CountInstanceDomains(domain string) (int, db.Error) { q := i.conn.Model(&[]*gtsmodel.Instance{}) if domain == i.config.Host { @@ -81,7 +81,7 @@ func (i *instanceDB) GetDomainCountForInstance(domain string) (int, db.Error) { return q.Count() } -func (i *instanceDB) GetAccountsForInstance(domain string, maxID string, limit int) ([]*gtsmodel.Account, db.Error) { +func (i *instanceDB) GetInstanceAccounts(domain string, maxID string, limit int) ([]*gtsmodel.Account, db.Error) { i.log.Debug("GetAccountsForInstance") accounts := []*gtsmodel.Account{} diff --git a/internal/db/pg/notification.go b/internal/db/pg/notification.go index ac3a2149b..281a76d85 100644 --- a/internal/db/pg/notification.go +++ b/internal/db/pg/notification.go @@ -19,15 +19,88 @@ package pg import ( + "context" + "github.com/go-pg/pg/v10" + "github.com/go-pg/pg/v10/orm" + "github.com/sirupsen/logrus" + "github.com/superseriousbusiness/gotosocial/internal/cache" + "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" ) -func (ps *postgresService) GetNotificationsForAccount(accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, db.Error) { - notifications := []*gtsmodel.Notification{} +type notificationDB struct { + config *config.Config + conn *pg.DB + log *logrus.Logger + cancel context.CancelFunc + cache cache.Cache +} - q := ps.conn.Model(¬ifications).Where("target_account_id = ?", accountID) +func (n *notificationDB) cacheNotification(id string, notification *gtsmodel.Notification) { + if n.cache == nil { + n.cache = cache.New() + } + + if err := n.cache.Store(id, notification); err != nil { + n.log.Panicf("notificationDB: error storing in cache: %s", err) + } +} + +func (n *notificationDB) notificationCached(id string) (*gtsmodel.Notification, bool) { + if n.cache == nil { + n.cache = cache.New() + return nil, false + } + + nI, err := n.cache.Fetch(id) + if err != nil || nI == nil { + return nil, false + } + + notification, ok := nI.(*gtsmodel.Notification) + if !ok { + n.log.Panicf("notificationDB: cached interface with key %s was not a notification", id) + } + + return notification, true +} + +func (n *notificationDB) newNotificationQ(i interface{}) *orm.Query { + return n.conn.Model(i). + Relation("OriginAccount"). + Relation("TargetAccount"). + Relation("Status") +} + +func (n *notificationDB) GetNotification(id string) (*gtsmodel.Notification, db.Error) { + if notification, cached := n.notificationCached(id); cached { + return notification, nil + } + + notification := >smodel.Notification{} + + q := n.newNotificationQ(notification). + Where("notification.id = ?", id) + + err := processErrorResponse(q.Select()) + + if err == nil && notification != nil { + n.cacheNotification(id, notification) + } + + return notification, err +} + +func (n *notificationDB) GetNotifications(accountID string, limit int, maxID string, sinceID string) ([]*gtsmodel.Notification, db.Error) { + // begin by selecting just the IDs + notifIDs := []*gtsmodel.Notification{} + q := n.conn. + Model(¬ifIDs). + Column("id"). + Where("target_account_id = ?", accountID). + Order("id DESC") if maxID != "" { q = q.Where("id < ?", maxID) @@ -41,13 +114,22 @@ func (ps *postgresService) GetNotificationsForAccount(accountID string, limit in q = q.Limit(limit) } - q = q.Order("created_at DESC") - - if err := q.Select(); err != nil { - if err != pg.ErrNoRows { - return nil, err - } - + err := processErrorResponse(q.Select()) + if err != nil { + return nil, err } + + // now we have the IDs, select the notifs one by one + // reason for this is that for each notif, we can instead get it from our cache if it's cached + notifications := []*gtsmodel.Notification{} + for _, notifID := range notifIDs { + notif, err := n.GetNotification(notifID.ID) + errP := processErrorResponse(err) + if errP != nil { + return nil, errP + } + notifications = append(notifications, notif) + } + return notifications, nil } diff --git a/internal/db/pg/pg.go b/internal/db/pg/pg.go index 9d9c8e572..0437baf02 100644 --- a/internal/db/pg/pg.go +++ b/internal/db/pg/pg.go @@ -148,6 +148,12 @@ func NewPostgresService(ctx context.Context, c *config.Config, log *logrus.Logge log: log, cancel: cancel, }, + Notification: ¬ificationDB{ + config: c, + conn: conn, + log: log, + cancel: cancel, + }, Relationship: &relationshipDB{ config: c, conn: conn, diff --git a/internal/db/pg/relationship.go b/internal/db/pg/relationship.go index e9349ce7f..a9d200f9a 100644 --- a/internal/db/pg/relationship.go +++ b/internal/db/pg/relationship.go @@ -54,7 +54,7 @@ func (r *relationshipDB) processResponse(block *gtsmodel.Block, err error) (*gts } } -func (r *relationshipDB) Blocked(account1 string, account2 string, eitherDirection bool) (bool, db.Error) { +func (r *relationshipDB) IsBlocked(account1 string, account2 string, eitherDirection bool) (bool, db.Error) { q := r.conn.Model(>smodel.Block{}).Where("account_id = ?", account1).Where("target_account_id = ?", account2) if eitherDirection { @@ -128,7 +128,7 @@ func (r *relationshipDB) GetRelationship(requestingAccount string, targetAccount return rel, nil } -func (r *relationshipDB) Follows(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, db.Error) { +func (r *relationshipDB) IsFollowing(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, db.Error) { if sourceAccount == nil || targetAccount == nil { return false, nil } @@ -136,7 +136,7 @@ func (r *relationshipDB) Follows(sourceAccount *gtsmodel.Account, targetAccount return r.conn.Model(>smodel.Follow{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists() } -func (r *relationshipDB) FollowRequested(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, db.Error) { +func (r *relationshipDB) IsFollowRequested(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, db.Error) { if sourceAccount == nil || targetAccount == nil { return false, nil } @@ -144,7 +144,7 @@ func (r *relationshipDB) FollowRequested(sourceAccount *gtsmodel.Account, target return r.conn.Model(>smodel.FollowRequest{}).Where("account_id = ?", sourceAccount.ID).Where("target_account_id = ?", targetAccount.ID).Exists() } -func (r *relationshipDB) Mutuals(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, db.Error) { +func (r *relationshipDB) IsMutualFollowing(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, db.Error) { if account1 == nil || account2 == nil { return false, nil } diff --git a/internal/db/pg/timeline.go b/internal/db/pg/timeline.go index 41599a785..fa8b07aab 100644 --- a/internal/db/pg/timeline.go +++ b/internal/db/pg/timeline.go @@ -36,7 +36,7 @@ type timelineDB struct { cancel context.CancelFunc } -func (t *timelineDB) GetHomeTimelineForAccount(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, db.Error) { +func (t *timelineDB) GetHomeTimeline(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, db.Error) { statuses := []*gtsmodel.Status{} q := t.conn.Model(&statuses) @@ -96,7 +96,7 @@ func (t *timelineDB) GetHomeTimelineForAccount(accountID string, maxID string, s return statuses, nil } -func (t *timelineDB) GetPublicTimelineForAccount(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, db.Error) { +func (t *timelineDB) GetPublicTimeline(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, db.Error) { statuses := []*gtsmodel.Status{} q := t.conn.Model(&statuses). @@ -143,7 +143,7 @@ func (t *timelineDB) GetPublicTimelineForAccount(accountID string, maxID string, // TODO optimize this query and the logic here, because it's slow as balls -- it takes like a literal second to return with a limit of 20! // It might be worth serving it through a timeline instead of raw DB queries, like we do for Home feeds. -func (t *timelineDB) GetFavedTimelineForAccount(accountID string, maxID string, minID string, limit int) ([]*gtsmodel.Status, string, string, db.Error) { +func (t *timelineDB) GetFavedTimeline(accountID string, maxID string, minID string, limit int) ([]*gtsmodel.Status, string, string, db.Error) { faves := []*gtsmodel.StatusFave{} diff --git a/internal/db/relationship.go b/internal/db/relationship.go index 8966b9145..e54e776d7 100644 --- a/internal/db/relationship.go +++ b/internal/db/relationship.go @@ -22,9 +22,9 @@ import "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" // Relationship contains functions for getting or modifying the relationship between two accounts. type Relationship interface { - // Blocked checks whether account 1 has a block in place against block2. + // IsBlocked checks whether account 1 has a block in place against block2. // If eitherDirection is true, then the function returns true if account1 blocks account2, OR if account2 blocks account1. - Blocked(account1 string, account2 string, eitherDirection bool) (bool, Error) + IsBlocked(account1 string, account2 string, eitherDirection bool) (bool, Error) // GetBlock returns the block from account1 targeting account2, if it exists, or an error if it doesn't. // @@ -35,14 +35,14 @@ type Relationship interface { // GetRelationship retrieves the relationship of the targetAccount to the requestingAccount. GetRelationship(requestingAccount string, targetAccount string) (*gtsmodel.Relationship, Error) - // Follows returns true if sourceAccount follows target account, or an error if something goes wrong while finding out. - Follows(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, Error) + // IsFollowing returns true if sourceAccount follows target account, or an error if something goes wrong while finding out. + IsFollowing(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, Error) - // FollowRequested returns true if sourceAccount has requested to follow target account, or an error if something goes wrong while finding out. - FollowRequested(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, Error) + // IsFollowRequested returns true if sourceAccount has requested to follow target account, or an error if something goes wrong while finding out. + IsFollowRequested(sourceAccount *gtsmodel.Account, targetAccount *gtsmodel.Account) (bool, Error) - // Mutuals returns true if account1 and account2 both follow each other, or an error if something goes wrong while finding out. - Mutuals(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, Error) + // IsMutualFollowing returns true if account1 and account2 both follow each other, or an error if something goes wrong while finding out. + IsMutualFollowing(account1 *gtsmodel.Account, account2 *gtsmodel.Account) (bool, Error) // AcceptFollowRequest moves a follow request in the database from the follow_requests table to the follows table. // In other words, it should create the follow, and delete the existing follow request. diff --git a/internal/db/timeline.go b/internal/db/timeline.go index ed84b268a..74aa5c781 100644 --- a/internal/db/timeline.go +++ b/internal/db/timeline.go @@ -22,23 +22,23 @@ import "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" // Timeline contains functionality for retrieving home/public/faved etc timelines for an account. type Timeline interface { - // GetHomeTimelineForAccount returns a slice of statuses from accounts that are followed by the given account id. + // GetHomeTimeline returns a slice of statuses from accounts that are followed by the given account id. // // Statuses should be returned in descending order of when they were created (newest first). - GetHomeTimelineForAccount(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, Error) + GetHomeTimeline(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, Error) - // GetPublicTimelineForAccount fetches the account's PUBLIC timeline -- ie., posts and replies that are public. + // GetPublicTimeline fetches the account's PUBLIC timeline -- ie., posts and replies that are public. // It will use the given filters and try to return as many statuses as possible up to the limit. // // Statuses should be returned in descending order of when they were created (newest first). - GetPublicTimelineForAccount(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, Error) + GetPublicTimeline(accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, Error) - // GetFavedTimelineForAccount fetches the account's FAVED timeline -- ie., posts and replies that the requesting account has faved. + // GetFavedTimeline fetches the account's FAVED timeline -- ie., posts and replies that the requesting account has faved. // It will use the given filters and try to return as many statuses as possible up to the limit. // // Note that unlike the other GetTimeline functions, the returned statuses will be arranged by their FAVE id, not the STATUS id. // In other words, they'll be returned in descending order of when they were faved by the requesting user, not when they were created. // // Also note the extra return values, which correspond to the nextMaxID and prevMinID for building Link headers. - GetFavedTimelineForAccount(accountID string, maxID string, minID string, limit int) ([]*gtsmodel.Status, string, string, Error) + GetFavedTimeline(accountID string, maxID string, minID string, limit int) ([]*gtsmodel.Status, string, string, Error) } diff --git a/internal/federation/federatingdb/following.go b/internal/federation/federatingdb/following.go index 953b9032a..ac671968d 100644 --- a/internal/federation/federatingdb/following.go +++ b/internal/federation/federatingdb/following.go @@ -57,7 +57,7 @@ func (f *federatingDB) Following(c context.Context, actorIRI *url.URL) (followin } acctFollowing := []gtsmodel.Follow{} - if err := f.db.GetAccountFollowing(acct.ID, &acctFollowing); err != nil { + if err := f.db.GetAccountFollows(acct.ID, &acctFollowing); err != nil { return nil, fmt.Errorf("FOLLOWING: db error getting following for account id %s: %s", acct.ID, err) } diff --git a/internal/processing/account/createblock.go b/internal/processing/account/createblock.go index 13624c252..f10a2efa3 100644 --- a/internal/processing/account/createblock.go +++ b/internal/processing/account/createblock.go @@ -37,7 +37,7 @@ func (p *processor) BlockCreate(requestingAccount *gtsmodel.Account, targetAccou } // if requestingAccount already blocks target account, we don't need to do anything - if blocked, err := p.db.Blocked(requestingAccount.ID, targetAccountID, false); err != nil { + if blocked, err := p.db.IsBlocked(requestingAccount.ID, targetAccountID, false); err != nil { return nil, gtserror.NewErrorInternalError(fmt.Errorf("BlockCreate: error checking existence of block: %s", err)) } else if blocked { return p.RelationshipGet(requestingAccount, targetAccountID) diff --git a/internal/processing/account/createfollow.go b/internal/processing/account/createfollow.go index 62640e03e..8c856a50e 100644 --- a/internal/processing/account/createfollow.go +++ b/internal/processing/account/createfollow.go @@ -31,7 +31,7 @@ import ( func (p *processor) FollowCreate(requestingAccount *gtsmodel.Account, form *apimodel.AccountFollowRequest) (*apimodel.Relationship, gtserror.WithCode) { // if there's a block between the accounts we shouldn't create the request ofc - if blocked, err := p.db.Blocked(requestingAccount.ID, form.ID, true); err != nil { + if blocked, err := p.db.IsBlocked(requestingAccount.ID, form.ID, true); err != nil { return nil, gtserror.NewErrorInternalError(err) } else if blocked { return nil, gtserror.NewErrorNotFound(fmt.Errorf("block exists between accounts")) @@ -47,7 +47,7 @@ func (p *processor) FollowCreate(requestingAccount *gtsmodel.Account, form *apim } // check if a follow exists already - if follows, err := p.db.Follows(requestingAccount, targetAcct); err != nil { + if follows, err := p.db.IsFollowing(requestingAccount, targetAcct); err != nil { return nil, gtserror.NewErrorInternalError(fmt.Errorf("accountfollowcreate: error checking follow in db: %s", err)) } else if follows { // already follows so just return the relationship @@ -55,7 +55,7 @@ func (p *processor) FollowCreate(requestingAccount *gtsmodel.Account, form *apim } // check if a follow request exists already - if followRequested, err := p.db.FollowRequested(requestingAccount, targetAcct); err != nil { + if followRequested, err := p.db.IsFollowRequested(requestingAccount, targetAcct); err != nil { return nil, gtserror.NewErrorInternalError(fmt.Errorf("accountfollowcreate: error checking follow request in db: %s", err)) } else if followRequested { // already follow requested so just return the relationship diff --git a/internal/processing/account/get.go b/internal/processing/account/get.go index ed6e27c94..3dfc54b51 100644 --- a/internal/processing/account/get.go +++ b/internal/processing/account/get.go @@ -39,7 +39,7 @@ func (p *processor) Get(requestingAccount *gtsmodel.Account, targetAccountID str var blocked bool var err error if requestingAccount != nil { - blocked, err = p.db.Blocked(requestingAccount.ID, targetAccountID, true) + blocked, err = p.db.IsBlocked(requestingAccount.ID, targetAccountID, true) if err != nil { return nil, fmt.Errorf("error checking account block: %s", err) } diff --git a/internal/processing/account/getfollowers.go b/internal/processing/account/getfollowers.go index fddea5553..fd2792471 100644 --- a/internal/processing/account/getfollowers.go +++ b/internal/processing/account/getfollowers.go @@ -28,7 +28,7 @@ import ( ) func (p *processor) FollowersGet(requestingAccount *gtsmodel.Account, targetAccountID string) ([]apimodel.Account, gtserror.WithCode) { - if blocked, err := p.db.Blocked(requestingAccount.ID, targetAccountID, true); err != nil { + if blocked, err := p.db.IsBlocked(requestingAccount.ID, targetAccountID, true); err != nil { return nil, gtserror.NewErrorInternalError(err) } else if blocked { return nil, gtserror.NewErrorNotFound(fmt.Errorf("block exists between accounts")) @@ -44,7 +44,7 @@ func (p *processor) FollowersGet(requestingAccount *gtsmodel.Account, targetAcco } for _, f := range followers { - blocked, err := p.db.Blocked(requestingAccount.ID, f.AccountID, true) + blocked, err := p.db.IsBlocked(requestingAccount.ID, f.AccountID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/account/getfollowing.go b/internal/processing/account/getfollowing.go index 5f7693fbc..69f0c1d8a 100644 --- a/internal/processing/account/getfollowing.go +++ b/internal/processing/account/getfollowing.go @@ -28,7 +28,7 @@ import ( ) func (p *processor) FollowingGet(requestingAccount *gtsmodel.Account, targetAccountID string) ([]apimodel.Account, gtserror.WithCode) { - if blocked, err := p.db.Blocked(requestingAccount.ID, targetAccountID, true); err != nil { + if blocked, err := p.db.IsBlocked(requestingAccount.ID, targetAccountID, true); err != nil { return nil, gtserror.NewErrorInternalError(err) } else if blocked { return nil, gtserror.NewErrorNotFound(fmt.Errorf("block exists between accounts")) @@ -36,7 +36,7 @@ func (p *processor) FollowingGet(requestingAccount *gtsmodel.Account, targetAcco following := []gtsmodel.Follow{} accounts := []apimodel.Account{} - if err := p.db.GetAccountFollowing(targetAccountID, &following); err != nil { + if err := p.db.GetAccountFollows(targetAccountID, &following); err != nil { if err == db.ErrNoEntries { return accounts, nil } @@ -44,7 +44,7 @@ func (p *processor) FollowingGet(requestingAccount *gtsmodel.Account, targetAcco } for _, f := range following { - blocked, err := p.db.Blocked(requestingAccount.ID, f.AccountID, true) + blocked, err := p.db.IsBlocked(requestingAccount.ID, f.AccountID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/account/getstatuses.go b/internal/processing/account/getstatuses.go index e1e3d0006..dc21e7006 100644 --- a/internal/processing/account/getstatuses.go +++ b/internal/processing/account/getstatuses.go @@ -28,7 +28,7 @@ import ( ) func (p *processor) StatusesGet(requestingAccount *gtsmodel.Account, targetAccountID string, limit int, excludeReplies bool, maxID string, pinnedOnly bool, mediaOnly bool) ([]apimodel.Status, gtserror.WithCode) { - if blocked, err := p.db.Blocked(requestingAccount.ID, targetAccountID, true); err != nil { + if blocked, err := p.db.IsBlocked(requestingAccount.ID, targetAccountID, true); err != nil { return nil, gtserror.NewErrorInternalError(err) } else if blocked { return nil, gtserror.NewErrorNotFound(fmt.Errorf("block exists between accounts")) diff --git a/internal/processing/account/removefollow.go b/internal/processing/account/removefollow.go index f05760c19..6646d694e 100644 --- a/internal/processing/account/removefollow.go +++ b/internal/processing/account/removefollow.go @@ -29,7 +29,7 @@ import ( func (p *processor) FollowRemove(requestingAccount *gtsmodel.Account, targetAccountID string) (*apimodel.Relationship, gtserror.WithCode) { // if there's a block between the accounts we shouldn't do anything - blocked, err := p.db.Blocked(requestingAccount.ID, targetAccountID, true) + blocked, err := p.db.IsBlocked(requestingAccount.ID, targetAccountID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/admin/createdomainblock.go b/internal/processing/admin/createdomainblock.go index a58b2c9ad..624f632dc 100644 --- a/internal/processing/admin/createdomainblock.go +++ b/internal/processing/admin/createdomainblock.go @@ -123,7 +123,7 @@ func (p *processor) initiateDomainBlockSideEffects(account *gtsmodel.Account, bl selectAccountsLoop: for { - accounts, err := p.db.GetAccountsForInstance(block.Domain, maxID, limit) + accounts, err := p.db.GetInstanceAccounts(block.Domain, maxID, limit) if err != nil { if err == db.ErrNoEntries { // no accounts left for this instance so we're done diff --git a/internal/processing/federation.go b/internal/processing/federation.go index 997603fa7..cea14b4de 100644 --- a/internal/processing/federation.go +++ b/internal/processing/federation.go @@ -62,7 +62,7 @@ func (p *processor) GetFediUser(ctx context.Context, requestedUsername string, r return nil, gtserror.NewErrorNotAuthorized(err) } - blocked, err := p.db.Blocked(requestedAccount.ID, requestingAccount.ID, true) + blocked, err := p.db.IsBlocked(requestedAccount.ID, requestingAccount.ID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } @@ -106,7 +106,7 @@ func (p *processor) GetFediFollowers(ctx context.Context, requestedUsername stri return nil, gtserror.NewErrorNotAuthorized(err) } - blocked, err := p.db.Blocked(requestedAccount.ID, requestingAccount.ID, true) + blocked, err := p.db.IsBlocked(requestedAccount.ID, requestingAccount.ID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } @@ -151,7 +151,7 @@ func (p *processor) GetFediFollowing(ctx context.Context, requestedUsername stri return nil, gtserror.NewErrorNotAuthorized(err) } - blocked, err := p.db.Blocked(requestedAccount.ID, requestingAccount.ID, true) + blocked, err := p.db.IsBlocked(requestedAccount.ID, requestingAccount.ID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } @@ -198,7 +198,7 @@ func (p *processor) GetFediStatus(ctx context.Context, requestedUsername string, // authorize the request: // 1. check if a block exists between the requester and the requestee - blocked, err := p.db.Blocked(requestedAccount.ID, requestingAccount.ID, true) + blocked, err := p.db.IsBlocked(requestedAccount.ID, requestingAccount.ID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } @@ -258,7 +258,7 @@ func (p *processor) GetFediStatusReplies(ctx context.Context, requestedUsername // authorize the request: // 1. check if a block exists between the requester and the requestee - blocked, err := p.db.Blocked(requestedAccount.ID, requestingAccount.ID, true) + blocked, err := p.db.IsBlocked(requestedAccount.ID, requestingAccount.ID, true) if err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/followrequest.go b/internal/processing/followrequest.go index 21ee740fc..867725023 100644 --- a/internal/processing/followrequest.go +++ b/internal/processing/followrequest.go @@ -27,8 +27,8 @@ import ( ) func (p *processor) FollowRequestsGet(auth *oauth.Auth) ([]apimodel.Account, gtserror.WithCode) { - frs := []gtsmodel.FollowRequest{} - if err := p.db.GetAccountFollowRequests(auth.Account.ID, &frs); err != nil { + frs, err := p.db.GetAccountFollowRequests(auth.Account.ID) + if err != nil { if err != db.ErrNoEntries { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/media/getfile.go b/internal/processing/media/getfile.go index adca406fe..01288c56d 100644 --- a/internal/processing/media/getfile.go +++ b/internal/processing/media/getfile.go @@ -57,7 +57,7 @@ func (p *processor) GetFile(account *gtsmodel.Account, form *apimodel.GetContent // make sure the requesting account and the media account don't block each other if account != nil { - blocked, err := p.db.Blocked(account.ID, form.AccountID, true) + blocked, err := p.db.IsBlocked(account.ID, form.AccountID, true) if err != nil { return nil, gtserror.NewErrorNotFound(fmt.Errorf("block status could not be established between accounts %s and %s: %s", form.AccountID, account.ID, err)) } diff --git a/internal/processing/notification.go b/internal/processing/notification.go index 6ad974126..7af74b04f 100644 --- a/internal/processing/notification.go +++ b/internal/processing/notification.go @@ -27,7 +27,7 @@ import ( func (p *processor) NotificationsGet(authed *oauth.Auth, limit int, maxID string, sinceID string) ([]*apimodel.Notification, gtserror.WithCode) { l := p.log.WithField("func", "NotificationsGet") - notifs, err := p.db.GetNotificationsForAccount(authed.Account.ID, limit, maxID, sinceID) + notifs, err := p.db.GetNotifications(authed.Account.ID, limit, maxID, sinceID) if err != nil { return nil, gtserror.NewErrorInternalError(err) } diff --git a/internal/processing/search.go b/internal/processing/search.go index 2430fbd65..f2ae721ae 100644 --- a/internal/processing/search.go +++ b/internal/processing/search.go @@ -90,7 +90,7 @@ func (p *processor) SearchGet(authed *oauth.Auth, searchQuery *apimodel.SearchQu */ for _, foundAccount := range foundAccounts { // make sure there's no block in either direction between the account and the requester - if blocked, err := p.db.Blocked(authed.Account.ID, foundAccount.ID, true); err == nil && !blocked { + if blocked, err := p.db.IsBlocked(authed.Account.ID, foundAccount.ID, true); err == nil && !blocked { // all good, convert it and add it to the results if acctMasto, err := p.tc.AccountToMastoPublic(foundAccount); err == nil && acctMasto != nil { results.Accounts = append(results.Accounts, *acctMasto) diff --git a/internal/processing/status/boostedby.go b/internal/processing/status/boostedby.go index e65665a32..1bde6b5ae 100644 --- a/internal/processing/status/boostedby.go +++ b/internal/processing/status/boostedby.go @@ -34,7 +34,7 @@ func (p *processor) BoostedBy(requestingAccount *gtsmodel.Account, targetStatusI // filter the list so the user doesn't see accounts they blocked or which blocked them filteredAccounts := []*gtsmodel.Account{} for _, s := range statusReblogs { - blocked, err := p.db.Blocked(requestingAccount.ID, s.AccountID, true) + blocked, err := p.db.IsBlocked(requestingAccount.ID, s.AccountID, true) if err != nil { return nil, gtserror.NewErrorNotFound(fmt.Errorf("StatusBoostedBy: error checking blocks: %s", err)) } diff --git a/internal/processing/status/favedby.go b/internal/processing/status/favedby.go index 92a725035..dffe6bba9 100644 --- a/internal/processing/status/favedby.go +++ b/internal/processing/status/favedby.go @@ -34,7 +34,7 @@ func (p *processor) FavedBy(requestingAccount *gtsmodel.Account, targetStatusID // filter the list so the user doesn't see accounts they blocked or which blocked them filteredAccounts := []*gtsmodel.Account{} for _, fave := range statusFaves { - blocked, err := p.db.Blocked(requestingAccount.ID, fave.AccountID, true) + blocked, err := p.db.IsBlocked(requestingAccount.ID, fave.AccountID, true) if err != nil { return nil, gtserror.NewErrorInternalError(fmt.Errorf("error checking blocks: %s", err)) } diff --git a/internal/processing/status/util.go b/internal/processing/status/util.go index e26997b31..025607f4a 100644 --- a/internal/processing/status/util.go +++ b/internal/processing/status/util.go @@ -119,7 +119,7 @@ func (p *processor) ProcessReplyToID(form *apimodel.AdvancedStatusCreateForm, th return fmt.Errorf("status with id %s not replyable: %s", form.InReplyToID, err) } // check if a block exists - if blocked, err := p.db.Blocked(thisAccountID, repliedAccount.ID, true); err != nil { + if blocked, err := p.db.IsBlocked(thisAccountID, repliedAccount.ID, true); err != nil { if err != db.ErrNoEntries { return fmt.Errorf("status with id %s not replyable: %s", form.InReplyToID, err) } diff --git a/internal/processing/timeline.go b/internal/processing/timeline.go index bceadda73..afddd3e6c 100644 --- a/internal/processing/timeline.go +++ b/internal/processing/timeline.go @@ -74,7 +74,7 @@ func (p *processor) HomeTimelineGet(authed *oauth.Auth, maxID string, sinceID st } func (p *processor) PublicTimelineGet(authed *oauth.Auth, maxID string, sinceID string, minID string, limit int, local bool) (*apimodel.StatusTimelineResponse, gtserror.WithCode) { - statuses, err := p.db.GetPublicTimelineForAccount(authed.Account.ID, maxID, sinceID, minID, limit, local) + statuses, err := p.db.GetPublicTimeline(authed.Account.ID, maxID, sinceID, minID, limit, local) if err != nil { if err == db.ErrNoEntries { // there are just no entries left @@ -95,7 +95,7 @@ func (p *processor) PublicTimelineGet(authed *oauth.Auth, maxID string, sinceID } func (p *processor) FavedTimelineGet(authed *oauth.Auth, maxID string, minID string, limit int) (*apimodel.StatusTimelineResponse, gtserror.WithCode) { - statuses, nextMaxID, prevMinID, err := p.db.GetFavedTimelineForAccount(authed.Account.ID, maxID, minID, limit) + statuses, nextMaxID, prevMinID, err := p.db.GetFavedTimeline(authed.Account.ID, maxID, minID, limit) if err != nil { if err == db.ErrNoEntries { // there are just no entries left diff --git a/internal/timeline/index.go b/internal/timeline/index.go index 0b28c1a19..7cffe7ab9 100644 --- a/internal/timeline/index.go +++ b/internal/timeline/index.go @@ -50,7 +50,7 @@ func (t *timeline) IndexBefore(statusID string, include bool, amount int) error i := 0 grabloop: for ; len(filtered) < amount && i < 5; i = i + 1 { // try the grabloop 5 times only - statuses, err := t.db.GetHomeTimelineForAccount(t.accountID, "", "", offsetStatus, amount, false) + statuses, err := t.db.GetHomeTimeline(t.accountID, "", "", offsetStatus, amount, false) if err != nil { if err == db.ErrNoEntries { break grabloop // we just don't have enough statuses left in the db so index what we've got and then bail @@ -130,7 +130,7 @@ positionLoop: grabloop: for ; len(filtered) < amount && i < 5; i = i + 1 { // try the grabloop 5 times only l.Tracef("entering grabloop; i is %d; len(filtered) is %d", i, len(filtered)) - statuses, err := t.db.GetHomeTimelineForAccount(t.accountID, offsetStatus, "", "", amount, false) + statuses, err := t.db.GetHomeTimeline(t.accountID, offsetStatus, "", "", amount, false) if err != nil { if err == db.ErrNoEntries { break grabloop // we just don't have enough statuses left in the db so index what we've got and then bail diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go index d68a16720..cedd6c3d8 100644 --- a/internal/typeutils/internaltofrontend.go +++ b/internal/typeutils/internaltofrontend.go @@ -38,15 +38,15 @@ func (c *converter) AccountToMastoSensitive(a *gtsmodel.Account) (*model.Account // then adding the Source object to it... // check pending follow requests aimed at this account - fr := []gtsmodel.FollowRequest{} - if err := c.db.GetAccountFollowRequests(a.ID, &fr); err != nil { + frs, err := c.db.GetAccountFollowRequests(a.ID) + if err != nil { if err != db.ErrNoEntries { return nil, fmt.Errorf("error getting follow requests: %s", err) } - } + } var frc int - if fr != nil { - frc = len(fr) + if frs != nil { + frc = len(frs) } mastoAccount.Source = &model.Source{ @@ -567,17 +567,17 @@ func (c *converter) InstanceToMasto(i *gtsmodel.Instance) (*model.Instance, erro statusCountKey := "status_count" domainCountKey := "domain_count" - userCount, err := c.db.GetUserCountForInstance(c.config.Host) + userCount, err := c.db.CountInstanceUsers(c.config.Host) if err == nil { mi.Stats[userCountKey] = userCount } - statusCount, err := c.db.GetStatusCountForInstance(c.config.Host) + statusCount, err := c.db.CountInstanceStatuses(c.config.Host) if err == nil { mi.Stats[statusCountKey] = statusCount } - domainCount, err := c.db.GetDomainCountForInstance(c.config.Host) + domainCount, err := c.db.CountInstanceDomains(c.config.Host) if err == nil { mi.Stats[domainCountKey] = domainCount } diff --git a/internal/visibility/statushometimelineable.go b/internal/visibility/statushometimelineable.go index d1c553a77..a3ca62fb3 100644 --- a/internal/visibility/statushometimelineable.go +++ b/internal/visibility/statushometimelineable.go @@ -85,7 +85,7 @@ func (f *filter) StatusHometimelineable(targetStatus *gtsmodel.Status, timelineO } // the replied-to account != timelineOwnerAccount, so make sure the timelineOwnerAccount follows the replied-to account - follows, err := f.db.Follows(timelineOwnerAccount, targetStatus.InReplyToAccount) + follows, err := f.db.IsFollowing(timelineOwnerAccount, targetStatus.InReplyToAccount) if err != nil { return false, fmt.Errorf("StatusHometimelineable: error checking follow from account %s to account %s: %s", timelineOwnerAccount.ID, targetStatus.InReplyToAccountID, err) } diff --git a/internal/visibility/statusvisible.go b/internal/visibility/statusvisible.go index 588114ed5..15e545881 100644 --- a/internal/visibility/statusvisible.go +++ b/internal/visibility/statusvisible.go @@ -126,7 +126,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // At this point we have a populated targetAccount, targetStatus, and requestingAccount, so we can check for blocks and whathaveyou // First check if a block exists directly between the target account (which authored the status) and the requesting account. - if blocked, err := f.db.Blocked(targetAccount.ID, requestingAccount.ID, true); err != nil { + if blocked, err := f.db.IsBlocked(targetAccount.ID, requestingAccount.ID, true); err != nil { l.Debugf("something went wrong figuring out if the accounts have a block: %s", err) return false, err } else if blocked { @@ -137,7 +137,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // status replies to account id if relevantAccounts.InReplyToAccount != nil && relevantAccounts.InReplyToAccount.ID != requestingAccount.ID { - if blocked, err := f.db.Blocked(relevantAccounts.InReplyToAccount.ID, requestingAccount.ID, true); err != nil { + if blocked, err := f.db.IsBlocked(relevantAccounts.InReplyToAccount.ID, requestingAccount.ID, true); err != nil { return false, err } else if blocked { l.Trace("a block exists between requesting account and reply to account") @@ -146,7 +146,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // check reply to ID if targetStatus.InReplyToID != "" && (targetStatus.Visibility == gtsmodel.VisibilityFollowersOnly || targetStatus.Visibility == gtsmodel.VisibilityDirect) { - followsRepliedAccount, err := f.db.Follows(requestingAccount, relevantAccounts.InReplyToAccount) + followsRepliedAccount, err := f.db.IsFollowing(requestingAccount, relevantAccounts.InReplyToAccount) if err != nil { return false, err } @@ -159,7 +159,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // status boosts accounts id if relevantAccounts.BoostedAccount != nil { - if blocked, err := f.db.Blocked(relevantAccounts.BoostedAccount.ID, requestingAccount.ID, true); err != nil { + if blocked, err := f.db.IsBlocked(relevantAccounts.BoostedAccount.ID, requestingAccount.ID, true); err != nil { return false, err } else if blocked { l.Trace("a block exists between requesting account and boosted account") @@ -169,7 +169,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount // status boosts a reply to account id if relevantAccounts.BoostedInReplyToAccount != nil { - if blocked, err := f.db.Blocked(relevantAccounts.BoostedInReplyToAccount.ID, requestingAccount.ID, true); err != nil { + if blocked, err := f.db.IsBlocked(relevantAccounts.BoostedInReplyToAccount.ID, requestingAccount.ID, true); err != nil { return false, err } else if blocked { l.Trace("a block exists between requesting account and boosted reply to account") @@ -182,7 +182,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount if a == nil { continue } - if blocked, err := f.db.Blocked(a.ID, requestingAccount.ID, true); err != nil { + if blocked, err := f.db.IsBlocked(a.ID, requestingAccount.ID, true); err != nil { return false, err } else if blocked { l.Trace("a block exists between requesting account and a mentioned account") @@ -195,7 +195,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount if a == nil { continue } - if blocked, err := f.db.Blocked(a.ID, requestingAccount.ID, true); err != nil { + if blocked, err := f.db.IsBlocked(a.ID, requestingAccount.ID, true); err != nil { return false, err } else if blocked { l.Trace("a block exists between requesting account and a boosted mentioned account") @@ -221,7 +221,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount return true, nil case gtsmodel.VisibilityFollowersOnly: // check one-way follow - follows, err := f.db.Follows(requestingAccount, targetAccount) + follows, err := f.db.IsFollowing(requestingAccount, targetAccount) if err != nil { return false, err } @@ -232,7 +232,7 @@ func (f *filter) StatusVisible(targetStatus *gtsmodel.Status, requestingAccount return true, nil case gtsmodel.VisibilityMutualsOnly: // check mutual follow - mutuals, err := f.db.Mutuals(requestingAccount, targetAccount) + mutuals, err := f.db.IsMutualFollowing(requestingAccount, targetAccount) if err != nil { return false, err }