diff options
Diffstat (limited to 'internal/db')
-rw-r--r-- | internal/db/account.go | 17 | ||||
-rw-r--r-- | internal/db/bundb/account.go | 29 | ||||
-rw-r--r-- | internal/db/bundb/admin.go | 25 |
3 files changed, 58 insertions, 13 deletions
diff --git a/internal/db/account.go b/internal/db/account.go index 4f02a4d29..45a4ccc09 100644 --- a/internal/db/account.go +++ b/internal/db/account.go @@ -140,10 +140,23 @@ type Account interface { // Update local account settings. UpdateAccountSettings(ctx context.Context, settings *gtsmodel.AccountSettings, columns ...string) error - // PopulateAccountStats gets (or creates and gets) account stats for - // the given account, and attaches them to the account model. + // PopulateAccountStats either creates account stats for the given + // account by performing COUNT(*) database queries, or retrieves + // existing stats from the database, and attaches stats to account. + // + // If account is local and stats were last regenerated > 48 hours ago, + // stats will always be regenerated using COUNT(*) queries, to prevent drift. PopulateAccountStats(ctx context.Context, account *gtsmodel.Account) error + // StubAccountStats creates zeroed account stats for the given account, + // skipping COUNT(*) queries, upserts them in the DB, and attaches them + // to the account model. + // + // Useful following fresh dereference of a remote account, or fresh + // creation of a local account, when you know all COUNT(*) queries + // would return 0 anyway. + StubAccountStats(ctx context.Context, account *gtsmodel.Account) error + // RegenerateAccountStats creates, upserts, and returns stats // for the given account, and attaches them to the account model. // diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index eb5385c70..43978243a 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -1217,6 +1217,35 @@ func (a *accountDB) PopulateAccountStats(ctx context.Context, account *gtsmodel. return nil } +func (a *accountDB) StubAccountStats(ctx context.Context, account *gtsmodel.Account) error { + stats := >smodel.AccountStats{ + AccountID: account.ID, + RegeneratedAt: time.Now(), + FollowersCount: util.Ptr(0), + FollowingCount: util.Ptr(0), + FollowRequestsCount: util.Ptr(0), + StatusesCount: util.Ptr(0), + StatusesPinnedCount: util.Ptr(0), + } + + // Upsert this stats in case a race + // meant someone else inserted it first. + if err := a.state.Caches.GTS.AccountStats.Store(stats, func() error { + if _, err := NewUpsert(a.db). + Model(stats). + Constraint("account_id"). + Exec(ctx); err != nil { + return err + } + return nil + }); err != nil { + return err + } + + account.Stats = stats + return nil +} + func (a *accountDB) RegenerateAccountStats(ctx context.Context, account *gtsmodel.Account) error { // Initialize a new stats struct. stats := >smodel.AccountStats{ diff --git a/internal/db/bundb/admin.go b/internal/db/bundb/admin.go index e9191b7c7..ff398fca5 100644 --- a/internal/db/bundb/admin.go +++ b/internal/db/bundb/admin.go @@ -120,16 +120,6 @@ func (a *adminDB) NewSignup(ctx context.Context, newSignup gtsmodel.NewSignup) ( return nil, err } - settings := >smodel.AccountSettings{ - AccountID: accountID, - Privacy: gtsmodel.VisibilityDefault, - } - - // Insert the settings! - if err := a.state.DB.PutAccountSettings(ctx, settings); err != nil { - return nil, err - } - account = >smodel.Account{ ID: accountID, Username: newSignup.Username, @@ -145,13 +135,26 @@ func (a *adminDB) NewSignup(ctx context.Context, newSignup gtsmodel.NewSignup) ( PrivateKey: privKey, PublicKey: &privKey.PublicKey, PublicKeyURI: uris.PublicKeyURI, - Settings: settings, } // Insert the new account! if err := a.state.DB.PutAccount(ctx, account); err != nil { return nil, err } + + // Insert basic settings for new account. + account.Settings = >smodel.AccountSettings{ + AccountID: accountID, + Privacy: gtsmodel.VisibilityDefault, + } + if err := a.state.DB.PutAccountSettings(ctx, account.Settings); err != nil { + return nil, err + } + + // Stub empty stats for new account. + if err := a.state.DB.StubAccountStats(ctx, account); err != nil { + return nil, err + } } // Created or already had an account. |