From 61e42c8110e5c34d4ff411848a4dfe7be94da3f4 Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Thu, 15 Jul 2021 19:40:45 +0530 Subject: [PATCH] GroupStore: Use native upsert (#17902) 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/group_store.go | 38 +++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/store/sqlstore/group_store.go b/store/sqlstore/group_store.go index d30a371b92..dc931af382 100644 --- a/store/sqlstore/group_store.go +++ b/store/sqlstore/group_store.go @@ -394,6 +394,7 @@ func (s *SqlGroupStore) UpsertMember(groupID string, userID string) (*model.Grou GroupId: groupID, UserId: userID, CreateAt: model.GetMillis(), + DeleteAt: 0, } if err := member.IsValid(); err != nil { @@ -405,32 +406,25 @@ func (s *SqlGroupStore) UpsertMember(groupID string, userID string) (*model.Grou return nil, errors.Wrapf(err, "failed to get UserGroup with groupId=%s and userId=%s", groupID, userID) } - var retrievedMember *model.GroupMember - if err := s.GetReplica().SelectOne(&retrievedMember, "SELECT * FROM GroupMembers WHERE GroupId = :GroupId AND UserId = :UserId", map[string]interface{}{"GroupId": member.GroupId, "UserId": member.UserId}); err != nil { - if err != sql.ErrNoRows { - return nil, errors.Wrapf(err, "failed to get GroupMember with groupId=%s and userId=%s", groupID, userID) - } + query := s.getQueryBuilder(). + Insert("GroupMembers"). + Columns("GroupId", "UserId", "CreateAt", "DeleteAt"). + Values(member.GroupId, member.UserId, member.CreateAt, member.DeleteAt) + + if s.DriverName() == model.DATABASE_DRIVER_MYSQL { + query = query.SuffixExpr(sq.Expr("ON DUPLICATE KEY UPDATE CreateAt = ?, DeleteAt = ?", member.CreateAt, member.DeleteAt)) + } else if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { + query = query.SuffixExpr(sq.Expr("ON CONFLICT (groupid, userid) DO UPDATE SET CreateAt = ?, DeleteAt = ?", member.CreateAt, member.DeleteAt)) } - if retrievedMember == nil { - if err := s.GetMaster().Insert(member); err != nil { - if IsUniqueConstraintError(err, []string{"GroupId", "UserId", "groupmembers_pkey", "PRIMARY"}) { - return nil, store.NewErrInvalidInput("Member", "", fmt.Sprintf("<%s, %s>", groupID, userID)) - } - return nil, errors.Wrap(err, "failed to save Member") - } - } else { - member.DeleteAt = 0 - var rowsChanged int64 - var err error - if rowsChanged, err = s.GetMaster().Update(member); err != nil { - return nil, errors.Wrapf(err, "failed to update GroupMember with groupId=%s and userId=%s", groupID, userID) - } - if rowsChanged > 1 { - return nil, errors.Wrapf(err, "multiple GroupMembers were updated: %d", rowsChanged) - } + queryString, args, err := query.ToSql() + if err != nil { + return nil, errors.Wrap(err, "failed to generate sqlquery") } + if _, err = s.GetMaster().Exec(queryString, args...); err != nil { + return nil, errors.Wrap(err, "failed to save GroupMember") + } return member, nil }