diff options
Diffstat (limited to 'internal/db')
-rw-r--r-- | internal/db/account.go | 3 | ||||
-rw-r--r-- | internal/db/bundb/account.go | 49 | ||||
-rw-r--r-- | internal/db/bundb/emoji.go | 86 | ||||
-rw-r--r-- | internal/db/bundb/media.go | 78 | ||||
-rw-r--r-- | internal/db/bundb/media_test.go | 2 | ||||
-rw-r--r-- | internal/db/bundb/migrations/20230724100000_emoji_cleanup.go | 55 | ||||
-rw-r--r-- | internal/db/bundb/report.go | 2 | ||||
-rw-r--r-- | internal/db/bundb/search.go | 39 | ||||
-rw-r--r-- | internal/db/bundb/status.go | 34 | ||||
-rw-r--r-- | internal/db/bundb/status_test.go | 4 | ||||
-rw-r--r-- | internal/db/bundb/util.go | 36 | ||||
-rw-r--r-- | internal/db/emoji.go | 11 | ||||
-rw-r--r-- | internal/db/media.go | 12 | ||||
-rw-r--r-- | internal/db/status.go | 9 |
14 files changed, 327 insertions, 93 deletions
diff --git a/internal/db/account.go b/internal/db/account.go index 4a08918b0..2e113c35e 100644 --- a/internal/db/account.go +++ b/internal/db/account.go @@ -73,6 +73,9 @@ type Account interface { // GetAccountFaves fetches faves/likes created by the target accountID. GetAccountFaves(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, Error) + // GetAccountsUsingEmoji fetches all account models using emoji with given ID stored in their 'emojis' column. + GetAccountsUsingEmoji(ctx context.Context, emojiID string) ([]*gtsmodel.Account, error) + // GetAccountStatusesCount is a shortcut for the common action of counting statuses produced by accountID. CountAccountStatuses(ctx context.Context, accountID string) (int, Error) diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go index 17339732e..179db6bb3 100644 --- a/internal/db/bundb/account.go +++ b/internal/db/bundb/account.go @@ -56,6 +56,27 @@ func (a *accountDB) GetAccountByID(ctx context.Context, id string) (*gtsmodel.Ac ) } +func (a *accountDB) GetAccountsByIDs(ctx context.Context, ids []string) ([]*gtsmodel.Account, error) { + accounts := make([]*gtsmodel.Account, 0, len(ids)) + + for _, id := range ids { + // Attempt to fetch account from DB. + account, err := a.GetAccountByID( + gtscontext.SetBarebones(ctx), + id, + ) + if err != nil { + log.Errorf(ctx, "error getting account %q: %v", id, err) + continue + } + + // Append account to return slice. + accounts = append(accounts, account) + } + + return accounts, nil +} + func (a *accountDB) GetAccountByURI(ctx context.Context, uri string) (*gtsmodel.Account, db.Error) { return a.getAccount( ctx, @@ -444,6 +465,34 @@ func (a *accountDB) GetAccountCustomCSSByUsername(ctx context.Context, username return account.CustomCSS, nil } +func (a *accountDB) GetAccountsUsingEmoji(ctx context.Context, emojiID string) ([]*gtsmodel.Account, error) { + var accountIDs []string + + // Create SELECT account query. + q := a.conn.NewSelect(). + Table("accounts"). + Column("id") + + // Append a WHERE LIKE clause to the query + // that checks the `emoji` column for any + // text containing this specific emoji ID. + // + // The reason we do this instead of doing a + // `WHERE ? IN (emojis)` is that the latter + // ends up being much MUCH slower, and the + // database stores this ID-array-column as + // text anyways, allowing a simple LIKE query. + q = whereLike(q, "emojis", emojiID) + + // Execute the query, scanning destination into accountIDs. + if _, err := q.Exec(ctx, &accountIDs); err != nil { + return nil, a.conn.ProcessError(err) + } + + // Convert account IDs into account objects. + return a.GetAccountsByIDs(ctx, accountIDs) +} + func (a *accountDB) GetAccountFaves(ctx context.Context, accountID string) ([]*gtsmodel.StatusFave, db.Error) { faves := new([]*gtsmodel.StatusFave) diff --git a/internal/db/bundb/emoji.go b/internal/db/bundb/emoji.go index 60c140264..321b5c0e7 100644 --- a/internal/db/bundb/emoji.go +++ b/internal/db/bundb/emoji.go @@ -126,12 +126,20 @@ func (e *emojiDB) DeleteEmojiByID(ctx context.Context, id string) db.Error { return err } - // Select all accounts using this emoji. - if _, err := tx.NewSelect(). + // Prepare SELECT accounts query. + aq := tx.NewSelect(). Table("accounts"). - Column("id"). - Where("? IN (emojis)", id). - Exec(ctx, &accountIDs); err != nil { + Column("id") + + // Append a WHERE LIKE clause to the query + // that checks the `emoji` column for any + // text containing this specific emoji ID. + // + // (see GetStatusesUsingEmoji() for details.) + aq = whereLike(aq, "emojis", id) + + // Select all accounts using this emoji into accountIDss. + if _, err := aq.Exec(ctx, &accountIDs); err != nil { return err } @@ -162,12 +170,20 @@ func (e *emojiDB) DeleteEmojiByID(ctx context.Context, id string) db.Error { } } - // Select all statuses using this emoji. - if _, err := tx.NewSelect(). + // Prepare SELECT statuses query. + sq := tx.NewSelect(). Table("statuses"). - Column("id"). - Where("? IN (emojis)", id). - Exec(ctx, &statusIDs); err != nil { + Column("id") + + // Append a WHERE LIKE clause to the query + // that checks the `emoji` column for any + // text containing this specific emoji ID. + // + // (see GetStatusesUsingEmoji() for details.) + sq = whereLike(sq, "emojis", id) + + // Select all statuses using this emoji into statusIDs. + if _, err := sq.Exec(ctx, &statusIDs); err != nil { return err } @@ -328,7 +344,7 @@ func (e *emojiDB) GetEmojisBy(ctx context.Context, domain string, includeDisable } func (e *emojiDB) GetEmojis(ctx context.Context, maxID string, limit int) ([]*gtsmodel.Emoji, error) { - emojiIDs := []string{} + var emojiIDs []string q := e.conn.NewSelect(). Table("emojis"). @@ -336,9 +352,55 @@ func (e *emojiDB) GetEmojis(ctx context.Context, maxID string, limit int) ([]*gt Order("id DESC") if maxID != "" { - q = q.Where("? < ?", bun.Ident("id"), maxID) + q = q.Where("id < ?", maxID) + } + + if limit != 0 { + q = q.Limit(limit) } + if err := q.Scan(ctx, &emojiIDs); err != nil { + return nil, e.conn.ProcessError(err) + } + + return e.GetEmojisByIDs(ctx, emojiIDs) +} + +func (e *emojiDB) GetRemoteEmojis(ctx context.Context, maxID string, limit int) ([]*gtsmodel.Emoji, error) { + var emojiIDs []string + + q := e.conn.NewSelect(). + Table("emojis"). + Column("id"). + Where("domain IS NOT NULL"). + Order("id DESC") + + if maxID != "" { + q = q.Where("id < ?", maxID) + } + + if limit != 0 { + q = q.Limit(limit) + } + + if err := q.Scan(ctx, &emojiIDs); err != nil { + return nil, e.conn.ProcessError(err) + } + + return e.GetEmojisByIDs(ctx, emojiIDs) +} + +func (e *emojiDB) GetCachedEmojisOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.Emoji, error) { + var emojiIDs []string + + q := e.conn.NewSelect(). + Table("emojis"). + Column("id"). + Where("cached = true"). + Where("domain IS NOT NULL"). + Where("created_at < ?", olderThan). + Order("created_at DESC") + if limit != 0 { q = q.Limit(limit) } diff --git a/internal/db/bundb/media.go b/internal/db/bundb/media.go index 80a4f8bbe..c190df44a 100644 --- a/internal/db/bundb/media.go +++ b/internal/db/bundb/media.go @@ -232,29 +232,6 @@ func (m *mediaDB) DeleteAttachment(ctx context.Context, id string) error { return m.conn.ProcessError(err) } -func (m *mediaDB) GetRemoteOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.MediaAttachment, db.Error) { - attachmentIDs := []string{} - - q := m.conn. - NewSelect(). - TableExpr("? AS ?", bun.Ident("media_attachments"), bun.Ident("media_attachment")). - Column("media_attachment.id"). - Where("? = ?", bun.Ident("media_attachment.cached"), true). - Where("? < ?", bun.Ident("media_attachment.created_at"), olderThan). - Where("? IS NOT NULL", bun.Ident("media_attachment.remote_url")). - Order("media_attachment.created_at DESC") - - if limit != 0 { - q = q.Limit(limit) - } - - if err := q.Scan(ctx, &attachmentIDs); err != nil { - return nil, m.conn.ProcessError(err) - } - - return m.GetAttachmentsByIDs(ctx, attachmentIDs) -} - func (m *mediaDB) CountRemoteOlderThan(ctx context.Context, olderThan time.Time) (int, db.Error) { q := m.conn. NewSelect(). @@ -273,15 +250,39 @@ func (m *mediaDB) CountRemoteOlderThan(ctx context.Context, olderThan time.Time) } func (m *mediaDB) GetAttachments(ctx context.Context, maxID string, limit int) ([]*gtsmodel.MediaAttachment, error) { - attachmentIDs := []string{} + attachmentIDs := make([]string, 0, limit) + + q := m.conn.NewSelect(). + Table("media_attachments"). + Column("id"). + Order("id DESC") + + if maxID != "" { + q = q.Where("id < ?", maxID) + } + + if limit != 0 { + q = q.Limit(limit) + } + + if err := q.Scan(ctx, &attachmentIDs); err != nil { + return nil, m.conn.ProcessError(err) + } + + return m.GetAttachmentsByIDs(ctx, attachmentIDs) +} + +func (m *mediaDB) GetRemoteAttachments(ctx context.Context, maxID string, limit int) ([]*gtsmodel.MediaAttachment, error) { + attachmentIDs := make([]string, 0, limit) q := m.conn.NewSelect(). Table("media_attachments"). Column("id"). + Where("remote_url IS NOT NULL"). Order("id DESC") if maxID != "" { - q = q.Where("? < ?", bun.Ident("id"), maxID) + q = q.Where("id < ?", maxID) } if limit != 0 { @@ -295,8 +296,31 @@ func (m *mediaDB) GetAttachments(ctx context.Context, maxID string, limit int) ( return m.GetAttachmentsByIDs(ctx, attachmentIDs) } +func (m *mediaDB) GetCachedAttachmentsOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.MediaAttachment, db.Error) { + attachmentIDs := make([]string, 0, limit) + + q := m.conn. + NewSelect(). + Table("media_attachments"). + Column("id"). + Where("cached = true"). + Where("remote_url IS NOT NULL"). + Where("created_at < ?", olderThan). + Order("created_at DESC") + + if limit != 0 { + q = q.Limit(limit) + } + + if err := q.Scan(ctx, &attachmentIDs); err != nil { + return nil, m.conn.ProcessError(err) + } + + return m.GetAttachmentsByIDs(ctx, attachmentIDs) +} + func (m *mediaDB) GetAvatarsAndHeaders(ctx context.Context, maxID string, limit int) ([]*gtsmodel.MediaAttachment, db.Error) { - attachmentIDs := []string{} + attachmentIDs := make([]string, 0, limit) q := m.conn.NewSelect(). TableExpr("? AS ?", bun.Ident("media_attachments"), bun.Ident("media_attachment")). @@ -324,7 +348,7 @@ func (m *mediaDB) GetAvatarsAndHeaders(ctx context.Context, maxID string, limit } func (m *mediaDB) GetLocalUnattachedOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.MediaAttachment, db.Error) { - attachmentIDs := []string{} + attachmentIDs := make([]string, 0, limit) q := m.conn. NewSelect(). diff --git a/internal/db/bundb/media_test.go b/internal/db/bundb/media_test.go index 6b419022a..59b927119 100644 --- a/internal/db/bundb/media_test.go +++ b/internal/db/bundb/media_test.go @@ -38,7 +38,7 @@ func (suite *MediaTestSuite) TestGetAttachmentByID() { } func (suite *MediaTestSuite) TestGetOlder() { - attachments, err := suite.db.GetRemoteOlderThan(context.Background(), time.Now(), 20) + attachments, err := suite.db.GetCachedAttachmentsOlderThan(context.Background(), time.Now(), 20) suite.NoError(err) suite.Len(attachments, 2) } diff --git a/internal/db/bundb/migrations/20230724100000_emoji_cleanup.go b/internal/db/bundb/migrations/20230724100000_emoji_cleanup.go new file mode 100644 index 000000000..0ee501395 --- /dev/null +++ b/internal/db/bundb/migrations/20230724100000_emoji_cleanup.go @@ -0,0 +1,55 @@ +// GoToSocial +// Copyright (C) GoToSocial Authors admin@gotosocial.org +// SPDX-License-Identifier: AGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. + +package migrations + +import ( + "context" + "strings" + + "github.com/uptrace/bun" +) + +func init() { + up := func(ctx context.Context, db *bun.DB) error { + _, err := db.ExecContext(ctx, "ALTER TABLE emojis ADD COLUMN cached BOOLEAN DEFAULT false") + + if err != nil && !(strings.Contains(err.Error(), "already exists") || strings.Contains(err.Error(), "duplicate column name") || strings.Contains(err.Error(), "SQLSTATE 42701")) { + return err + } + + if _, err := db.NewUpdate(). + Table("emojis"). + Where("disabled = false"). + Set("cached = true"). + Exec(ctx); err != nil { + return err + } + + return nil + } + + down := func(ctx context.Context, db *bun.DB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + return nil + }) + } + + if err := Migrations.Register(up, down); err != nil { + panic(err) + } +} diff --git a/internal/db/bundb/report.go b/internal/db/bundb/report.go index e017a8906..ee8aa1cb3 100644 --- a/internal/db/bundb/report.go +++ b/internal/db/bundb/report.go @@ -149,7 +149,7 @@ func (r *reportDB) getReport(ctx context.Context, lookup string, dbQuery func(*g if len(report.StatusIDs) > 0 { // Fetch reported statuses - report.Statuses, err = r.state.DB.GetStatuses(ctx, report.StatusIDs) + report.Statuses, err = r.state.DB.GetStatusesByIDs(ctx, report.StatusIDs) if err != nil { return nil, fmt.Errorf("error getting status mentions: %w", err) } diff --git a/internal/db/bundb/search.go b/internal/db/bundb/search.go index c05ebb8b1..1d7eefd48 100644 --- a/internal/db/bundb/search.go +++ b/internal/db/bundb/search.go @@ -19,7 +19,6 @@ package bundb import ( "context" - "strings" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/gotosocial/internal/id" @@ -61,40 +60,6 @@ type searchDB struct { state *state.State } -// replacer is a thread-safe string replacer which escapes -// common SQLite + Postgres `LIKE` wildcard chars using the -// escape character `\`. Initialized as a var in this package -// so it can be reused. -var replacer = strings.NewReplacer( - `\`, `\\`, // Escape char. - `%`, `\%`, // Zero or more char. - `_`, `\_`, // Exactly one char. -) - -// whereSubqueryLike appends a WHERE clause to the -// given SelectQuery q, which searches for matches -// of searchQuery in the given subQuery using LIKE. -func whereSubqueryLike( - q *bun.SelectQuery, - subQuery *bun.SelectQuery, - searchQuery string, -) *bun.SelectQuery { - // Escape existing wildcard + escape - // chars in the search query string. - searchQuery = replacer.Replace(searchQuery) - - // Add our own wildcards back in; search - // zero or more chars around the query. - searchQuery = `%` + searchQuery + `%` - - // Append resulting WHERE - // clause to the main query. - return q.Where( - "(?) LIKE ? ESCAPE ?", - subQuery, searchQuery, `\`, - ) -} - // Query example (SQLite): // // SELECT "account"."id" FROM "accounts" AS "account" @@ -167,7 +132,7 @@ func (s *searchDB) SearchForAccounts( // Search using LIKE for matches of query // string within accountText subquery. - q = whereSubqueryLike(q, accountTextSubq, query) + q = whereLike(q, accountTextSubq, query) if limit > 0 { // Limit amount of accounts returned. @@ -345,7 +310,7 @@ func (s *searchDB) SearchForStatuses( // Search using LIKE for matches of query // string within statusText subquery. - q = whereSubqueryLike(q, statusTextSubq, query) + q = whereLike(q, statusTextSubq, query) if limit > 0 { // Limit amount of statuses returned. diff --git a/internal/db/bundb/status.go b/internal/db/bundb/status.go index 0dffbabcc..ccfc9fd4b 100644 --- a/internal/db/bundb/status.go +++ b/internal/db/bundb/status.go @@ -58,18 +58,18 @@ func (s *statusDB) GetStatusByID(ctx context.Context, id string) (*gtsmodel.Stat ) } -func (s *statusDB) GetStatuses(ctx context.Context, ids []string) ([]*gtsmodel.Status, db.Error) { +func (s *statusDB) GetStatusesByIDs(ctx context.Context, ids []string) ([]*gtsmodel.Status, error) { statuses := make([]*gtsmodel.Status, 0, len(ids)) for _, id := range ids { - // Attempt fetch from DB + // Attempt to fetch status from DB. status, err := s.GetStatusByID(ctx, id) if err != nil { log.Errorf(ctx, "error getting status %q: %v", id, err) continue } - // Append status + // Append status to return slice. statuses = append(statuses, status) } @@ -429,6 +429,34 @@ func (s *statusDB) DeleteStatusByID(ctx context.Context, id string) db.Error { }) } +func (s *statusDB) GetStatusesUsingEmoji(ctx context.Context, emojiID string) ([]*gtsmodel.Status, error) { + var statusIDs []string + + // Create SELECT status query. + q := s.conn.NewSelect(). + Table("statuses"). + Column("id") + + // Append a WHERE LIKE clause to the query + // that checks the `emoji` column for any + // text containing this specific emoji ID. + // + // The reason we do this instead of doing a + // `WHERE ? IN (emojis)` is that the latter + // ends up being much MUCH slower, and the + // database stores this ID-array-column as + // text anyways, allowing a simple LIKE query. + q = whereLike(q, "emojis", emojiID) + + // Execute the query, scanning destination into statusIDs. + if _, err := q.Exec(ctx, &statusIDs); err != nil { + return nil, s.conn.ProcessError(err) + } + + // Convert status IDs into status objects. + return s.GetStatusesByIDs(ctx, statusIDs) +} + func (s *statusDB) GetStatusParents(ctx context.Context, status *gtsmodel.Status, onlyDirect bool) ([]*gtsmodel.Status, db.Error) { if onlyDirect { // Only want the direct parent, no further than first level diff --git a/internal/db/bundb/status_test.go b/internal/db/bundb/status_test.go index cab7501f9..a69608796 100644 --- a/internal/db/bundb/status_test.go +++ b/internal/db/bundb/status_test.go @@ -50,13 +50,13 @@ func (suite *StatusTestSuite) TestGetStatusByID() { suite.True(*status.Likeable) } -func (suite *StatusTestSuite) TestGetStatusesByID() { +func (suite *StatusTestSuite) TestGetStatusesByIDs() { ids := []string{ suite.testStatuses["local_account_1_status_1"].ID, suite.testStatuses["local_account_2_status_3"].ID, } - statuses, err := suite.db.GetStatuses(context.Background(), ids) + statuses, err := suite.db.GetStatusesByIDs(context.Background(), ids) if err != nil { suite.FailNow(err.Error()) } diff --git a/internal/db/bundb/util.go b/internal/db/bundb/util.go index 06bb289d3..bdd45d1e7 100644 --- a/internal/db/bundb/util.go +++ b/internal/db/bundb/util.go @@ -18,10 +18,46 @@ package bundb import ( + "strings" + "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/uptrace/bun" ) +// likeEscaper is a thread-safe string replacer which escapes +// common SQLite + Postgres `LIKE` wildcard chars using the +// escape character `\`. Initialized as a var in this package +// so it can be reused. +var likeEscaper = strings.NewReplacer( + `\`, `\\`, // Escape char. + `%`, `\%`, // Zero or more char. + `_`, `\_`, // Exactly one char. +) + +// whereSubqueryLike appends a WHERE clause to the +// given SelectQuery, which searches for matches +// of `search` in the given subQuery using LIKE. +func whereLike( + query *bun.SelectQuery, + subject interface{}, + search string, +) *bun.SelectQuery { + // Escape existing wildcard + escape + // chars in the search query string. + search = likeEscaper.Replace(search) + + // Add our own wildcards back in; search + // zero or more chars around the query. + search = `%` + search + `%` + + // Append resulting WHERE + // clause to the main query. + return query.Where( + "(?) LIKE ? ESCAPE ?", + subject, search, `\`, + ) +} + // updateWhere parses []db.Where and adds it to the given update query. func updateWhere(q *bun.UpdateQuery, where []db.Where) { for _, w := range where { diff --git a/internal/db/emoji.go b/internal/db/emoji.go index 5dcad9ece..67d7f7232 100644 --- a/internal/db/emoji.go +++ b/internal/db/emoji.go @@ -19,6 +19,7 @@ package db import ( "context" + "time" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" ) @@ -40,8 +41,16 @@ type Emoji interface { GetEmojisByIDs(ctx context.Context, ids []string) ([]*gtsmodel.Emoji, Error) // GetUseableEmojis gets all emojis which are useable by accounts on this instance. GetUseableEmojis(ctx context.Context) ([]*gtsmodel.Emoji, Error) - // GetEmojis ... + + // GetEmojis fetches all emojis with IDs less than 'maxID', up to a maximum of 'limit' emojis. GetEmojis(ctx context.Context, maxID string, limit int) ([]*gtsmodel.Emoji, error) + + // GetRemoteEmojis fetches all remote emojis with IDs less than 'maxID', up to a maximum of 'limit' emojis. + GetRemoteEmojis(ctx context.Context, maxID string, limit int) ([]*gtsmodel.Emoji, error) + + // GetCachedEmojisOlderThan fetches all cached remote emojis with 'updated_at' greater than 'olderThan', up to a maximum of 'limit' emojis. + GetCachedEmojisOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.Emoji, error) + // GetEmojisBy gets emojis based on given parameters. Useful for admin actions. GetEmojisBy(ctx context.Context, domain string, includeDisabled bool, includeEnabled bool, shortcode string, maxShortcodeDomain string, minShortcodeDomain string, limit int) ([]*gtsmodel.Emoji, error) // GetEmojiByID gets a specific emoji by its database ID. diff --git a/internal/db/media.go b/internal/db/media.go index 01bca1748..5fb18a8fe 100644 --- a/internal/db/media.go +++ b/internal/db/media.go @@ -44,12 +44,12 @@ type Media interface { // GetAttachments ... GetAttachments(ctx context.Context, maxID string, limit int) ([]*gtsmodel.MediaAttachment, error) - // GetRemoteOlderThan gets limit n remote media attachments (including avatars and headers) older than the given - // olderThan time. These will be returned in order of attachment.created_at descending (newest to oldest in other words). - // - // The selected media attachments will be those with both a URL and a RemoteURL filled in. - // In other words, media attachments that originated remotely, and that we currently have cached locally. - GetRemoteOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.MediaAttachment, Error) + // GetRemoteAttachments ... + GetRemoteAttachments(ctx context.Context, maxID string, limit int) ([]*gtsmodel.MediaAttachment, error) + + // GetCachedAttachmentsOlderThan gets limit n remote attachments (including avatars and headers) older than + // the given time. These will be returned in order of attachment.created_at descending (i.e. newest to oldest). + GetCachedAttachmentsOlderThan(ctx context.Context, olderThan time.Time, limit int) ([]*gtsmodel.MediaAttachment, Error) // CountRemoteOlderThan is like GetRemoteOlderThan, except instead of getting limit n attachments, // it just counts how many remote attachments in the database (including avatars and headers) meet diff --git a/internal/db/status.go b/internal/db/status.go index fdce19094..c0e330260 100644 --- a/internal/db/status.go +++ b/internal/db/status.go @@ -28,9 +28,6 @@ type Status interface { // GetStatusByID returns one status from the database, with no rel fields populated, only their linking ID / URIs GetStatusByID(ctx context.Context, id string) (*gtsmodel.Status, Error) - // GetStatuses gets a slice of statuses corresponding to the given status IDs. - GetStatuses(ctx context.Context, ids []string) ([]*gtsmodel.Status, Error) - // GetStatusByURI returns one status from the database, with no rel fields populated, only their linking ID / URIs GetStatusByURI(ctx context.Context, uri string) (*gtsmodel.Status, Error) @@ -58,6 +55,12 @@ type Status interface { // CountStatusFaves returns the amount of faves/likes recorded for a status, or an error if something goes wrong CountStatusFaves(ctx context.Context, status *gtsmodel.Status) (int, Error) + // GetStatuses gets a slice of statuses corresponding to the given status IDs. + GetStatusesByIDs(ctx context.Context, ids []string) ([]*gtsmodel.Status, error) + + // GetStatusesUsingEmoji fetches all status models using emoji with given ID stored in their 'emojis' column. + GetStatusesUsingEmoji(ctx context.Context, emojiID string) ([]*gtsmodel.Status, error) + // GetStatusParents gets the parent statuses of a given status. // // If onlyDirect is true, only the immediate parent will be returned. |