[GH-25484] Fix draft removal on post deletion (#25715)

* [GH-25484] Fix draft removal on post deletion

* [GH-25484] Add batch migration to remove orphan drafts

* [GH-25484] Fix tests of migration and draft store

* [GH-25484] Remove translation file changes.

* [GH-25484] Remove translation file changes.

---------

Co-authored-by: Devin Binnie <52460000+devinbinnie@users.noreply.github.com>
Co-authored-by: Mattermost Build <build@mattermost.com>
Co-authored-by: Harrison Healey <harrisonmhealey@gmail.com>
Этот коммит содержится в:
Utsav Ladani
2024-01-29 20:25:34 +05:30
коммит произвёл GitHub
родитель 435da9bea7
Коммит 3ac6edb406
19 изменённых файлов: 1046 добавлений и 15 удалений

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

@@ -181,6 +181,29 @@ func (s *SqlDraftStore) Delete(userID, channelID, rootID string) error {
return nil
}
// DeleteDraftsAssociatedWithPost deletes all drafts associated with a post.
func (s *SqlDraftStore) DeleteDraftsAssociatedWithPost(channelID, rootID string) error {
query := s.getQueryBuilder().
Delete("Drafts").
Where(sq.Eq{
"ChannelId": channelID,
"RootId": rootID,
})
sql, args, err := query.ToSql()
if err != nil {
return errors.Wrapf(err, "failed to convert to sql")
}
_, err = s.GetMasterX().Exec(sql, args...)
if err != nil {
return errors.Wrap(err, "failed to delete Draft")
}
return nil
}
// GetMaxDraftSize returns the maximum number of runes that may be stored in a post.
func (s *SqlDraftStore) GetMaxDraftSize() int {
s.maxDraftSizeOnce.Do(func() {
@@ -320,3 +343,59 @@ func (s *SqlDraftStore) DeleteEmptyDraftsByCreateAtAndUserId(createAt int64, use
return nil
}
func (s *SqlDraftStore) DeleteOrphanDraftsByCreateAtAndUserId(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").
Suffix("AND (d.RootId IN (SELECT Id FROM Posts WHERE DeleteAt <> 0) OR NOT EXISTS (SELECT 1 FROM Posts WHERE Posts.Id = d.RootId))")
} 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)"),
).
Suffix("AND (d.RootId IN (SELECT Id FROM Posts WHERE DeleteAt <> 0) OR NOT EXISTS (SELECT 1 FROM Posts WHERE Posts.Id = d.RootId))")
}
if _, err := s.GetMasterX().ExecBuilder(builder); err != nil {
return errors.Wrapf(err, "failed to delete orphan drafts")
}
return nil
}