diff options
Diffstat (limited to 'internal/db')
-rw-r--r-- | internal/db/bundb/errors.go | 4 | ||||
-rw-r--r-- | internal/db/bundb/status.go | 52 | ||||
-rw-r--r-- | internal/db/emoji.go | 2 | ||||
-rw-r--r-- | internal/db/error.go | 15 | ||||
-rw-r--r-- | internal/db/status.go | 3 |
5 files changed, 61 insertions, 15 deletions
diff --git a/internal/db/bundb/errors.go b/internal/db/bundb/errors.go index 67a673e15..7d0157373 100644 --- a/internal/db/bundb/errors.go +++ b/internal/db/bundb/errors.go @@ -19,7 +19,7 @@ func processPostgresError(err error) db.Error { // (https://www.postgresql.org/docs/10/errcodes-appendix.html) switch pgErr.Code { case "23505" /* unique_violation */ : - return db.NewErrAlreadyExists(pgErr.Message) + return db.ErrAlreadyExists default: return err } @@ -36,7 +36,7 @@ func processSQLiteError(err error) db.Error { // Handle supplied error code: switch sqliteErr.Code() { case sqlite3.SQLITE_CONSTRAINT_UNIQUE, sqlite3.SQLITE_CONSTRAINT_PRIMARYKEY: - return db.NewErrAlreadyExists(err.Error()) + return db.ErrAlreadyExists default: return err } diff --git a/internal/db/bundb/status.go b/internal/db/bundb/status.go index 378ee1a7a..e247e8940 100644 --- a/internal/db/bundb/status.go +++ b/internal/db/bundb/status.go @@ -22,6 +22,7 @@ import ( "container/list" "context" "database/sql" + "errors" "time" "github.com/superseriousbusiness/gotosocial/internal/cache" @@ -175,6 +176,57 @@ func (s *statusDB) PutStatus(ctx context.Context, status *gtsmodel.Status) db.Er }) } +func (s *statusDB) UpdateStatus(ctx context.Context, status *gtsmodel.Status) (*gtsmodel.Status, db.Error) { + err := s.conn.RunInTx(ctx, func(tx bun.Tx) error { + // create links between this status and any emojis it uses + for _, i := range status.EmojiIDs { + if _, err := tx.NewInsert().Model(>smodel.StatusToEmoji{ + StatusID: status.ID, + EmojiID: i, + }).Exec(ctx); err != nil { + err = s.conn.errProc(err) + if !errors.Is(err, db.ErrAlreadyExists) { + return err + } + } + } + + // create links between this status and any tags it uses + for _, i := range status.TagIDs { + if _, err := tx.NewInsert().Model(>smodel.StatusToTag{ + StatusID: status.ID, + TagID: i, + }).Exec(ctx); err != nil { + err = s.conn.errProc(err) + if !errors.Is(err, db.ErrAlreadyExists) { + return err + } + } + } + + // change the status ID of the media attachments to this status + for _, a := range status.Attachments { + a.StatusID = status.ID + a.UpdatedAt = time.Now() + if _, err := tx.NewUpdate().Model(a). + Where("id = ?", a.ID). + Exec(ctx); err != nil { + return err + } + } + + // Finally, update the status itself + if _, err := tx.NewUpdate().Model(status).WherePK().Exec(ctx); err != nil { + return err + } + + s.cache.Put(status) + return nil + }) + + return status, err +} + func (s *statusDB) GetStatusParents(ctx context.Context, status *gtsmodel.Status, onlyDirect bool) ([]*gtsmodel.Status, db.Error) { parents := []*gtsmodel.Status{} s.statusParent(ctx, status, &parents, onlyDirect) diff --git a/internal/db/emoji.go b/internal/db/emoji.go index 0038e10e4..374fd7b12 100644 --- a/internal/db/emoji.go +++ b/internal/db/emoji.go @@ -35,4 +35,6 @@ type Emoji interface { // GetEmojiByShortcodeDomain gets an emoji based on its shortcode and domain. // For local emoji, domain should be an empty string. GetEmojiByShortcodeDomain(ctx context.Context, shortcode string, domain string) (*gtsmodel.Emoji, Error) + // GetEmojiByURI returns one emoji based on its ActivityPub URI. + GetEmojiByURI(ctx context.Context, uri string) (*gtsmodel.Emoji, Error) } diff --git a/internal/db/error.go b/internal/db/error.go index 9ac0b6aa0..8dc344360 100644 --- a/internal/db/error.go +++ b/internal/db/error.go @@ -28,19 +28,8 @@ var ( ErrNoEntries Error = fmt.Errorf("no entries") // ErrMultipleEntries is returned when a caller expected ONE entry for a query, but multiples were found. ErrMultipleEntries Error = fmt.Errorf("multiple entries") + // ErrAlreadyExists is returned when a conflict was encountered in the db when doing an insert. + ErrAlreadyExists Error = fmt.Errorf("already exists") // ErrUnknown denotes an unknown database error. ErrUnknown Error = fmt.Errorf("unknown error") ) - -// ErrAlreadyExists is returned when a caller tries to insert a database entry that already exists in the db. -type ErrAlreadyExists struct { - message string -} - -func (e *ErrAlreadyExists) Error() string { - return e.message -} - -func NewErrAlreadyExists(msg string) error { - return &ErrAlreadyExists{message: msg} -} diff --git a/internal/db/status.go b/internal/db/status.go index 74eb0d4ff..307d9ea74 100644 --- a/internal/db/status.go +++ b/internal/db/status.go @@ -38,6 +38,9 @@ type Status interface { // PutStatus stores one status in the database. PutStatus(ctx context.Context, status *gtsmodel.Status) Error + // UpdateStatus updates one status in the database and returns it to the caller. + UpdateStatus(ctx context.Context, status *gtsmodel.Status) (*gtsmodel.Status, Error) + // CountStatusReplies returns the amount of replies recorded for a status, or an error if something goes wrong CountStatusReplies(ctx context.Context, status *gtsmodel.Status) (int, Error) |