[MM-53428] Delete empty drafts on upsert (#24046)
* [MM-53428] Delete empty drafts on upsert * Add migrations to fix existing drafts * Fix CI * Delete empty drafts entirely from the DB * Fix lint * Implement batch migration for deleting drafts * Missing store layers * Add updated mock * Remove unnecessary test * PR feedback * Add check for cluster migration * Fix MySQL * Don't check for len<2 * Bit of PR feedback * Use query builder for parameters * PR feedback * More PR feedback * Merge'd * unit test GetLastCreateAtAndUserIdValuesForEmptyDraftsMigration * simplified builder interface * fix DeleteEmptyDraftsByCreateAtAndUserId for MySQL * rework as batch migration worker * fix typo * log ip address on version mismatches too * simplify reset semantics * remove trace log in favour of low spam * document parameters for clarity --------- Co-authored-by: Mattermost Build <build@mattermost.com> Co-authored-by: Jesse Hallam <jesse.hallam@gmail.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
760dfe41f9
Коммит
89492a6a46
@@ -159,11 +159,8 @@ func (s *SqlDraftStore) GetDraftsForUser(userID, teamID string) ([]*model.Draft,
|
||||
}
|
||||
|
||||
func (s *SqlDraftStore) Delete(userID, channelID, rootID string) error {
|
||||
time := model.GetMillis()
|
||||
query := s.getQueryBuilder().
|
||||
Update("Drafts").
|
||||
Set("UpdateAt", time).
|
||||
Set("DeleteAt", time).
|
||||
Delete("Drafts").
|
||||
Where(sq.Eq{
|
||||
"UserId": userID,
|
||||
"ChannelId": channelID,
|
||||
@@ -236,3 +233,90 @@ func (s *SqlDraftStore) determineMaxDraftSize() int {
|
||||
|
||||
return maxDraftSize
|
||||
}
|
||||
|
||||
func (s *SqlDraftStore) GetLastCreateAtAndUserIdValuesForEmptyDraftsMigration(createAt int64, userId string) (int64, string, error) {
|
||||
var drafts []struct {
|
||||
CreateAt int64
|
||||
UserId string
|
||||
}
|
||||
|
||||
query := s.getQueryBuilder().
|
||||
Select("CreateAt", "UserId").
|
||||
From("Drafts").
|
||||
Where(sq.Or{
|
||||
sq.Gt{"CreateAt": createAt},
|
||||
sq.And{
|
||||
sq.Eq{"CreateAt": createAt},
|
||||
sq.Gt{"UserId": userId},
|
||||
},
|
||||
}).
|
||||
OrderBy("CreateAt", "UserId ASC").
|
||||
Limit(100)
|
||||
|
||||
err := s.GetReplicaX().SelectBuilder(&drafts, query)
|
||||
if err != nil {
|
||||
return 0, "", errors.Wrap(err, "failed to get the list of drafts")
|
||||
}
|
||||
|
||||
if len(drafts) == 0 {
|
||||
return 0, "", nil
|
||||
}
|
||||
|
||||
lastElement := drafts[len(drafts)-1]
|
||||
return lastElement.CreateAt, lastElement.UserId, nil
|
||||
}
|
||||
|
||||
func (s *SqlDraftStore) DeleteEmptyDraftsByCreateAtAndUserId(createAt int64, userId string) error {
|
||||
var builder Builder
|
||||
if s.DriverName() == model.DatabaseDriverPostgres {
|
||||
builder = s.getQueryBuilder().
|
||||
Delete("Drafts d").
|
||||
PrefixExpr(s.getQueryBuilder().Select().
|
||||
Prefix("WITH dd AS (").
|
||||
Columns("UserId", "ChannelId", "RootId").
|
||||
From("Drafts").
|
||||
Where(sq.Or{
|
||||
sq.Gt{"CreateAt": createAt},
|
||||
sq.And{
|
||||
sq.Eq{"CreateAt": createAt},
|
||||
sq.Gt{"UserId": userId},
|
||||
},
|
||||
}).
|
||||
OrderBy("CreateAt", "UserId").
|
||||
Limit(100).
|
||||
Suffix(")"),
|
||||
).
|
||||
Using("dd").
|
||||
Where("d.UserId = dd.UserId").
|
||||
Where("d.ChannelId = dd.ChannelId").
|
||||
Where("d.RootId = dd.RootId").
|
||||
Where("d.Message = ''")
|
||||
} else if s.DriverName() == model.DatabaseDriverMysql {
|
||||
builder = s.getQueryBuilder().
|
||||
Delete("Drafts d").
|
||||
What("d.*").
|
||||
JoinClause(s.getQueryBuilder().Select().
|
||||
Prefix("INNER JOIN (").
|
||||
Columns("UserId, ChannelId, RootId").
|
||||
From("Drafts").
|
||||
Where(sq.And{
|
||||
sq.Or{
|
||||
sq.Gt{"CreateAt": createAt},
|
||||
sq.And{
|
||||
sq.Eq{"CreateAt": createAt},
|
||||
sq.Gt{"UserId": userId},
|
||||
},
|
||||
},
|
||||
}).
|
||||
OrderBy("CreateAt", "UserId").
|
||||
Limit(100).
|
||||
Suffix(") dj ON (d.UserId = dj.UserId AND d.ChannelId = dj.ChannelId AND d.RootId = dj.RootId)"),
|
||||
).Where(sq.Eq{"Message": ""})
|
||||
}
|
||||
|
||||
if _, err := s.GetMasterX().ExecBuilder(builder); err != nil {
|
||||
return errors.Wrapf(err, "failed to delete empty drafts")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Ссылка в новой задаче
Block a user