MM-52600: [Shared Channels] Shared channels do not sync channel membership (#30976)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
0082e3e94d
Коммит
fa1c77d9b0
@@ -2070,22 +2070,34 @@ func (s SqlChannelStore) PatchMultipleMembersNotifyProps(members []*model.Channe
|
||||
return updated, nil
|
||||
}
|
||||
|
||||
func (s SqlChannelStore) GetMembers(channelID string, offset, limit int) (model.ChannelMembers, error) {
|
||||
sql, args, err := s.channelMembersForTeamWithSchemeSelectQuery.
|
||||
func (s SqlChannelStore) GetMembers(opts model.ChannelMembersGetOptions) (model.ChannelMembers, error) {
|
||||
query := s.channelMembersForTeamWithSchemeSelectQuery.
|
||||
Where(sq.Eq{
|
||||
"ChannelId": channelID,
|
||||
}).
|
||||
Limit(uint64(limit)).
|
||||
Offset(uint64(offset)).
|
||||
ToSql()
|
||||
"ChannelId": opts.ChannelID,
|
||||
})
|
||||
|
||||
if opts.UpdatedAfter > 0 {
|
||||
query = query.Where(sq.Gt{"ChannelMembers.LastUpdateAt": opts.UpdatedAfter})
|
||||
query = query.OrderBy("ChannelMembers.LastUpdateAt")
|
||||
}
|
||||
|
||||
if opts.Limit > 0 {
|
||||
query = query.Limit(uint64(opts.Limit))
|
||||
}
|
||||
|
||||
if opts.Offset > 0 {
|
||||
query = query.Offset(uint64(opts.Offset))
|
||||
}
|
||||
|
||||
sql, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetMember_ToSql ChannelID=%s", channelID)
|
||||
return nil, errors.Wrapf(err, "GetMember_ToSql ChannelID=%s", opts.ChannelID)
|
||||
}
|
||||
|
||||
dbMembers := channelMemberWithSchemeRolesList{}
|
||||
err = s.GetReplica().Select(&dbMembers, sql, args...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to get ChannelMembers with channelId=%s", channelID)
|
||||
return nil, errors.Wrapf(err, "failed to get ChannelMembers with channelId=%s", opts.ChannelID)
|
||||
}
|
||||
|
||||
return dbMembers.ToModel(), nil
|
||||
|
||||
@@ -417,6 +417,7 @@ func sharedChannelRemoteFields(prefix string) []string {
|
||||
"COALESCE(" + prefix + "LastPostCreateID,'') AS LastPostCreateID",
|
||||
prefix + "LastPostUpdateAt",
|
||||
"COALESCE(" + prefix + "LastPostId,'') AS LastPostUpdateID",
|
||||
prefix + "LastMembersSyncAt",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,6 +709,7 @@ func sharedChannelUserFields(prefix string) []string {
|
||||
prefix + "RemoteId",
|
||||
prefix + "CreateAt",
|
||||
prefix + "LastSyncAt",
|
||||
prefix + "LastMembershipSyncAt",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -720,7 +722,7 @@ func (s SqlSharedChannelStore) SaveUser(scUser *model.SharedChannelUser) (*model
|
||||
|
||||
query, args, err := s.getQueryBuilder().Insert("SharedChannelUsers").
|
||||
Columns(sharedChannelUserFields("")...).
|
||||
Values(scUser.Id, scUser.UserId, scUser.ChannelId, scUser.RemoteId, scUser.CreateAt, scUser.LastSyncAt).
|
||||
Values(scUser.Id, scUser.UserId, scUser.ChannelId, scUser.RemoteId, scUser.CreateAt, scUser.LastSyncAt, scUser.LastMembershipSyncAt).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "savesharedchanneluser_tosql")
|
||||
@@ -853,6 +855,25 @@ func (s SqlSharedChannelStore) UpdateUserLastSyncAt(userID string, channelID str
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateUserLastMembershipSyncAt updates the LastMembershipSyncAt timestamp for the specified SharedChannelUser using the provided sync time.
|
||||
func (s SqlSharedChannelStore) UpdateUserLastMembershipSyncAt(userID string, channelID string, remoteID string, syncTime int64) error {
|
||||
query := s.getQueryBuilder().
|
||||
Update("SharedChannelUsers AS scu").
|
||||
Set("LastMembershipSyncAt", sq.Expr("GREATEST(scu.LastMembershipSyncAt, ?)", syncTime)).
|
||||
Where(sq.Eq{
|
||||
"scu.UserId": userID,
|
||||
"scu.ChannelId": channelID,
|
||||
"scu.RemoteId": remoteID,
|
||||
})
|
||||
|
||||
_, err := s.GetMaster().ExecBuilder(query)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update LastMembershipSyncAt for SharedChannelUser with userId=%s, channelId=%s, remoteId=%s: %w",
|
||||
userID, channelID, remoteID, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func sharedChannelAttachementFields(prefix string) []string {
|
||||
if prefix != "" && !strings.HasSuffix(prefix, ".") {
|
||||
prefix = prefix + "."
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"github.com/mattermost/mattermost/server/public/model"
|
||||
sq "github.com/mattermost/squirrel"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// UpdateRemoteMembershipCursor updates the LastMembersSyncAt timestamp for the specified SharedChannelRemote,
|
||||
// but only if the new timestamp is greater than the current value.
|
||||
func (s SqlSharedChannelStore) UpdateRemoteMembershipCursor(id string, syncTime int64) error {
|
||||
query := s.getQueryBuilder().
|
||||
Update("SharedChannelRemotes")
|
||||
|
||||
query = query.Set("LastMembersSyncAt", sq.Expr("GREATEST(LastMembersSyncAt, ?)", syncTime))
|
||||
|
||||
query = query.Where(sq.Eq{"Id": id})
|
||||
|
||||
result, err := s.GetMaster().ExecBuilder(query)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to update membership cursor for SharedChannelRemote")
|
||||
}
|
||||
|
||||
count, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to determine rows affected")
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
return fmt.Errorf("id not found: %s", id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetUserChanges gets all SharedChannelUser changes for a given user, channel after a specific time.
|
||||
// This is used to detect if there are conflicting membership changes.
|
||||
func (s SqlSharedChannelStore) GetUserChanges(userID string, channelID string, afterTime int64) ([]*model.SharedChannelUser, error) {
|
||||
squery, args, err := s.getQueryBuilder().
|
||||
Select(sharedChannelUserFields("")...).
|
||||
From("SharedChannelUsers").
|
||||
Where(sq.Eq{"SharedChannelUsers.UserId": userID}).
|
||||
Where(sq.Eq{"SharedChannelUsers.ChannelId": channelID}).
|
||||
Where(sq.Gt{"SharedChannelUsers.LastSyncAt": afterTime}).
|
||||
ToSql()
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "getsharedchanneluserchanges_tosql")
|
||||
}
|
||||
|
||||
users := []*model.SharedChannelUser{}
|
||||
if err := s.GetReplica().Select(&users, squery, args...); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return make([]*model.SharedChannelUser, 0), nil
|
||||
}
|
||||
return nil, errors.Wrapf(err, "failed to find shared channel user changes with UserId=%s, ChannelId=%s, afterTime=%d",
|
||||
userID, channelID, afterTime)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
Ссылка в новой задаче
Block a user