diff options
Diffstat (limited to 'internal/db/bundb')
-rw-r--r-- | internal/db/bundb/account.go | 39 | ||||
-rw-r--r-- | internal/db/bundb/admin.go | 12 | ||||
-rw-r--r-- | internal/db/bundb/bundb.go | 94 | ||||
-rw-r--r-- | internal/db/bundb/bundbnew_test.go | 4 | ||||
-rw-r--r-- | internal/db/bundb/domain.go | 26 | ||||
-rw-r--r-- | internal/db/bundb/emoji.go | 63 | ||||
-rw-r--r-- | internal/db/bundb/mention.go | 22 | ||||
-rw-r--r-- | internal/db/bundb/notification.go | 24 | ||||
-rw-r--r-- | internal/db/bundb/relationship.go | 37 | ||||
-rw-r--r-- | internal/db/bundb/status.go | 44 | ||||
-rw-r--r-- | internal/db/bundb/timeline.go | 11 | ||||
-rw-r--r-- | internal/db/bundb/tombstone.go | 28 | ||||
-rw-r--r-- | internal/db/bundb/user.go | 43 |
13 files changed, 132 insertions, 315 deletions
diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index ea0852d77..9f3fc8a16 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -25,39 +25,18 @@ import ( "strings" "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect" ) type accountDB struct { - conn *DBConn - cache *result.Cache[*gtsmodel.Account] - emojis *emojiDB - status *statusDB -} - -func (a *accountDB) init() { - // Initialize account result cache - a.cache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - {Name: "URI"}, - {Name: "URL"}, - {Name: "Username.Domain"}, - {Name: "PublicKeyURI"}, - }, func(a1 *gtsmodel.Account) *gtsmodel.Account { - a2 := new(gtsmodel.Account) - *a2 = *a1 - return a2 - }, 1000) - - // Set cache TTL and start sweep routine - a.cache.SetTTL(time.Minute*5, false) - a.cache.Start(time.Second * 10) + conn *DBConn + state *state.State } func (a *accountDB) newAccountQ(account *gtsmodel.Account) *bun.SelectQuery { @@ -152,7 +131,7 @@ func (a *accountDB) GetInstanceAccount(ctx context.Context, domain string) (*gts func (a *accountDB) getAccount(ctx context.Context, lookup string, dbQuery func(*gtsmodel.Account) error, keyParts ...any) (*gtsmodel.Account, db.Error) { // Fetch account from database cache with loader callback - account, err := a.cache.Load(lookup, func() (*gtsmodel.Account, error) { + account, err := a.state.Caches.GTS.Account().Load(lookup, func() (*gtsmodel.Account, error) { var account gtsmodel.Account // Not cached! Perform database query @@ -168,7 +147,7 @@ func (a *accountDB) getAccount(ctx context.Context, lookup string, dbQuery func( if len(account.EmojiIDs) > 0 { // Set the account's related emojis - account.Emojis, err = a.emojis.emojisFromIDs(ctx, account.EmojiIDs) + account.Emojis, err = a.state.DB.GetEmojisByIDs(ctx, account.EmojiIDs) if err != nil { return nil, fmt.Errorf("error getting account emojis: %w", err) } @@ -178,7 +157,7 @@ func (a *accountDB) getAccount(ctx context.Context, lookup string, dbQuery func( } func (a *accountDB) PutAccount(ctx context.Context, account *gtsmodel.Account) db.Error { - return a.cache.Store(account, func() error { + return a.state.Caches.GTS.Account().Store(account, func() error { // It is safe to run this database transaction within cache.Store // as the cache does not attempt a mutex lock until AFTER hook. // @@ -204,7 +183,7 @@ func (a *accountDB) UpdateAccount(ctx context.Context, account *gtsmodel.Account // Update the account's last-updated account.UpdatedAt = time.Now() - return a.cache.Store(account, func() error { + return a.state.Caches.GTS.Account().Store(account, func() error { // It is safe to run this database transaction within cache.Store // as the cache does not attempt a mutex lock until AFTER hook. // @@ -263,7 +242,7 @@ func (a *accountDB) DeleteAccount(ctx context.Context, id string) db.Error { return err } - a.cache.Invalidate("ID", id) + a.state.Caches.GTS.Account().Invalidate("ID", id) return nil } @@ -514,7 +493,7 @@ func (a *accountDB) statusesFromIDs(ctx context.Context, statusIDs []string) ([] for _, id := range statusIDs { // Fetch from status from database by ID - status, err := a.status.GetStatusByID(ctx, id) + status, err := a.state.DB.GetStatusByID(ctx, id) if err != nil { log.Errorf("statusesFromIDs: error getting status %q: %v", id, err) continue diff --git a/internal/db/bundb/admin.go b/internal/db/bundb/admin.go index 2a8851684..d3554f298 100644 --- a/internal/db/bundb/admin.go +++ b/internal/db/bundb/admin.go @@ -34,6 +34,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/superseriousbusiness/gotosocial/internal/uris" "github.com/uptrace/bun" "golang.org/x/crypto/bcrypt" @@ -43,9 +44,8 @@ import ( const rsaKeyBits = 2048 type adminDB struct { - conn *DBConn - accounts *accountDB - users *userDB + conn *DBConn + state *state.State } func (a *adminDB) IsUsernameAvailable(ctx context.Context, username string) (bool, db.Error) { @@ -139,7 +139,7 @@ func (a *adminDB) NewSignup(ctx context.Context, username string, reason string, } // insert the new account! - if err := a.accounts.PutAccount(ctx, acct); err != nil { + if err := a.state.DB.PutAccount(ctx, acct); err != nil { return nil, err } } @@ -185,7 +185,7 @@ func (a *adminDB) NewSignup(ctx context.Context, username string, reason string, } // insert the user! - if err := a.users.PutUser(ctx, u); err != nil { + if err := a.state.DB.PutUser(ctx, u); err != nil { return nil, err } @@ -241,7 +241,7 @@ func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error { } // insert the new account! - if err := a.accounts.PutAccount(ctx, acct); err != nil { + if err := a.state.DB.PutAccount(ctx, acct); err != nil { return err } diff --git a/internal/db/bundb/bundb.go b/internal/db/bundb/bundb.go index 163174456..fa32f32eb 100644 --- a/internal/db/bundb/bundb.go +++ b/internal/db/bundb/bundb.go @@ -40,6 +40,7 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect/pgdialect" "github.com/uptrace/bun/dialect/sqlitedialect" @@ -122,7 +123,7 @@ func doMigration(ctx context.Context, db *bun.DB) error { // NewBunDBService returns a bunDB derived from the provided config, which implements the go-fed DB interface. // Under the hood, it uses https://github.com/uptrace/bun to create and maintain a database connection. -func NewBunDBService(ctx context.Context) (db.DB, error) { +func NewBunDBService(ctx context.Context, state *state.State) (db.DB, error) { var conn *DBConn var err error dbType := strings.ToLower(config.GetDbType()) @@ -158,69 +159,64 @@ func NewBunDBService(ctx context.Context) (db.DB, error) { return nil, fmt.Errorf("db migration error: %s", err) } - // Create DB structs that require ptrs to each other - account := &accountDB{conn: conn} - admin := &adminDB{conn: conn} - domain := &domainDB{conn: conn} - mention := &mentionDB{conn: conn} - notif := ¬ificationDB{conn: conn} - status := &statusDB{conn: conn} - emoji := &emojiDB{conn: conn} - relationship := &relationshipDB{conn: conn} - timeline := &timelineDB{conn: conn} - tombstone := &tombstoneDB{conn: conn} - user := &userDB{conn: conn} - - // Setup DB cross-referencing - account.emojis = emoji - account.status = status - admin.users = user - relationship.accounts = account - status.accounts = account - status.emojis = emoji - status.mentions = mention - timeline.status = status - - // Initialize db structs - account.init() - domain.init() - emoji.init() - mention.init() - notif.init() - relationship.init() - status.init() - tombstone.init() - user.init() - ps := &DBService{ - Account: account, + Account: &accountDB{ + conn: conn, + state: state, + }, Admin: &adminDB{ - conn: conn, - accounts: account, - users: user, + conn: conn, + state: state, }, Basic: &basicDB{ conn: conn, }, - Domain: domain, - Emoji: emoji, + Domain: &domainDB{ + conn: conn, + state: state, + }, + Emoji: &emojiDB{ + conn: conn, + state: state, + }, Instance: &instanceDB{ conn: conn, }, Media: &mediaDB{ conn: conn, }, - Mention: mention, - Notification: notif, - Relationship: relationship, + Mention: &mentionDB{ + conn: conn, + state: state, + }, + Notification: ¬ificationDB{ + conn: conn, + state: state, + }, + Relationship: &relationshipDB{ + conn: conn, + state: state, + }, Session: &sessionDB{ conn: conn, }, - Status: status, - Timeline: timeline, - User: user, - Tombstone: tombstone, - conn: conn, + Status: &statusDB{ + conn: conn, + state: state, + }, + Timeline: &timelineDB{ + conn: conn, + state: state, + }, + User: &userDB{ + conn: conn, + state: state, + }, + Tombstone: &tombstoneDB{ + conn: conn, + state: state, + }, + conn: conn, } // we can confidently return this useable service now diff --git a/internal/db/bundb/bundbnew_test.go b/internal/db/bundb/bundbnew_test.go index 2bd945864..bdc1eae03 100644 --- a/internal/db/bundb/bundbnew_test.go +++ b/internal/db/bundb/bundbnew_test.go @@ -33,7 +33,7 @@ type BundbNewTestSuite struct { func (suite *BundbNewTestSuite) TestCreateNewDB() { // create a new db with standard test settings - db, err := bundb.NewBunDBService(context.Background()) + db, err := bundb.NewBunDBService(context.Background(), nil) suite.NoError(err) suite.NotNil(db) } @@ -42,7 +42,7 @@ func (suite *BundbNewTestSuite) TestCreateNewSqliteDBNoAddress() { // create a new db with no address specified config.SetDbAddress("") config.SetDbType("sqlite") - db, err := bundb.NewBunDBService(context.Background()) + db, err := bundb.NewBunDBService(context.Background(), nil) suite.EqualError(err, "'db-address' was not set when attempting to start sqlite") suite.Nil(db) } diff --git a/internal/db/bundb/domain.go b/internal/db/bundb/domain.go index ea2e4f077..a5d9f61e2 100644 --- a/internal/db/bundb/domain.go +++ b/internal/db/bundb/domain.go @@ -22,34 +22,18 @@ import ( "context" "net/url" "strings" - "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" "golang.org/x/net/idna" ) type domainDB struct { conn *DBConn - cache *result.Cache[*gtsmodel.DomainBlock] -} - -func (d *domainDB) init() { - // Initialize domain block result cache - d.cache = result.NewSized([]result.Lookup{ - {Name: "Domain"}, - }, func(d1 *gtsmodel.DomainBlock) *gtsmodel.DomainBlock { - d2 := new(gtsmodel.DomainBlock) - *d2 = *d1 - return d2 - }, 1000) - - // Set cache TTL and start sweep routine - d.cache.SetTTL(time.Minute*5, false) - d.cache.Start(time.Second * 10) + state *state.State } // normalizeDomain converts the given domain to lowercase @@ -71,7 +55,7 @@ func (d *domainDB) CreateDomainBlock(ctx context.Context, block *gtsmodel.Domain return err } - return d.cache.Store(block, func() error { + return d.state.Caches.GTS.DomainBlock().Store(block, func() error { _, err := d.conn.NewInsert(). Model(block). Exec(ctx) @@ -87,7 +71,7 @@ func (d *domainDB) GetDomainBlock(ctx context.Context, domain string) (*gtsmodel return nil, err } - return d.cache.Load("Domain", func() (*gtsmodel.DomainBlock, error) { + return d.state.Caches.GTS.DomainBlock().Load("Domain", func() (*gtsmodel.DomainBlock, error) { // Check for easy case, domain referencing *us* if domain == "" || domain == config.GetAccountDomain() { return nil, db.ErrNoEntries @@ -125,7 +109,7 @@ func (d *domainDB) DeleteDomainBlock(ctx context.Context, domain string) db.Erro } // Clear domain from cache - d.cache.Invalidate("Domain", domain) + d.state.Caches.GTS.DomainBlock().Invalidate(domain) return nil } diff --git a/internal/db/bundb/emoji.go b/internal/db/bundb/emoji.go index 554d8f560..4407fe81c 100644 --- a/internal/db/bundb/emoji.go +++ b/internal/db/bundb/emoji.go @@ -23,50 +23,17 @@ import ( "strings" "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect" ) type emojiDB struct { - conn *DBConn - emojiCache *result.Cache[*gtsmodel.Emoji] - categoryCache *result.Cache[*gtsmodel.EmojiCategory] -} - -func (e *emojiDB) init() { - // Initialize emoji result cache - e.emojiCache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - {Name: "URI"}, - {Name: "Shortcode.Domain"}, - {Name: "ImageStaticURL"}, - }, func(e1 *gtsmodel.Emoji) *gtsmodel.Emoji { - e2 := new(gtsmodel.Emoji) - *e2 = *e1 - return e2 - }, 1000) - - // Set cache TTL and start sweep routine - e.emojiCache.SetTTL(time.Minute*5, false) - e.emojiCache.Start(time.Second * 10) - - // Initialize category result cache - e.categoryCache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - {Name: "Name"}, - }, func(c1 *gtsmodel.EmojiCategory) *gtsmodel.EmojiCategory { - c2 := new(gtsmodel.EmojiCategory) - *c2 = *c1 - return c2 - }, 1000) - - // Set cache TTL and start sweep routine - e.categoryCache.SetTTL(time.Minute*5, false) - e.categoryCache.Start(time.Second * 10) + conn *DBConn + state *state.State } func (e *emojiDB) newEmojiQ(emoji *gtsmodel.Emoji) *bun.SelectQuery { @@ -83,7 +50,7 @@ func (e *emojiDB) newEmojiCategoryQ(emojiCategory *gtsmodel.EmojiCategory) *bun. } func (e *emojiDB) PutEmoji(ctx context.Context, emoji *gtsmodel.Emoji) db.Error { - return e.emojiCache.Store(emoji, func() error { + return e.state.Caches.GTS.Emoji().Store(emoji, func() error { _, err := e.conn.NewInsert().Model(emoji).Exec(ctx) return e.conn.ProcessError(err) }) @@ -102,7 +69,7 @@ func (e *emojiDB) UpdateEmoji(ctx context.Context, emoji *gtsmodel.Emoji, column return nil, e.conn.ProcessError(err) } - e.emojiCache.Invalidate("ID", emoji.ID) + e.state.Caches.GTS.Emoji().Invalidate("ID", emoji.ID) return emoji, nil } @@ -139,7 +106,7 @@ func (e *emojiDB) DeleteEmojiByID(ctx context.Context, id string) db.Error { return err } - e.emojiCache.Invalidate("ID", id) + e.state.Caches.GTS.Emoji().Invalidate("ID", id) return nil } @@ -257,7 +224,7 @@ func (e *emojiDB) GetEmojis(ctx context.Context, domain string, includeDisabled } } - return e.emojisFromIDs(ctx, emojiIDs) + return e.GetEmojisByIDs(ctx, emojiIDs) } func (e *emojiDB) GetUseableEmojis(ctx context.Context) ([]*gtsmodel.Emoji, db.Error) { @@ -276,7 +243,7 @@ func (e *emojiDB) GetUseableEmojis(ctx context.Context) ([]*gtsmodel.Emoji, db.E return nil, e.conn.ProcessError(err) } - return e.emojisFromIDs(ctx, emojiIDs) + return e.GetEmojisByIDs(ctx, emojiIDs) } func (e *emojiDB) GetEmojiByID(ctx context.Context, id string) (*gtsmodel.Emoji, db.Error) { @@ -338,7 +305,7 @@ func (e *emojiDB) GetEmojiByStaticURL(ctx context.Context, imageStaticURL string } func (e *emojiDB) PutEmojiCategory(ctx context.Context, emojiCategory *gtsmodel.EmojiCategory) db.Error { - return e.categoryCache.Store(emojiCategory, func() error { + return e.state.Caches.GTS.EmojiCategory().Store(emojiCategory, func() error { _, err := e.conn.NewInsert().Model(emojiCategory).Exec(ctx) return e.conn.ProcessError(err) }) @@ -357,7 +324,7 @@ func (e *emojiDB) GetEmojiCategories(ctx context.Context) ([]*gtsmodel.EmojiCate return nil, e.conn.ProcessError(err) } - return e.emojiCategoriesFromIDs(ctx, emojiCategoryIDs) + return e.GetEmojiCategoriesByIDs(ctx, emojiCategoryIDs) } func (e *emojiDB) GetEmojiCategory(ctx context.Context, id string) (*gtsmodel.EmojiCategory, db.Error) { @@ -383,7 +350,7 @@ func (e *emojiDB) GetEmojiCategoryByName(ctx context.Context, name string) (*gts } func (e *emojiDB) getEmoji(ctx context.Context, lookup string, dbQuery func(*gtsmodel.Emoji) error, keyParts ...any) (*gtsmodel.Emoji, db.Error) { - return e.emojiCache.Load(lookup, func() (*gtsmodel.Emoji, error) { + return e.state.Caches.GTS.Emoji().Load(lookup, func() (*gtsmodel.Emoji, error) { var emoji gtsmodel.Emoji // Not cached! Perform database query @@ -395,8 +362,7 @@ func (e *emojiDB) getEmoji(ctx context.Context, lookup string, dbQuery func(*gts }, keyParts...) } -func (e *emojiDB) emojisFromIDs(ctx context.Context, emojiIDs []string) ([]*gtsmodel.Emoji, db.Error) { - // Catch case of no emojis early +func (e *emojiDB) GetEmojisByIDs(ctx context.Context, emojiIDs []string) ([]*gtsmodel.Emoji, db.Error) { if len(emojiIDs) == 0 { return nil, db.ErrNoEntries } @@ -417,7 +383,7 @@ func (e *emojiDB) emojisFromIDs(ctx context.Context, emojiIDs []string) ([]*gtsm } func (e *emojiDB) getEmojiCategory(ctx context.Context, lookup string, dbQuery func(*gtsmodel.EmojiCategory) error, keyParts ...any) (*gtsmodel.EmojiCategory, db.Error) { - return e.categoryCache.Load(lookup, func() (*gtsmodel.EmojiCategory, error) { + return e.state.Caches.GTS.EmojiCategory().Load(lookup, func() (*gtsmodel.EmojiCategory, error) { var category gtsmodel.EmojiCategory // Not cached! Perform database query @@ -429,8 +395,7 @@ func (e *emojiDB) getEmojiCategory(ctx context.Context, lookup string, dbQuery f }, keyParts...) } -func (e *emojiDB) emojiCategoriesFromIDs(ctx context.Context, emojiCategoryIDs []string) ([]*gtsmodel.EmojiCategory, db.Error) { - // Catch case of no emoji categories early +func (e *emojiDB) GetEmojiCategoriesByIDs(ctx context.Context, emojiCategoryIDs []string) ([]*gtsmodel.EmojiCategory, db.Error) { if len(emojiCategoryIDs) == 0 { return nil, db.ErrNoEntries } diff --git a/internal/db/bundb/mention.go b/internal/db/bundb/mention.go index 303e16484..5ba56104c 100644 --- a/internal/db/bundb/mention.go +++ b/internal/db/bundb/mention.go @@ -20,33 +20,17 @@ package bundb import ( "context" - "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" ) type mentionDB struct { conn *DBConn - cache *result.Cache[*gtsmodel.Mention] -} - -func (m *mentionDB) init() { - // Initialize notification result cache - m.cache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - }, func(m1 *gtsmodel.Mention) *gtsmodel.Mention { - m2 := new(gtsmodel.Mention) - *m2 = *m1 - return m2 - }, 1000) - - // Set cache TTL and start sweep routine - m.cache.SetTTL(time.Minute*5, false) - m.cache.Start(time.Second * 10) + state *state.State } func (m *mentionDB) newMentionQ(i interface{}) *bun.SelectQuery { @@ -59,7 +43,7 @@ func (m *mentionDB) newMentionQ(i interface{}) *bun.SelectQuery { } func (m *mentionDB) GetMention(ctx context.Context, id string) (*gtsmodel.Mention, db.Error) { - return m.cache.Load("ID", func() (*gtsmodel.Mention, error) { + return m.state.Caches.GTS.Mention().Load("ID", func() (*gtsmodel.Mention, error) { var mention gtsmodel.Mention q := m.newMentionQ(&mention). diff --git a/internal/db/bundb/notification.go b/internal/db/bundb/notification.go index 6a8fab464..a65d799c3 100644 --- a/internal/db/bundb/notification.go +++ b/internal/db/bundb/notification.go @@ -20,37 +20,21 @@ package bundb import ( "context" - "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" ) type notificationDB struct { conn *DBConn - cache *result.Cache[*gtsmodel.Notification] -} - -func (n *notificationDB) init() { - // Initialize notification result cache - n.cache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - }, func(n1 *gtsmodel.Notification) *gtsmodel.Notification { - n2 := new(gtsmodel.Notification) - *n2 = *n1 - return n2 - }, 1000) - - // Set cache TTL and start sweep routine - n.cache.SetTTL(time.Minute*5, false) - n.cache.Start(time.Second * 10) + state *state.State } func (n *notificationDB) GetNotification(ctx context.Context, id string) (*gtsmodel.Notification, db.Error) { - return n.cache.Load("ID", func() (*gtsmodel.Notification, error) { + return n.state.Caches.GTS.Notification().Load("ID", func() (*gtsmodel.Notification, error) { var notif gtsmodel.Notification q := n.conn.NewSelect(). @@ -130,6 +114,6 @@ func (n *notificationDB) ClearNotifications(ctx context.Context, accountID strin return n.conn.ProcessError(err) } - n.cache.Clear() + n.state.Caches.GTS.Notification().Clear() return nil } diff --git a/internal/db/bundb/relationship.go b/internal/db/bundb/relationship.go index f6df95524..deab74d61 100644 --- a/internal/db/bundb/relationship.go +++ b/internal/db/bundb/relationship.go @@ -23,35 +23,16 @@ import ( "database/sql" "errors" "fmt" - "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" ) type relationshipDB struct { - conn *DBConn - accounts *accountDB - blockCache *result.Cache[*gtsmodel.Block] -} - -func (r *relationshipDB) init() { - // Initialize block result cache - r.blockCache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - {Name: "AccountID.TargetAccountID"}, - {Name: "URI"}, - }, func(b1 *gtsmodel.Block) *gtsmodel.Block { - b2 := new(gtsmodel.Block) - *b2 = *b1 - return b2 - }, 1000) - - // Set cache TTL and start sweep routine - r.blockCache.SetTTL(time.Minute*5, false) - r.blockCache.Start(time.Second * 10) + conn *DBConn + state *state.State } func (r *relationshipDB) newFollowQ(follow interface{}) *bun.SelectQuery { @@ -94,13 +75,13 @@ func (r *relationshipDB) GetBlock(ctx context.Context, account1 string, account2 } // Set the block originating account - block.Account, err = r.accounts.GetAccountByID(ctx, block.AccountID) + block.Account, err = r.state.DB.GetAccountByID(ctx, block.AccountID) if err != nil { return nil, err } // Set the block target account - block.TargetAccount, err = r.accounts.GetAccountByID(ctx, block.TargetAccountID) + block.TargetAccount, err = r.state.DB.GetAccountByID(ctx, block.TargetAccountID) if err != nil { return nil, err } @@ -109,7 +90,7 @@ func (r *relationshipDB) GetBlock(ctx context.Context, account1 string, account2 } func (r *relationshipDB) getBlock(ctx context.Context, account1 string, account2 string) (*gtsmodel.Block, db.Error) { - return r.blockCache.Load("AccountID.TargetAccountID", func() (*gtsmodel.Block, error) { + return r.state.Caches.GTS.Block().Load("AccountID.TargetAccountID", func() (*gtsmodel.Block, error) { var block gtsmodel.Block q := r.conn.NewSelect().Model(&block). @@ -124,7 +105,7 @@ func (r *relationshipDB) getBlock(ctx context.Context, account1 string, account2 } func (r *relationshipDB) PutBlock(ctx context.Context, block *gtsmodel.Block) db.Error { - return r.blockCache.Store(block, func() error { + return r.state.Caches.GTS.Block().Store(block, func() error { _, err := r.conn.NewInsert().Model(block).Exec(ctx) return r.conn.ProcessError(err) }) @@ -140,7 +121,7 @@ func (r *relationshipDB) DeleteBlockByID(ctx context.Context, id string) db.Erro } // Drop any old value from cache by this ID - r.blockCache.Invalidate("ID", id) + r.state.Caches.GTS.Block().Invalidate("ID", id) return nil } @@ -154,7 +135,7 @@ func (r *relationshipDB) DeleteBlockByURI(ctx context.Context, uri string) db.Er } // Drop any old value from cache by this URI - r.blockCache.Invalidate("URI", uri) + r.state.Caches.GTS.Block().Invalidate("URI", uri) return nil } diff --git a/internal/db/bundb/status.go b/internal/db/bundb/status.go index 2b33b84e9..20ca843be 100644 --- a/internal/db/bundb/status.go +++ b/internal/db/bundb/status.go @@ -26,36 +26,16 @@ import ( "fmt" "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" ) type statusDB struct { - conn *DBConn - cache *result.Cache[*gtsmodel.Status] - accounts *accountDB - emojis *emojiDB - mentions *mentionDB -} - -func (s *statusDB) init() { - // Initialize status result cache - s.cache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - {Name: "URI"}, - {Name: "URL"}, - }, func(s1 *gtsmodel.Status) *gtsmodel.Status { - s2 := new(gtsmodel.Status) - *s2 = *s1 - return s2 - }, 1000) - - // Set cache TTL and start sweep routine - s.cache.SetTTL(time.Minute*5, false) - s.cache.Start(time.Second * 10) + conn *DBConn + state *state.State } func (s *statusDB) newStatusQ(status interface{}) *bun.SelectQuery { @@ -111,7 +91,7 @@ func (s *statusDB) GetStatusByURL(ctx context.Context, url string) (*gtsmodel.St func (s *statusDB) getStatus(ctx context.Context, lookup string, dbQuery func(*gtsmodel.Status) error, keyParts ...any) (*gtsmodel.Status, db.Error) { // Fetch status from database cache with loader callback - status, err := s.cache.Load(lookup, func() (*gtsmodel.Status, error) { + status, err := s.state.Caches.GTS.Status().Load(lookup, func() (*gtsmodel.Status, error) { var status gtsmodel.Status // Not cached! Perform database query @@ -149,14 +129,14 @@ func (s *statusDB) getStatus(ctx context.Context, lookup string, dbQuery func(*g } // Set the status author account - status.Account, err = s.accounts.GetAccountByID(ctx, status.AccountID) + status.Account, err = s.state.DB.GetAccountByID(ctx, status.AccountID) if err != nil { return nil, fmt.Errorf("error getting status account: %w", err) } if id := status.BoostOfAccountID; id != "" { // Set boost of status' author account - status.BoostOfAccount, err = s.accounts.GetAccountByID(ctx, id) + status.BoostOfAccount, err = s.state.DB.GetAccountByID(ctx, id) if err != nil { return nil, fmt.Errorf("error getting boosted status account: %w", err) } @@ -164,7 +144,7 @@ func (s *statusDB) getStatus(ctx context.Context, lookup string, dbQuery func(*g if id := status.InReplyToAccountID; id != "" { // Set in-reply-to status' author account - status.InReplyToAccount, err = s.accounts.GetAccountByID(ctx, id) + status.InReplyToAccount, err = s.state.DB.GetAccountByID(ctx, id) if err != nil { return nil, fmt.Errorf("error getting in reply to status account: %w", err) } @@ -172,7 +152,7 @@ func (s *statusDB) getStatus(ctx context.Context, lookup string, dbQuery func(*g if len(status.EmojiIDs) > 0 { // Fetch status emojis - status.Emojis, err = s.emojis.emojisFromIDs(ctx, status.EmojiIDs) + status.Emojis, err = s.state.DB.GetEmojisByIDs(ctx, status.EmojiIDs) if err != nil { return nil, fmt.Errorf("error getting status emojis: %w", err) } @@ -180,7 +160,7 @@ func (s *statusDB) getStatus(ctx context.Context, lookup string, dbQuery func(*g if len(status.MentionIDs) > 0 { // Fetch status mentions - status.Mentions, err = s.mentions.GetMentions(ctx, status.MentionIDs) + status.Mentions, err = s.state.DB.GetMentions(ctx, status.MentionIDs) if err != nil { return nil, fmt.Errorf("error getting status mentions: %w", err) } @@ -190,7 +170,7 @@ func (s *statusDB) getStatus(ctx context.Context, lookup string, dbQuery func(*g } func (s *statusDB) PutStatus(ctx context.Context, status *gtsmodel.Status) db.Error { - return s.cache.Store(status, func() error { + return s.state.Caches.GTS.Status().Store(status, func() error { // It is safe to run this database transaction within cache.Store // as the cache does not attempt a mutex lock until AFTER hook. // @@ -308,7 +288,7 @@ func (s *statusDB) UpdateStatus(ctx context.Context, status *gtsmodel.Status) db } // Drop any old value from cache by this ID - s.cache.Invalidate("ID", status.ID) + s.state.Caches.GTS.Status().Invalidate("ID", status.ID) return nil } @@ -347,7 +327,7 @@ func (s *statusDB) DeleteStatusByID(ctx context.Context, id string) db.Error { } // Drop any old value from cache by this ID - s.cache.Invalidate("ID", id) + s.state.Caches.GTS.Status().Invalidate("ID", id) return nil } diff --git a/internal/db/bundb/timeline.go b/internal/db/bundb/timeline.go index d15c07e9c..a6e3554f8 100644 --- a/internal/db/bundb/timeline.go +++ b/internal/db/bundb/timeline.go @@ -26,13 +26,14 @@ import ( "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/id" "github.com/superseriousbusiness/gotosocial/internal/log" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" "golang.org/x/exp/slices" ) type timelineDB struct { - conn *DBConn - status *statusDB + conn *DBConn + state *state.State } func (t *timelineDB) GetHomeTimeline(ctx context.Context, accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, db.Error) { @@ -111,7 +112,7 @@ func (t *timelineDB) GetHomeTimeline(ctx context.Context, accountID string, maxI for _, id := range statusIDs { // Fetch status from db for ID - status, err := t.status.GetStatusByID(ctx, id) + status, err := t.state.DB.GetStatusByID(ctx, id) if err != nil { log.Errorf("GetHomeTimeline: error fetching status %q: %v", id, err) continue @@ -179,7 +180,7 @@ func (t *timelineDB) GetPublicTimeline(ctx context.Context, maxID string, sinceI for _, id := range statusIDs { // Fetch status from db for ID - status, err := t.status.GetStatusByID(ctx, id) + status, err := t.state.DB.GetStatusByID(ctx, id) if err != nil { log.Errorf("GetPublicTimeline: error fetching status %q: %v", id, err) continue @@ -239,7 +240,7 @@ func (t *timelineDB) GetFavedTimeline(ctx context.Context, accountID string, max for _, fave := range faves { // Fetch status from db for corresponding favourite - status, err := t.status.GetStatusByID(ctx, fave.StatusID) + status, err := t.state.DB.GetStatusByID(ctx, fave.StatusID) if err != nil { log.Errorf("GetFavedTimeline: error fetching status for fave %q: %v", fave.ID, err) continue diff --git a/internal/db/bundb/tombstone.go b/internal/db/bundb/tombstone.go index 309a39fd3..64c0a4508 100644 --- a/internal/db/bundb/tombstone.go +++ b/internal/db/bundb/tombstone.go @@ -20,38 +20,20 @@ package bundb import ( "context" - "time" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" - - "codeberg.org/gruf/go-cache/v3/result" ) type tombstoneDB struct { conn *DBConn - cache *result.Cache[*gtsmodel.Tombstone] -} - -func (t *tombstoneDB) init() { - // Initialize tombstone result cache - t.cache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - {Name: "URI"}, - }, func(t1 *gtsmodel.Tombstone) *gtsmodel.Tombstone { - t2 := new(gtsmodel.Tombstone) - *t2 = *t1 - return t2 - }, 100) - - // Set cache TTL and start sweep routine - t.cache.SetTTL(time.Minute*5, false) - t.cache.Start(time.Second * 10) + state *state.State } func (t *tombstoneDB) GetTombstoneByURI(ctx context.Context, uri string) (*gtsmodel.Tombstone, db.Error) { - return t.cache.Load("URI", func() (*gtsmodel.Tombstone, error) { + return t.state.Caches.GTS.Tombstone().Load("URI", func() (*gtsmodel.Tombstone, error) { var tomb gtsmodel.Tombstone q := t.conn. @@ -76,7 +58,7 @@ func (t *tombstoneDB) TombstoneExistsWithURI(ctx context.Context, uri string) (b } func (t *tombstoneDB) PutTombstone(ctx context.Context, tombstone *gtsmodel.Tombstone) db.Error { - return t.cache.Store(tombstone, func() error { + return t.state.Caches.GTS.Tombstone().Store(tombstone, func() error { _, err := t.conn. NewInsert(). Model(tombstone). @@ -95,7 +77,7 @@ func (t *tombstoneDB) DeleteTombstone(ctx context.Context, id string) db.Error { } // Invalidate from cache by ID - t.cache.Invalidate("ID", id) + t.state.Caches.GTS.Tombstone().Invalidate("ID", id) return nil } diff --git a/internal/db/bundb/user.go b/internal/db/bundb/user.go index e7983556f..e90c06343 100644 --- a/internal/db/bundb/user.go +++ b/internal/db/bundb/user.go @@ -22,38 +22,19 @@ import ( "context" "time" - "codeberg.org/gruf/go-cache/v3/result" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/state" "github.com/uptrace/bun" ) type userDB struct { conn *DBConn - cache *result.Cache[*gtsmodel.User] -} - -func (u *userDB) init() { - // Initialize user result cache - u.cache = result.NewSized([]result.Lookup{ - {Name: "ID"}, - {Name: "AccountID"}, - {Name: "Email"}, - {Name: "ConfirmationToken"}, - {Name: "ExternalID"}, - }, func(u1 *gtsmodel.User) *gtsmodel.User { - u2 := new(gtsmodel.User) - *u2 = *u1 - return u2 - }, 1000) - - // Set cache TTL and start sweep routine - u.cache.SetTTL(time.Minute*5, false) - u.cache.Start(time.Second * 10) + state *state.State } func (u *userDB) GetUserByID(ctx context.Context, id string) (*gtsmodel.User, db.Error) { - return u.cache.Load("ID", func() (*gtsmodel.User, error) { + return u.state.Caches.GTS.User().Load("ID", func() (*gtsmodel.User, error) { var user gtsmodel.User q := u.conn. @@ -71,7 +52,7 @@ func (u *userDB) GetUserByID(ctx context.Context, id string) (*gtsmodel.User, db } func (u *userDB) GetUserByAccountID(ctx context.Context, accountID string) (*gtsmodel.User, db.Error) { - return u.cache.Load("AccountID", func() (*gtsmodel.User, error) { + return u.state.Caches.GTS.User().Load("AccountID", func() (*gtsmodel.User, error) { var user gtsmodel.User q := u.conn. @@ -89,7 +70,7 @@ func (u *userDB) GetUserByAccountID(ctx context.Context, accountID string) (*gts } func (u *userDB) GetUserByEmailAddress(ctx context.Context, emailAddress string) (*gtsmodel.User, db.Error) { - return u.cache.Load("Email", func() (*gtsmodel.User, error) { + return u.state.Caches.GTS.User().Load("Email", func() (*gtsmodel.User, error) { var user gtsmodel.User q := u.conn. @@ -105,9 +86,9 @@ func (u *userDB) GetUserByEmailAddress(ctx context.Context, emailAddress string) return &user, nil }, emailAddress) } -func (u *userDB) GetUserByExternalID(ctx context.Context, id string) (*gtsmodel.User, db.Error) { - return u.cache.Load("ExternalID", func() (*gtsmodel.User, error) { +func (u *userDB) GetUserByExternalID(ctx context.Context, id string) (*gtsmodel.User, db.Error) { + return u.state.Caches.GTS.User().Load("ExternalID", func() (*gtsmodel.User, error) { var user gtsmodel.User q := u.conn. @@ -125,7 +106,7 @@ func (u *userDB) GetUserByExternalID(ctx context.Context, id string) (*gtsmodel. } func (u *userDB) GetUserByConfirmationToken(ctx context.Context, confirmationToken string) (*gtsmodel.User, db.Error) { - return u.cache.Load("ConfirmationToken", func() (*gtsmodel.User, error) { + return u.state.Caches.GTS.User().Load("ConfirmationToken", func() (*gtsmodel.User, error) { var user gtsmodel.User q := u.conn. @@ -143,7 +124,7 @@ func (u *userDB) GetUserByConfirmationToken(ctx context.Context, confirmationTok } func (u *userDB) PutUser(ctx context.Context, user *gtsmodel.User) db.Error { - return u.cache.Store(user, func() error { + return u.state.Caches.GTS.User().Store(user, func() error { _, err := u.conn. NewInsert(). Model(user). @@ -172,8 +153,8 @@ func (u *userDB) UpdateUser(ctx context.Context, user *gtsmodel.User, columns .. return u.conn.ProcessError(err) } - // Invalidate in cache - u.cache.Invalidate("ID", user.ID) + // Invalidate user from cache + u.state.Caches.GTS.User().Invalidate("ID", user.ID) return nil } @@ -187,6 +168,6 @@ func (u *userDB) DeleteUserByID(ctx context.Context, userID string) db.Error { } // Invalidate user from cache - u.cache.Invalidate("ID", userID) + u.state.Caches.GTS.User().Invalidate("ID", userID) return nil } |