Migrate ChannelStore.UpdateLastViewedAt to squirrel (#19439)
Fixes https://github.com/mattermost/mattermost-server/issues/19332 ```release-note NONE ``` Co-authored-by: Mattermod <mattermod@users.noreply.github.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
de0d95f72b
Коммит
d5b24e383d
@@ -2431,7 +2431,6 @@ func (s SqlChannelStore) PermanentDeleteMembersByUser(userId string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: convert to squirrel (https://github.com/mattermost/mattermost-server/issues/19332)
|
||||
func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string, updateThreads bool) (map[string]int64, error) {
|
||||
var threadsToUpdate []string
|
||||
now := model.GetMillis()
|
||||
@@ -2443,38 +2442,50 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
|
||||
}
|
||||
}
|
||||
|
||||
keys, props := MapStringsToQueryParams(channelIds, "Channel")
|
||||
props["UserId"] = userId
|
||||
|
||||
var lastPostAtTimes []struct {
|
||||
lastPostAtTimes := []struct {
|
||||
Id string
|
||||
LastPostAt int64
|
||||
TotalMsgCount int64
|
||||
TotalMsgCountRoot int64
|
||||
}
|
||||
}{}
|
||||
|
||||
// We use the question placeholder format for both databases, because
|
||||
// we replace that with the dollar format later on.
|
||||
// It's needed to support the prefix CTE query. See: https://github.com/Masterminds/squirrel/issues/285.
|
||||
query := sq.StatementBuilder.PlaceholderFormat(sq.Question).
|
||||
Select("Id, LastPostAt, TotalMsgCount, TotalMsgCountRoot").
|
||||
From("Channels").
|
||||
Where(sq.Eq{"Id": channelIds})
|
||||
|
||||
query := `SELECT Id, LastPostAt, TotalMsgCount, TotalMsgCountRoot FROM Channels WHERE Id IN ` + keys
|
||||
// TODO: use a CTE for mysql too when version 8 becomes the minimum supported version.
|
||||
if s.DriverName() == model.DatabaseDriverPostgres {
|
||||
query = `WITH c AS ( ` + query + `),
|
||||
updated AS (
|
||||
UPDATE
|
||||
ChannelMembers cm
|
||||
SET
|
||||
MentionCount = 0,
|
||||
MentionCountRoot = 0,
|
||||
MsgCount = greatest(cm.MsgCount, c.TotalMsgCount),
|
||||
MsgCountRoot = greatest(cm.MsgCountRoot, c.TotalMsgCountRoot),
|
||||
LastViewedAt = greatest(cm.LastViewedAt, c.LastPostAt),
|
||||
LastUpdateAt = greatest(cm.LastViewedAt, c.LastPostAt)
|
||||
FROM c
|
||||
WHERE cm.UserId = :UserId
|
||||
AND c.Id=cm.ChannelId
|
||||
)
|
||||
SELECT Id, LastPostAt FROM c`
|
||||
with := query.Prefix("WITH c AS (").Suffix(") ,")
|
||||
update := sq.StatementBuilder.PlaceholderFormat(sq.Question).
|
||||
Update("ChannelMembers cm").
|
||||
Set("MentionCount", 0).
|
||||
Set("MentionCountRoot", 0).
|
||||
Set("MsgCount", sq.Expr("greatest(cm.MsgCount, c.TotalMsgCount)")).
|
||||
Set("MsgCountRoot", sq.Expr("greatest(cm.MsgCountRoot, c.TotalMsgCountRoot)")).
|
||||
Set("LastViewedAt", sq.Expr("greatest(cm.LastViewedAt, c.LastPostAt)")).
|
||||
Set("LastUpdateAt", sq.Expr("greatest(cm.LastViewedAt, c.LastPostAt)")).
|
||||
SuffixExpr(sq.Expr("FROM c WHERE cm.UserId = ? AND c.Id = cm.ChannelId", userId))
|
||||
updateWrap := update.Prefix("updated AS (").Suffix(")")
|
||||
query = with.SuffixExpr(updateWrap).Suffix("SELECT Id, LastPostAt FROM c")
|
||||
}
|
||||
|
||||
_, err := s.GetMaster().Select(&lastPostAtTimes, query, props)
|
||||
sql, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "UpdateLastViewedAt_CTE_Tosql")
|
||||
}
|
||||
|
||||
if s.DriverName() == model.DatabaseDriverPostgres {
|
||||
sql, err = sq.Dollar.ReplacePlaceholders(sql)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "UpdateLastViewedAt_ReplacePlaceholders")
|
||||
}
|
||||
}
|
||||
|
||||
err = s.GetMasterX().Select(&lastPostAtTimes, sql, args...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to find ChannelMembers data with userId=%s and channelId in %v", userId, channelIds)
|
||||
}
|
||||
@@ -2494,39 +2505,42 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
|
||||
return times, nil
|
||||
}
|
||||
|
||||
msgCountQuery := ""
|
||||
msgCountQueryRoot := ""
|
||||
lastViewedQuery := ""
|
||||
var msgCountQuery, msgCountQueryRoot, lastViewedQuery = sq.Case("ChannelId"), sq.Case("ChannelId"), sq.Case("ChannelId")
|
||||
|
||||
for index, t := range lastPostAtTimes {
|
||||
for _, t := range lastPostAtTimes {
|
||||
times[t.Id] = t.LastPostAt
|
||||
|
||||
props["msgCount"+strconv.Itoa(index)] = t.TotalMsgCount
|
||||
msgCountQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(MsgCount, :msgCount%d) ", index, index)
|
||||
msgCountQuery = msgCountQuery.When(
|
||||
sq.Expr("?", t.Id),
|
||||
sq.Expr("GREATEST(MsgCount, ?)", t.TotalMsgCount))
|
||||
|
||||
props["msgCountRoot"+strconv.Itoa(index)] = t.TotalMsgCountRoot
|
||||
msgCountQueryRoot += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(MsgCountRoot, :msgCountRoot%d) ", index, index)
|
||||
msgCountQueryRoot = msgCountQueryRoot.When(
|
||||
sq.Expr("?", t.Id),
|
||||
sq.Expr("GREATEST(MsgCountRoot, ?)", t.TotalMsgCountRoot))
|
||||
|
||||
props["lastViewed"+strconv.Itoa(index)] = t.LastPostAt
|
||||
lastViewedQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(LastViewedAt, :lastViewed%d) ", index, index)
|
||||
|
||||
props["channelId"+strconv.Itoa(index)] = t.Id
|
||||
lastViewedQuery = lastViewedQuery.When(
|
||||
sq.Expr("?", t.Id),
|
||||
sq.Expr("GREATEST(LastViewedAt, ?)", t.LastPostAt))
|
||||
}
|
||||
|
||||
updateQuery := `UPDATE
|
||||
ChannelMembers
|
||||
SET
|
||||
MentionCount = 0,
|
||||
MentionCountRoot = 0,
|
||||
MsgCount = CASE ChannelId ` + msgCountQuery + ` END,
|
||||
MsgCountRoot = CASE ChannelId ` + msgCountQueryRoot + ` END,
|
||||
LastViewedAt = CASE ChannelId ` + lastViewedQuery + ` END,
|
||||
LastUpdateAt = LastViewedAt
|
||||
WHERE
|
||||
UserId = :UserId
|
||||
AND ChannelId IN ` + keys
|
||||
updateQuery := s.getQueryBuilder().Update("ChannelMembers").
|
||||
Set("MentionCount", 0).
|
||||
Set("MentionCountRoot", 0).
|
||||
Set("MsgCount", msgCountQuery).
|
||||
Set("MsgCountRoot", msgCountQueryRoot).
|
||||
Set("LastViewedAt", lastViewedQuery).
|
||||
Set("LastUpdateAt", sq.Expr("LastViewedAt")).
|
||||
Where(sq.Eq{
|
||||
"UserId": userId,
|
||||
"ChannelId": channelIds,
|
||||
})
|
||||
|
||||
if _, err := s.GetMaster().Exec(updateQuery, props); err != nil {
|
||||
sql, args, err = updateQuery.ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "UpdateLastViewedAt_Update_Tosql")
|
||||
}
|
||||
|
||||
if _, err := s.GetMasterX().Exec(sql, args...); err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to update ChannelMembers with userId=%s and channelId in %v", userId, channelIds)
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user