From 76531008358ac71156e2054d3916e530ec43c1c4 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Fri, 9 Jul 2021 19:36:21 +0530 Subject: [PATCH] ChannelStore: Use native upsert for Postgres (#17880) Now that version 10 is minimum, we can start to use advanced postgres features. https://focalboard-community.octo.mattermost.com/workspace/zyoahc9uapdn3xdptac6jb69ic?id=285b80a3-257d-41f6-8cf4-ed80ca9d92e5&v=495cdb4d-c13a-4992-8eb9-80cfee2819a4&c=0445b560-91b9-469b-8f19-febf1881bcd6 ```release-note NONE ``` --- store/sqlstore/channel_store.go | 54 +++++++++++++++++---------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/store/sqlstore/channel_store.go b/store/sqlstore/channel_store.go index 56fb36f30d..9e1898b97e 100644 --- a/store/sqlstore/channel_store.go +++ b/store/sqlstore/channel_store.go @@ -485,11 +485,18 @@ func (s SqlChannelStore) upsertPublicChannelT(transaction *gorp.Transaction, cha return nil } + vals := map[string]interface{}{ + "Id": publicChannel.Id, + "DeleteAt": publicChannel.DeleteAt, + "TeamId": publicChannel.TeamId, + "DisplayName": publicChannel.DisplayName, + "Name": publicChannel.Name, + "Header": publicChannel.Header, + "Purpose": publicChannel.Purpose, + } + var err error if s.DriverName() == model.DATABASE_DRIVER_MYSQL { - // Leverage native upsert for MySQL, since RowsAffected returns 0 if the row exists - // but no changes were made, breaking the update-then-insert paradigm below when - // the row already exists. (Postgres 9.4 doesn't support native upsert.) - if _, err := transaction.Exec(` + _, err = transaction.Exec(` INSERT INTO PublicChannels(Id, DeleteAt, TeamId, DisplayName, Name, Header, Purpose) VALUES @@ -501,29 +508,24 @@ func (s SqlChannelStore) upsertPublicChannelT(transaction *gorp.Transaction, cha Name = :Name, Header = :Header, Purpose = :Purpose; - `, map[string]interface{}{ - "Id": publicChannel.Id, - "DeleteAt": publicChannel.DeleteAt, - "TeamId": publicChannel.TeamId, - "DisplayName": publicChannel.DisplayName, - "Name": publicChannel.Name, - "Header": publicChannel.Header, - "Purpose": publicChannel.Purpose, - }); err != nil { - return errors.Wrap(err, "failed to insert public channel") - } + `, vals) } else { - count, err := transaction.Update(publicChannel) - if err != nil { - return errors.Wrap(err, "failed to update public channel") - } - if count > 0 { - return nil - } - - if err := transaction.Insert(publicChannel); err != nil { - return errors.Wrap(err, "failed to insert public channel") - } + _, err = transaction.Exec(` + INSERT INTO + PublicChannels(Id, DeleteAt, TeamId, DisplayName, Name, Header, Purpose) + VALUES + (:Id, :DeleteAt, :TeamId, :DisplayName, :Name, :Header, :Purpose) + ON CONFLICT (id) DO UPDATE + SET DeleteAt = :DeleteAt, + TeamId = :TeamId, + DisplayName = :DisplayName, + Name = :Name, + Header = :Header, + Purpose = :Purpose; + `, vals) + } + if err != nil { + return errors.Wrap(err, "failed to insert public channel") } return nil