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.  | 
