[MM-45444] Denormalize Reactions to add ChannelId for top reactions insights query (#20572)

* Denormalize Reactions to add ChannelId for top reactions insights query

* Remove hardcoded timestamps

* Fix store, api4 tests for reactions

* Fix tests

* Fix integrity tests, allow reaction to have ChannelId populated before calling store function

* Lint fixes

* Add ChannelId field to BulkGetForPosts, Delete store handlers

* Add index to mysql migration, add not null characteristic without a separate command

* Select channelId instead of fetching post via store.GetPost, add if exists to drop column

* Make updating of Reactions conditional to support pre-migration

Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
Shivashis Padhi
2022-07-11 18:55:03 +05:30
коммит произвёл GitHub
родитель 7bbf30d6bc
Коммит 20d690b412
9 изменённых файлов: 148 добавлений и 29 удалений

Просмотреть файл

@@ -212,6 +212,7 @@ func createReaction(ss store.Store, userId, postId string) *model.Reaction {
UserId: userId,
PostId: postId,
EmojiName: model.NewId(),
ChannelId: model.NewId(),
}
reaction, _ = ss.Reaction().Save(reaction)
return reaction

Просмотреть файл

@@ -26,12 +26,23 @@ func (s *SqlReactionStore) Save(reaction *model.Reaction) (*model.Reaction, erro
if err := reaction.IsValid(); err != nil {
return nil, err
}
transaction, err := s.GetMasterX().Beginx()
if err != nil {
return nil, errors.Wrap(err, "begin_transaction")
}
defer finalizeTransactionX(transaction)
if reaction.ChannelId == "" {
// get channelId, if not already populated
var channelIds []string
var args []interface{}
query := "SELECT ChannelId from Posts where Id = ?"
args = append(args, reaction.PostId)
err = transaction.Select(&channelIds, query, args...)
if err != nil {
return nil, errors.Wrap(err, "failed while getting channelId from Posts")
}
reaction.ChannelId = channelIds[0]
}
err = s.saveReactionAndUpdatePost(transaction, reaction)
if err != nil {
// We don't consider duplicated save calls as an error
@@ -71,7 +82,7 @@ func (s *SqlReactionStore) Delete(reaction *model.Reaction) (*model.Reaction, er
func (s *SqlReactionStore) GetForPost(postId string, allowFromCache bool) ([]*model.Reaction, error) {
queryString, args, err := s.getQueryBuilder().
Select("UserId", "PostId", "EmojiName", "CreateAt", "COALESCE(UpdateAt, CreateAt) As UpdateAt",
"COALESCE(DeleteAt, 0) As DeleteAt", "RemoteId").
"COALESCE(DeleteAt, 0) As DeleteAt", "RemoteId", "ChannelId").
From("Reactions").
Where(sq.Eq{"PostId": postId}).
Where(sq.Eq{"COALESCE(DeleteAt, 0)": 0}).
@@ -132,7 +143,8 @@ func (s *SqlReactionStore) BulkGetForPosts(postIds []string) ([]*model.Reaction,
CreateAt,
COALESCE(UpdateAt, CreateAt) As UpdateAt,
COALESCE(DeleteAt, 0) As DeleteAt,
RemoteId
RemoteId,
ChannelId
FROM
Reactions
WHERE
@@ -247,8 +259,7 @@ func (s *SqlReactionStore) GetTopForTeamSince(teamID string, userID string, sinc
FROM
ChannelMembers
INNER JOIN Channels ON ChannelMembers.ChannelId = Channels.Id
INNER JOIN Posts ON Channels.Id = Posts.ChannelId
INNER JOIN Reactions ON Posts.Id = Reactions.PostId
INNER JOIN Reactions ON Channels.Id = Reactions.ChannelId
WHERE
ChannelMembers.UserId = ?
AND Channels.Type = 'P'
@@ -265,8 +276,7 @@ func (s *SqlReactionStore) GetTopForTeamSince(teamID string, userID string, sinc
Reactions.CreateAt AS CreateAt
FROM
Reactions
INNER JOIN Posts ON Reactions.PostId = Posts.Id
INNER JOIN PublicChannels ON Posts.ChannelId = PublicChannels.Id
INNER JOIN PublicChannels ON Reactions.ChannelId = PublicChannels.Id
WHERE
PublicChannels.TeamId = ?
GROUP BY
@@ -356,22 +366,22 @@ func (s *SqlReactionStore) saveReactionAndUpdatePost(transaction *sqlxTxWrapper,
if _, err := transaction.NamedExec(
`INSERT INTO
Reactions
(UserId, PostId, EmojiName, CreateAt, UpdateAt, DeleteAt, RemoteId)
(UserId, PostId, EmojiName, CreateAt, UpdateAt, DeleteAt, RemoteId, ChannelId)
VALUES
(:UserId, :PostId, :EmojiName, :CreateAt, :UpdateAt, :DeleteAt, :RemoteId)
(:UserId, :PostId, :EmojiName, :CreateAt, :UpdateAt, :DeleteAt, :RemoteId, :ChannelId)
ON DUPLICATE KEY UPDATE
UpdateAt = :UpdateAt, DeleteAt = :DeleteAt, RemoteId = :RemoteId`, reaction); err != nil {
UpdateAt = :UpdateAt, DeleteAt = :DeleteAt, RemoteId = :RemoteId, ChannelId = :ChannelId`, reaction); err != nil {
return err
}
} else if s.DriverName() == model.DatabaseDriverPostgres {
if _, err := transaction.NamedExec(
`INSERT INTO
Reactions
(UserId, PostId, EmojiName, CreateAt, UpdateAt, DeleteAt, RemoteId)
(UserId, PostId, EmojiName, CreateAt, UpdateAt, DeleteAt, RemoteId, ChannelId)
VALUES
(:UserId, :PostId, :EmojiName, :CreateAt, :UpdateAt, :DeleteAt, :RemoteId)
(:UserId, :PostId, :EmojiName, :CreateAt, :UpdateAt, :DeleteAt, :RemoteId, :ChannelId)
ON CONFLICT (UserId, PostId, EmojiName)
DO UPDATE SET UpdateAt = :UpdateAt, DeleteAt = :DeleteAt, RemoteId = :RemoteId`, reaction); err != nil {
DO UPDATE SET UpdateAt = :UpdateAt, DeleteAt = :DeleteAt, RemoteId = :RemoteId, ChannelId = :ChannelId`, reaction); err != nil {
return err
}
}