summaryrefslogtreecommitdiff
path: root/internal/db
diff options
context:
space:
mode:
Diffstat (limited to 'internal/db')
-rw-r--r--internal/db/account.go17
-rw-r--r--internal/db/bundb/account.go29
-rw-r--r--internal/db/bundb/admin.go25
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 := &gtsmodel.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 := &gtsmodel.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 := &gtsmodel.AccountSettings{
- AccountID: accountID,
- Privacy: gtsmodel.VisibilityDefault,
- }
-
- // Insert the settings!
- if err := a.state.DB.PutAccountSettings(ctx, settings); err != nil {
- return nil, err
- }
-
account = &gtsmodel.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 = &gtsmodel.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.