summaryrefslogtreecommitdiff
path: root/internal/db/bundb/account.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2021-09-01 10:08:21 +0100
committerLibravatar GitHub <noreply@github.com>2021-09-01 11:08:21 +0200
commit7d193de25fbccc00923d6d791d6d4e0d2d5d498e (patch)
treeda993d91aeaccc07c2fff461067325fbe89bba73 /internal/db/bundb/account.go
parentAdd SQLite support, fix un-thread-safe DB caches, small performance f… (#172) (diff)
downloadgotosocial-7d193de25fbccc00923d6d791d6d4e0d2d5d498e.tar.xz
Improve GetRemoteStatus and db.GetStatus() logic (#174)
* only fetch status parents / children if explicity requested when dereferencing Signed-off-by: kim (grufwub) <grufwub@gmail.com> * Remove recursive DB GetStatus logic, don't fetch parent unless requested Signed-off-by: kim (grufwub) <grufwub@gmail.com> * StatusCache copies status so there are no thread-safety issues with modified status objects Signed-off-by: kim (grufwub) <grufwub@gmail.com> * remove sqlite test files Signed-off-by: kim (grufwub) <grufwub@gmail.com> * fix bugs introduced by previous commit Signed-off-by: kim (grufwub) <grufwub@gmail.com> * fix not continue on error in loop Signed-off-by: kim (grufwub) <grufwub@gmail.com> * use our own RunInTx implementation (possible fix for nested tx error) Signed-off-by: kim (grufwub) <grufwub@gmail.com> * fix cast statement to work with SQLite Signed-off-by: kim (grufwub) <grufwub@gmail.com> * be less strict about valid status in cache Signed-off-by: kim (grufwub) <grufwub@gmail.com> * add cache=shared ALWAYS for SQLite db instances Signed-off-by: kim (grufwub) <grufwub@gmail.com> * Fix EnrichRemoteAccount when updating account fails Signed-off-by: kim (grufwub) <grufwub@gmail.com> * add nolint tag Signed-off-by: kim (grufwub) <grufwub@gmail.com> * ensure file: prefixes the filename in sqlite addr Signed-off-by: kim (grufwub) <grufwub@gmail.com> * add an account cache, add status author account from db Signed-off-by: kim (grufwub) <grufwub@gmail.com> * Fix incompatible SQLite query Signed-off-by: kim (grufwub) <grufwub@gmail.com> * *actually* use the new getAccount() function in accountsDB Signed-off-by: kim (grufwub) <grufwub@gmail.com> * update cache tests to use test suite Signed-off-by: kim (grufwub) <grufwub@gmail.com> * add RelationshipTestSuite, add tests for methods with changed SQL Signed-off-by: kim (grufwub) <grufwub@gmail.com>
Diffstat (limited to 'internal/db/bundb/account.go')
-rw-r--r--internal/db/bundb/account.go86
1 files changed, 54 insertions, 32 deletions
diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go
index d7d45a739..32a70f7cd 100644
--- a/internal/db/bundb/account.go
+++ b/internal/db/bundb/account.go
@@ -25,6 +25,7 @@ import (
"strings"
"time"
+ "github.com/superseriousbusiness/gotosocial/internal/cache"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -34,6 +35,7 @@ import (
type accountDB struct {
config *config.Config
conn *DBConn
+ cache *cache.AccountCache
}
func (a *accountDB) newAccountQ(account *gtsmodel.Account) *bun.SelectQuery {
@@ -45,60 +47,80 @@ func (a *accountDB) newAccountQ(account *gtsmodel.Account) *bun.SelectQuery {
}
func (a *accountDB) GetAccountByID(ctx context.Context, id string) (*gtsmodel.Account, db.Error) {
- account := new(gtsmodel.Account)
-
- q := a.newAccountQ(account).
- Where("account.id = ?", id)
-
- err := q.Scan(ctx)
- if err != nil {
- return nil, a.conn.ProcessError(err)
- }
- return account, nil
+ return a.getAccount(
+ ctx,
+ func() (*gtsmodel.Account, bool) {
+ return a.cache.GetByID(id)
+ },
+ func(account *gtsmodel.Account) error {
+ return a.newAccountQ(account).Where("account.id = ?", id).Scan(ctx)
+ },
+ )
}
func (a *accountDB) GetAccountByURI(ctx context.Context, uri string) (*gtsmodel.Account, db.Error) {
- account := new(gtsmodel.Account)
-
- q := a.newAccountQ(account).
- Where("account.uri = ?", uri)
+ return a.getAccount(
+ ctx,
+ func() (*gtsmodel.Account, bool) {
+ return a.cache.GetByURI(uri)
+ },
+ func(account *gtsmodel.Account) error {
+ return a.newAccountQ(account).Where("account.uri = ?", uri).Scan(ctx)
+ },
+ )
+}
- err := q.Scan(ctx)
- if err != nil {
- return nil, a.conn.ProcessError(err)
- }
- return account, nil
+func (a *accountDB) GetAccountByURL(ctx context.Context, url string) (*gtsmodel.Account, db.Error) {
+ return a.getAccount(
+ ctx,
+ func() (*gtsmodel.Account, bool) {
+ return a.cache.GetByURL(url)
+ },
+ func(account *gtsmodel.Account) error {
+ return a.newAccountQ(account).Where("account.url = ?", url).Scan(ctx)
+ },
+ )
}
-func (a *accountDB) GetAccountByURL(ctx context.Context, uri string) (*gtsmodel.Account, db.Error) {
- account := new(gtsmodel.Account)
+func (a *accountDB) getAccount(ctx context.Context, cacheGet func() (*gtsmodel.Account, bool), dbQuery func(*gtsmodel.Account) error) (*gtsmodel.Account, db.Error) {
+ // Attempt to fetch cached account
+ account, cached := cacheGet()
- q := a.newAccountQ(account).
- Where("account.url = ?", uri)
+ if !cached {
+ account = &gtsmodel.Account{}
- err := q.Scan(ctx)
- if err != nil {
- return nil, a.conn.ProcessError(err)
+ // Not cached! Perform database query
+ err := dbQuery(account)
+ if err != nil {
+ return nil, a.conn.ProcessError(err)
+ }
+
+ // Place in the cache
+ a.cache.Put(account)
}
+
return account, nil
}
func (a *accountDB) UpdateAccount(ctx context.Context, account *gtsmodel.Account) (*gtsmodel.Account, db.Error) {
if strings.TrimSpace(account.ID) == "" {
+ // TODO: we should not need this check here
return nil, errors.New("account had no ID")
}
+ // Update the account's last-used
account.UpdatedAt = time.Now()
- q := a.conn.
- NewUpdate().
- Model(account).
- WherePK()
-
- _, err := q.Exec(ctx)
+ // Update the account model in the DB
+ _, err := a.conn.NewUpdate().Model(account).WherePK().Exec(ctx)
if err != nil {
return nil, a.conn.ProcessError(err)
}
+
+ // Place updated account in cache
+ // (this will replace existing, i.e. invalidating)
+ a.cache.Put(account)
+
return account, nil
}