mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2024-11-27 06:40:32 +00:00
[bugfix] add ON CONFLICT statements to status updates (#1580)
This commit is contained in:
parent
e6cde25466
commit
bfccf4e450
2 changed files with 43 additions and 6 deletions
|
@ -200,7 +200,9 @@ func (s *statusDB) PutStatus(ctx context.Context, status *gtsmodel.Status) db.Er
|
|||
Model(>smodel.StatusToEmoji{
|
||||
StatusID: status.ID,
|
||||
EmojiID: i,
|
||||
}).Exec(ctx); err != nil {
|
||||
}).
|
||||
On("CONFLICT (?, ?) DO NOTHING", bun.Ident("status_id"), bun.Ident("emoji_id")).
|
||||
Exec(ctx); err != nil {
|
||||
err = s.conn.ProcessError(err)
|
||||
if !errors.Is(err, db.ErrAlreadyExists) {
|
||||
return err
|
||||
|
@ -215,7 +217,9 @@ func (s *statusDB) PutStatus(ctx context.Context, status *gtsmodel.Status) db.Er
|
|||
Model(>smodel.StatusToTag{
|
||||
StatusID: status.ID,
|
||||
TagID: i,
|
||||
}).Exec(ctx); err != nil {
|
||||
}).
|
||||
On("CONFLICT (?, ?) DO NOTHING", bun.Ident("status_id"), bun.Ident("tag_id")).
|
||||
Exec(ctx); err != nil {
|
||||
err = s.conn.ProcessError(err)
|
||||
if !errors.Is(err, db.ErrAlreadyExists) {
|
||||
return err
|
||||
|
@ -261,7 +265,9 @@ func (s *statusDB) UpdateStatus(ctx context.Context, status *gtsmodel.Status, co
|
|||
Model(>smodel.StatusToEmoji{
|
||||
StatusID: status.ID,
|
||||
EmojiID: i,
|
||||
}).Exec(ctx); err != nil {
|
||||
}).
|
||||
On("CONFLICT (?, ?) DO NOTHING", bun.Ident("status_id"), bun.Ident("emoji_id")).
|
||||
Exec(ctx); err != nil {
|
||||
err = s.conn.ProcessError(err)
|
||||
if !errors.Is(err, db.ErrAlreadyExists) {
|
||||
return err
|
||||
|
@ -276,7 +282,9 @@ func (s *statusDB) UpdateStatus(ctx context.Context, status *gtsmodel.Status, co
|
|||
Model(>smodel.StatusToTag{
|
||||
StatusID: status.ID,
|
||||
TagID: i,
|
||||
}).Exec(ctx); err != nil {
|
||||
}).
|
||||
On("CONFLICT (?, ?) DO NOTHING", bun.Ident("status_id"), bun.Ident("tag_id")).
|
||||
Exec(ctx); err != nil {
|
||||
err = s.conn.ProcessError(err)
|
||||
if !errors.Is(err, db.ErrAlreadyExists) {
|
||||
return err
|
||||
|
@ -300,7 +308,7 @@ func (s *statusDB) UpdateStatus(ctx context.Context, status *gtsmodel.Status, co
|
|||
}
|
||||
}
|
||||
|
||||
// Finally, insert the status
|
||||
// Finally, update the status
|
||||
_, err := tx.
|
||||
NewUpdate().
|
||||
Model(status).
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
)
|
||||
|
||||
type StatusTestSuite struct {
|
||||
|
@ -176,7 +177,10 @@ func (suite *StatusTestSuite) TestGetStatusChildren() {
|
|||
}
|
||||
|
||||
func (suite *StatusTestSuite) TestDeleteStatus() {
|
||||
targetStatus := suite.testStatuses["admin_account_status_1"]
|
||||
// Take a copy of the status.
|
||||
targetStatus := >smodel.Status{}
|
||||
*targetStatus = *suite.testStatuses["admin_account_status_1"]
|
||||
|
||||
err := suite.db.DeleteStatusByID(context.Background(), targetStatus.ID)
|
||||
suite.NoError(err)
|
||||
|
||||
|
@ -184,6 +188,31 @@ func (suite *StatusTestSuite) TestDeleteStatus() {
|
|||
suite.ErrorIs(err, db.ErrNoEntries)
|
||||
}
|
||||
|
||||
// This test was added specifically to ensure that Postgres wasn't getting upset
|
||||
// about trying to use a transaction in which an error has already occurred, which
|
||||
// was previously leading to errors like 'current transaction is aborted, commands
|
||||
// ignored until end of transaction block' when updating a status that already had
|
||||
// emojis or tags set on it.
|
||||
//
|
||||
// To run this test for postgres specifically, start a postgres container on localhost
|
||||
// and then run:
|
||||
//
|
||||
// GTS_DB_TYPE=postgres GTS_DB_ADDRESS=localhost go test ./internal/db/bundb -run '^TestStatusTestSuite$' -testify.m '^(TestUpdateStatus)$' github.com/superseriousbusiness/gotosocial/internal/db/bundb
|
||||
func (suite *StatusTestSuite) TestUpdateStatus() {
|
||||
// Take a copy of the status.
|
||||
targetStatus := >smodel.Status{}
|
||||
*targetStatus = *suite.testStatuses["admin_account_status_1"]
|
||||
|
||||
targetStatus.PinnedAt = time.Time{}
|
||||
|
||||
err := suite.db.UpdateStatus(context.Background(), targetStatus, "pinned_at")
|
||||
suite.NoError(err)
|
||||
|
||||
updated, err := suite.db.GetStatusByID(context.Background(), targetStatus.ID)
|
||||
suite.NoError(err)
|
||||
suite.True(updated.PinnedAt.IsZero())
|
||||
}
|
||||
|
||||
func TestStatusTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(StatusTestSuite))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue