Adds logical deletes to shared channel remotes and remote clusters (#28159)
* Adds logical deletes to shared channel remotes and remote clusters Instead of physically deleting the shared channel remote and remote clusters records when a channel is unshared, a remote uninvited or a remote cluster is deleted, now those have a logical `DeleteAt` field that is set. This allows us to safely restore shared channels between two remote clusters (as of now resetting the cursor without backfilling their contents) and to know which connections were established in the past and now are severed. * Delete the index in remoteclusters before adding the new column * Fix bad error check
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
19733eef1e
Коммит
f8202309ce
@@ -36,6 +36,7 @@ func remoteClusterFields(prefix string) []string {
|
||||
prefix + "SiteURL",
|
||||
prefix + "DefaultTeamId",
|
||||
prefix + "CreateAt",
|
||||
prefix + "DeleteAt",
|
||||
prefix + "LastPingAt",
|
||||
prefix + "Token",
|
||||
prefix + "RemoteToken",
|
||||
@@ -67,10 +68,10 @@ func (s sqlRemoteClusterStore) Save(remoteCluster *model.RemoteCluster) (*model.
|
||||
|
||||
query := `INSERT INTO RemoteClusters
|
||||
(RemoteId, RemoteTeamId, Name, DisplayName, SiteURL, DefaultTeamId, CreateAt,
|
||||
LastPingAt, Token, RemoteToken, Topics, CreatorId, PluginID, Options)
|
||||
DeleteAt, LastPingAt, Token, RemoteToken, Topics, CreatorId, PluginID, Options)
|
||||
VALUES
|
||||
(:RemoteId, :RemoteTeamId, :Name, :DisplayName, :SiteURL, :DefaultTeamId, :CreateAt,
|
||||
:LastPingAt, :Token, :RemoteToken, :Topics, :CreatorId, :PluginID, :Options)`
|
||||
:DeleteAt, :LastPingAt, :Token, :RemoteToken, :Topics, :CreatorId, :PluginID, :Options)`
|
||||
|
||||
if _, err := s.GetMasterX().NamedExec(query, remoteCluster); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to save RemoteCluster")
|
||||
@@ -89,6 +90,7 @@ func (s sqlRemoteClusterStore) Update(remoteCluster *model.RemoteCluster) (*mode
|
||||
SET Token = :Token,
|
||||
RemoteTeamId = :RemoteTeamId,
|
||||
CreateAt = :CreateAt,
|
||||
DeleteAt = :DeleteAt,
|
||||
LastPingAt = :LastPingAt,
|
||||
RemoteToken = :RemoteToken,
|
||||
CreatorId = :CreatorId,
|
||||
@@ -107,24 +109,53 @@ func (s sqlRemoteClusterStore) Update(remoteCluster *model.RemoteCluster) (*mode
|
||||
}
|
||||
|
||||
func (s sqlRemoteClusterStore) Delete(remoteId string) (bool, error) {
|
||||
transaction, err := s.GetMasterX().Beginx()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "DeleteRemoteCluster: begin_transaction")
|
||||
}
|
||||
defer finalizeTransactionX(transaction, &err)
|
||||
|
||||
curTime := model.GetMillis()
|
||||
|
||||
// we delete the remote cluster itself
|
||||
squery, args, err := s.getQueryBuilder().
|
||||
Delete("RemoteClusters").
|
||||
Update("RemoteClusters").
|
||||
Set("DeleteAt", curTime).
|
||||
Where(sq.Eq{"RemoteId": remoteId}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "delete_remote_cluster_tosql")
|
||||
}
|
||||
|
||||
result, err := s.GetMasterX().Exec(squery, args...)
|
||||
result, err := transaction.Exec(squery, args...)
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to delete RemoteCluster")
|
||||
}
|
||||
|
||||
// also remove the shared channel remotes for the cluster (if any)
|
||||
squery, args, err = s.getQueryBuilder().
|
||||
Update("SharedChannelRemotes").
|
||||
Set("UpdateAt", curTime).
|
||||
Set("DeleteAt", curTime).
|
||||
Where(sq.Eq{"RemoteId": remoteId}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "delete_shared_channel_remotes_for_remote_cluster_tosql")
|
||||
}
|
||||
|
||||
if _, err = transaction.Exec(squery, args...); err != nil {
|
||||
return false, errors.Wrap(err, "failed to delete SharedChannelRemotes for RemoteCluster")
|
||||
}
|
||||
|
||||
count, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "failed to determine rows affected")
|
||||
}
|
||||
|
||||
if err = transaction.Commit(); err != nil {
|
||||
return false, errors.Wrap(err, "commit_transaction")
|
||||
}
|
||||
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
@@ -213,6 +244,10 @@ func (s sqlRemoteClusterStore) GetAll(offset, limit int, filter model.RemoteClus
|
||||
query = query.Where(sq.NotEq{fmt.Sprintf("(rc.Options & %d)", filter.RequireOptions): 0})
|
||||
}
|
||||
|
||||
if !filter.IncludeDeleted {
|
||||
query = query.Where(sq.Eq{"DeleteAt": 0})
|
||||
}
|
||||
|
||||
if filter.Topic != "" {
|
||||
trimmed := strings.TrimSpace(filter.Topic)
|
||||
if trimmed == "" || trimmed == "*" {
|
||||
|
||||
@@ -269,8 +269,10 @@ func (s SqlSharedChannelStore) Update(sc *model.SharedChannel) (*model.SharedCha
|
||||
return sc, nil
|
||||
}
|
||||
|
||||
// Delete deletes a single shared channel plus associated SharedChannelRemotes.
|
||||
// Returns true if shared channel found and deleted, false if not found.
|
||||
// Delete deletes a single shared channel as deleted, plus marks as
|
||||
// deleted associated SharedChannelRemotes.
|
||||
// Returns true if shared channel found and deleted, false if not
|
||||
// found.
|
||||
func (s SqlSharedChannelStore) Delete(channelId string) (ok bool, err error) {
|
||||
transaction, err := s.GetMasterX().Beginx()
|
||||
if err != nil {
|
||||
@@ -291,17 +293,20 @@ func (s SqlSharedChannelStore) Delete(channelId string) (ok bool, err error) {
|
||||
return false, errors.Wrap(err, "failed to delete SharedChannel")
|
||||
}
|
||||
|
||||
curTime := model.GetMillis()
|
||||
|
||||
// Also remove remotes from SharedChannelRemotes (if any).
|
||||
squery, args, err = s.getQueryBuilder().
|
||||
Delete("SharedChannelRemotes").
|
||||
Update("SharedChannelRemotes").
|
||||
Set("UpdateAt", curTime).
|
||||
Set("DeleteAt", curTime).
|
||||
Where(sq.Eq{"ChannelId": channelId}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
return false, errors.Wrap(err, "delete_shared_channel_remotes_tosql")
|
||||
}
|
||||
|
||||
_, err = transaction.Exec(squery, args...)
|
||||
if err != nil {
|
||||
if _, err = transaction.Exec(squery, args...); err != nil {
|
||||
return false, errors.Wrap(err, "failed to delete SharedChannelRemotes")
|
||||
}
|
||||
|
||||
@@ -337,10 +342,10 @@ func (s SqlSharedChannelStore) SaveRemote(remote *model.SharedChannelRemote) (*m
|
||||
}
|
||||
|
||||
query, args, err := s.getQueryBuilder().Insert("SharedChannelRemotes").
|
||||
Columns("Id", "ChannelId", "CreatorId", "CreateAt", "UpdateAt", "IsInviteAccepted", "IsInviteConfirmed", "RemoteId",
|
||||
Columns("Id", "ChannelId", "CreatorId", "CreateAt", "UpdateAt", "DeleteAt", "IsInviteAccepted", "IsInviteConfirmed", "RemoteId",
|
||||
"LastPostCreateAt", "LastPostCreateId", "LastPostUpdateAt", "LastPostId").
|
||||
Values(remote.Id, remote.ChannelId, remote.CreatorId, remote.CreateAt, remote.UpdateAt, remote.IsInviteAccepted, remote.IsInviteConfirmed, remote.RemoteId,
|
||||
remote.LastPostCreateAt, remote.LastPostCreateID, remote.LastPostUpdateAt, remote.LastPostUpdateID).
|
||||
Values(remote.Id, remote.ChannelId, remote.CreatorId, remote.CreateAt, remote.UpdateAt, remote.DeleteAt, remote.IsInviteAccepted, remote.IsInviteConfirmed,
|
||||
remote.RemoteId, remote.LastPostCreateAt, remote.LastPostCreateID, remote.LastPostUpdateAt, remote.LastPostUpdateID).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "savesharedchannelremote_tosql")
|
||||
@@ -362,6 +367,7 @@ func (s SqlSharedChannelStore) UpdateRemote(remote *model.SharedChannelRemote) (
|
||||
Set("CreatorId", remote.CreatorId).
|
||||
Set("CreateAt", remote.CreateAt).
|
||||
Set("UpdateAt", remote.UpdateAt).
|
||||
Set("DeleteAt", remote.DeleteAt).
|
||||
Set("IsInviteAccepted", remote.IsInviteAccepted).
|
||||
Set("IsInviteConfirmed", remote.IsInviteConfirmed).
|
||||
Set("RemoteId", remote.RemoteId).
|
||||
@@ -403,6 +409,7 @@ func sharedChannelRemoteFields(prefix string) []string {
|
||||
prefix + "CreatorId",
|
||||
prefix + "CreateAt",
|
||||
prefix + "UpdateAt",
|
||||
prefix + "DeleteAt",
|
||||
prefix + "IsInviteAccepted",
|
||||
prefix + "IsInviteConfirmed",
|
||||
prefix + "RemoteId",
|
||||
@@ -504,6 +511,10 @@ func (s SqlSharedChannelStore) GetRemotes(offset, limit int, opts model.SharedCh
|
||||
|
||||
query = query.Offset(uint64(offset)).Limit(uint64(limit))
|
||||
|
||||
if !opts.IncludeDeleted {
|
||||
query = query.Where(sq.Eq{"DeleteAt": 0})
|
||||
}
|
||||
|
||||
squery, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "get_shared_channel_remotes_tosql")
|
||||
@@ -526,6 +537,7 @@ func (s SqlSharedChannelStore) HasRemote(channelID string, remoteId string) (boo
|
||||
From("SharedChannelRemotes").
|
||||
Where(sq.Eq{"RemoteId": remoteId}).
|
||||
Where(sq.Eq{"ChannelId": channelID}).
|
||||
Where(sq.Eq{"DeleteAt": 0}).
|
||||
Suffix(")")
|
||||
|
||||
query, args, err := builder.ToSql()
|
||||
@@ -549,6 +561,7 @@ func (s SqlSharedChannelStore) GetRemoteForUser(remoteId string, userId string)
|
||||
Join("SharedChannelRemotes AS scr ON rc.RemoteId = scr.RemoteId").
|
||||
Join("ChannelMembers AS cm ON scr.ChannelId = cm.ChannelId").
|
||||
Where(sq.Eq{"rc.RemoteId": remoteId}).
|
||||
Where(sq.Eq{"scr.DeleteAt": 0}).
|
||||
Where(sq.Eq{"cm.UserId": userId})
|
||||
|
||||
query, args, err := builder.ToSql()
|
||||
@@ -614,8 +627,12 @@ func (s SqlSharedChannelStore) UpdateRemoteCursor(id string, cursor model.GetPos
|
||||
// DeleteRemote deletes a single shared channel remote.
|
||||
// Returns true if remote found and deleted, false if not found.
|
||||
func (s SqlSharedChannelStore) DeleteRemote(id string) (bool, error) {
|
||||
curTime := model.GetMillis()
|
||||
|
||||
squery, args, err := s.getQueryBuilder().
|
||||
Delete("SharedChannelRemotes").
|
||||
Update("SharedChannelRemotes").
|
||||
Set("DeleteAt", curTime).
|
||||
Set("UpdateAt", curTime).
|
||||
Where(sq.Eq{"Id": id}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
@@ -644,6 +661,7 @@ func (s SqlSharedChannelStore) GetRemotesStatus(channelId string) ([]*model.Shar
|
||||
Select("scr.ChannelId, rc.DisplayName, rc.SiteURL, rc.LastPingAt, sc.ReadOnly, scr.IsInviteAccepted").
|
||||
From("SharedChannelRemotes scr, RemoteClusters rc, SharedChannels sc").
|
||||
Where("scr.RemoteId = rc.RemoteId").
|
||||
Where("scr.DeleteAt = 0").
|
||||
Where("scr.ChannelId = sc.ChannelId").
|
||||
Where(sq.Eq{"scr.ChannelId": channelId})
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user