MM-35133 trigger sync user immediately after change (#17579)
- ensure changes to user profile sync immediately - refactor sync send
Этот коммит содержится в:
@@ -5394,7 +5394,7 @@ func (s *OpenTracingLayerPostStore) GetPostsSince(options model.GetPostsSinceOpt
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, allowFromCache bool) ([]*model.Post, error) {
|
||||
func (s *OpenTracingLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, cursor model.GetPostsSinceForSyncCursor, limit int) ([]*model.Post, model.GetPostsSinceForSyncCursor, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "PostStore.GetPostsSinceForSync")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -5403,13 +5403,13 @@ func (s *OpenTracingLayerPostStore) GetPostsSinceForSync(options model.GetPostsS
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.PostStore.GetPostsSinceForSync(options, allowFromCache)
|
||||
result, resultVar1, err := s.PostStore.GetPostsSinceForSync(options, cursor, limit)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
return result, resultVar1, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerPostStore) GetRepliesForExport(parentID string) ([]*model.ReplyForExport, error) {
|
||||
@@ -7274,16 +7274,52 @@ func (s *OpenTracingLayerSharedChannelStore) GetRemotesStatus(channelId string)
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
func (s *OpenTracingLayerSharedChannelStore) GetSingleUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.GetUser")
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.GetSingleUser")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.SharedChannelStore.GetUser(userID, channelID, remoteID)
|
||||
result, err := s.SharedChannelStore.GetSingleUser(userID, channelID, remoteID)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSharedChannelStore) GetUsersForSync(filter model.GetUsersForSyncFilter) ([]*model.User, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.GetUsersForSync")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.SharedChannelStore.GetUsersForSync(filter)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
}
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSharedChannelStore) GetUsersForUser(userID string) ([]*model.SharedChannelUser, error) {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.GetUsersForUser")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
result, err := s.SharedChannelStore.GetUsersForUser(userID)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
@@ -7454,16 +7490,16 @@ func (s *OpenTracingLayerSharedChannelStore) UpdateRemote(remote *model.SharedCh
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTime int64) error {
|
||||
func (s *OpenTracingLayerSharedChannelStore) UpdateRemoteCursor(id string, cursor model.GetPostsSinceForSyncCursor) error {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.UpdateRemoteNextSyncAt")
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.UpdateRemoteCursor")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
defer func() {
|
||||
s.Root.Store.SetContext(origCtx)
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
err := s.SharedChannelStore.UpdateRemoteNextSyncAt(id, syncTime)
|
||||
err := s.SharedChannelStore.UpdateRemoteCursor(id, cursor)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
@@ -7472,7 +7508,7 @@ func (s *OpenTracingLayerSharedChannelStore) UpdateRemoteNextSyncAt(id string, s
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *OpenTracingLayerSharedChannelStore) UpdateUserLastSyncAt(id string, syncTime int64) error {
|
||||
func (s *OpenTracingLayerSharedChannelStore) UpdateUserLastSyncAt(userID string, channelID string, remoteID string) error {
|
||||
origCtx := s.Root.Store.Context()
|
||||
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "SharedChannelStore.UpdateUserLastSyncAt")
|
||||
s.Root.Store.SetContext(newCtx)
|
||||
@@ -7481,7 +7517,7 @@ func (s *OpenTracingLayerSharedChannelStore) UpdateUserLastSyncAt(id string, syn
|
||||
}()
|
||||
|
||||
defer span.Finish()
|
||||
err := s.SharedChannelStore.UpdateUserLastSyncAt(id, syncTime)
|
||||
err := s.SharedChannelStore.UpdateUserLastSyncAt(userID, channelID, remoteID)
|
||||
if err != nil {
|
||||
span.LogFields(spanlog.Error(err))
|
||||
ext.Error.Set(span, true)
|
||||
|
||||
@@ -5824,21 +5824,21 @@ func (s *RetryLayerPostStore) GetPostsSince(options model.GetPostsSinceOptions,
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, allowFromCache bool) ([]*model.Post, error) {
|
||||
func (s *RetryLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, cursor model.GetPostsSinceForSyncCursor, limit int) ([]*model.Post, model.GetPostsSinceForSyncCursor, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.PostStore.GetPostsSinceForSync(options, allowFromCache)
|
||||
result, resultVar1, err := s.PostStore.GetPostsSinceForSync(options, cursor, limit)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
return result, resultVar1, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
return result, resultVar1, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
return result, resultVar1, err
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7896,11 +7896,51 @@ func (s *RetryLayerSharedChannelStore) GetRemotesStatus(channelId string) ([]*mo
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
func (s *RetryLayerSharedChannelStore) GetSingleUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.SharedChannelStore.GetUser(userID, channelID, remoteID)
|
||||
result, err := s.SharedChannelStore.GetSingleUser(userID, channelID, remoteID)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSharedChannelStore) GetUsersForSync(filter model.GetUsersForSyncFilter) ([]*model.User, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.SharedChannelStore.GetUsersForSync(filter)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
if !isRepeatableError(err) {
|
||||
return result, err
|
||||
}
|
||||
tries++
|
||||
if tries >= 3 {
|
||||
err = errors.Wrap(err, "giving up after 3 consecutive repeatable transaction failures")
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSharedChannelStore) GetUsersForUser(userID string) ([]*model.SharedChannelUser, error) {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
result, err := s.SharedChannelStore.GetUsersForUser(userID)
|
||||
if err == nil {
|
||||
return result, nil
|
||||
}
|
||||
@@ -8096,11 +8136,11 @@ func (s *RetryLayerSharedChannelStore) UpdateRemote(remote *model.SharedChannelR
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTime int64) error {
|
||||
func (s *RetryLayerSharedChannelStore) UpdateRemoteCursor(id string, cursor model.GetPostsSinceForSyncCursor) error {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
err := s.SharedChannelStore.UpdateRemoteNextSyncAt(id, syncTime)
|
||||
err := s.SharedChannelStore.UpdateRemoteCursor(id, cursor)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
@@ -8116,11 +8156,11 @@ func (s *RetryLayerSharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTim
|
||||
|
||||
}
|
||||
|
||||
func (s *RetryLayerSharedChannelStore) UpdateUserLastSyncAt(id string, syncTime int64) error {
|
||||
func (s *RetryLayerSharedChannelStore) UpdateUserLastSyncAt(userID string, channelID string, remoteID string) error {
|
||||
|
||||
tries := 0
|
||||
for {
|
||||
err := s.SharedChannelStore.UpdateUserLastSyncAt(id, syncTime)
|
||||
err := s.SharedChannelStore.UpdateUserLastSyncAt(userID, channelID, remoteID)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1004,26 +1004,16 @@ func (s *SqlPostStore) HasAutoResponsePostByUserSince(options model.GetPostsSinc
|
||||
return exist > 0, nil
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, _ /* allowFromCache */ bool) ([]*model.Post, error) {
|
||||
if options.Limit < 0 || options.Limit > 1000 {
|
||||
return nil, store.NewErrInvalidInput("Post", "<options.Limit>", options.Limit)
|
||||
}
|
||||
|
||||
order := " ASC"
|
||||
if options.SortDescending {
|
||||
order = " DESC"
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, cursor model.GetPostsSinceForSyncCursor, limit int) ([]*model.Post, model.GetPostsSinceForSyncCursor, error) {
|
||||
query := s.getQueryBuilder().
|
||||
Select("*").
|
||||
From("Posts").
|
||||
Where(sq.GtOrEq{"UpdateAt": options.Since}).
|
||||
Where(sq.Eq{"ChannelId": options.ChannelId}).
|
||||
Limit(uint64(options.Limit)).
|
||||
OrderBy("CreateAt"+order, "DeleteAt", "Id")
|
||||
Where(sq.Or{sq.Gt{"UpdateAt": cursor.LastPostUpdateAt}, sq.And{sq.Eq{"UpdateAt": cursor.LastPostUpdateAt}, sq.Gt{"Id": cursor.LastPostId}}}).
|
||||
OrderBy("UpdateAt", "Id").
|
||||
Limit(uint64(limit))
|
||||
|
||||
if options.Until > 0 {
|
||||
query = query.Where(sq.LtOrEq{"UpdateAt": options.Until})
|
||||
if options.ChannelId != "" {
|
||||
query = query.Where(sq.Eq{"ChannelId": options.ChannelId})
|
||||
}
|
||||
|
||||
if !options.IncludeDeleted {
|
||||
@@ -1034,24 +1024,22 @@ func (s *SqlPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOp
|
||||
query = query.Where(sq.NotEq{"COALESCE(Posts.RemoteId,'')": options.ExcludeRemoteId})
|
||||
}
|
||||
|
||||
if options.Offset > 0 {
|
||||
query = query.Offset(uint64(options.Offset))
|
||||
}
|
||||
|
||||
queryString, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getpostssinceforsync_tosql")
|
||||
return nil, cursor, errors.Wrap(err, "getpostssinceforsync_tosql")
|
||||
}
|
||||
|
||||
var posts []*model.Post
|
||||
|
||||
_, err = s.GetReplica().Select(&posts, queryString, args...)
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to find Posts with channelId=%s", options.ChannelId)
|
||||
return nil, cursor, errors.Wrapf(err, "error getting Posts with channelId=%s", options.ChannelId)
|
||||
}
|
||||
|
||||
return posts, nil
|
||||
if len(posts) != 0 {
|
||||
cursor.LastPostUpdateAt = posts[len(posts)-1].UpdateAt
|
||||
cursor.LastPostId = posts[len(posts)-1].Id
|
||||
}
|
||||
return posts, cursor, nil
|
||||
}
|
||||
|
||||
func (s *SqlPostStore) GetPostsBefore(options model.GetPostsOptions) (*model.PostList, error) {
|
||||
|
||||
@@ -14,6 +14,10 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultGetUsersForSyncLimit = 100
|
||||
)
|
||||
|
||||
type SqlSharedChannelStore struct {
|
||||
*SqlStore
|
||||
}
|
||||
@@ -40,6 +44,7 @@ func newSqlSharedChannelStore(sqlStore *SqlStore) store.SharedChannelStore {
|
||||
tableSharedChannelRemotes.ColMap("ChannelId").SetMaxSize(26)
|
||||
tableSharedChannelRemotes.ColMap("CreatorId").SetMaxSize(26)
|
||||
tableSharedChannelRemotes.ColMap("RemoteId").SetMaxSize(26)
|
||||
tableSharedChannelRemotes.ColMap("LastPostId").SetMaxSize(26)
|
||||
tableSharedChannelRemotes.SetUniqueTogether("ChannelId", "RemoteId")
|
||||
|
||||
tableSharedChannelUsers := db.AddTableWithName(model.SharedChannelUser{}, "SharedChannelUsers").SetKeys(false, "Id")
|
||||
@@ -467,20 +472,21 @@ func (s SqlSharedChannelStore) GetRemoteForUser(remoteId string, userId string)
|
||||
return &rc, nil
|
||||
}
|
||||
|
||||
// UpdateRemoteNextSyncAt updates the NextSyncAt timestamp for the specified SharedChannelRemote.
|
||||
func (s SqlSharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTime int64) error {
|
||||
// UpdateRemoteCursor updates the LastPostUpdateAt timestamp and LastPostId for the specified SharedChannelRemote.
|
||||
func (s SqlSharedChannelStore) UpdateRemoteCursor(id string, cursor model.GetPostsSinceForSyncCursor) error {
|
||||
squery, args, err := s.getQueryBuilder().
|
||||
Update("SharedChannelRemotes").
|
||||
Set("NextSyncAt", syncTime).
|
||||
Set("LastPostUpdateAt", cursor.LastPostUpdateAt).
|
||||
Set("LastPostId", cursor.LastPostId).
|
||||
Where(sq.Eq{"Id": id}).
|
||||
ToSql()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "update_shared_channel_remote_next_sync_at_tosql")
|
||||
return errors.Wrap(err, "update_shared_channel_remote_cursor_tosql")
|
||||
}
|
||||
|
||||
result, err := s.GetMaster().Exec(squery, args...)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to update NextSyncAt for SharedChannelRemote")
|
||||
return errors.Wrap(err, "failed to update cursor for SharedChannelRemote")
|
||||
}
|
||||
|
||||
count, err := result.RowsAffected()
|
||||
@@ -556,8 +562,8 @@ func (s SqlSharedChannelStore) SaveUser(scUser *model.SharedChannelUser) (*model
|
||||
return scUser, nil
|
||||
}
|
||||
|
||||
// GetUser fetches a shared channel user based on user_id and remoteId.
|
||||
func (s SqlSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
// GetSingleUser fetches a shared channel user based on userID, channelID and remoteID.
|
||||
func (s SqlSharedChannelStore) GetSingleUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
var scu model.SharedChannelUser
|
||||
|
||||
squery, args, err := s.getQueryBuilder().
|
||||
@@ -569,7 +575,7 @@ func (s SqlSharedChannelStore) GetUser(userID string, channelID string, remoteID
|
||||
ToSql()
|
||||
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "getsharedchanneluser_tosql")
|
||||
return nil, errors.Wrapf(err, "getsharedchannelsingleuser_tosql")
|
||||
}
|
||||
|
||||
if err := s.GetReplica().SelectOne(&scu, squery, args...); err != nil {
|
||||
@@ -581,20 +587,104 @@ func (s SqlSharedChannelStore) GetUser(userID string, channelID string, remoteID
|
||||
return &scu, nil
|
||||
}
|
||||
|
||||
// UpdateUserLastSyncAt updates the LastSyncAt timestamp for the specified SharedChannelUser.
|
||||
func (s SqlSharedChannelStore) UpdateUserLastSyncAt(id string, syncTime int64) error {
|
||||
// GetUsersForUser fetches all shared channel user records based on userID.
|
||||
func (s SqlSharedChannelStore) GetUsersForUser(userID string) ([]*model.SharedChannelUser, error) {
|
||||
squery, args, err := s.getQueryBuilder().
|
||||
Update("SharedChannelUsers").
|
||||
Set("LastSyncAt", syncTime).
|
||||
Where(sq.Eq{"Id": id}).
|
||||
Select("*").
|
||||
From("SharedChannelUsers").
|
||||
Where(sq.Eq{"SharedChannelUsers.UserId": userID}).
|
||||
ToSql()
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "update_shared_channel_user_last_sync_at_tosql")
|
||||
return nil, errors.Wrapf(err, "getsharedchanneluser_tosql")
|
||||
}
|
||||
|
||||
result, err := s.GetMaster().Exec(squery, args...)
|
||||
var 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 with UserId=%s", userID)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// GetUsersForSync fetches all shared channel users that need to be synchronized, meaning their
|
||||
// `SharedChannelUsers.LastSyncAt` is less than or equal to `User.UpdateAt`.
|
||||
func (s SqlSharedChannelStore) GetUsersForSync(filter model.GetUsersForSyncFilter) ([]*model.User, error) {
|
||||
if filter.Limit <= 0 {
|
||||
filter.Limit = DefaultGetUsersForSyncLimit
|
||||
}
|
||||
|
||||
query := s.getQueryBuilder().
|
||||
Select("u.*").
|
||||
Distinct().
|
||||
From("Users AS u").
|
||||
Join("SharedChannelUsers AS scu ON u.Id = scu.UserId").
|
||||
OrderBy("u.Id").
|
||||
Limit(filter.Limit)
|
||||
|
||||
if filter.CheckProfileImage {
|
||||
query = query.Where("scu.LastSyncAt < u.LastPictureUpdate")
|
||||
} else {
|
||||
query = query.Where("scu.LastSyncAt < u.UpdateAt")
|
||||
}
|
||||
|
||||
if filter.ChannelID != "" {
|
||||
query = query.Where(sq.Eq{"scu.ChannelId": filter.ChannelID})
|
||||
}
|
||||
|
||||
sqlQuery, args, err := query.ToSql()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to update LastSycnAt for SharedChannelUser")
|
||||
return nil, errors.Wrapf(err, "getsharedchannelusersforsync_tosql")
|
||||
}
|
||||
|
||||
var users []*model.User
|
||||
if _, err := s.GetReplica().Select(&users, sqlQuery, args...); err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
return make([]*model.User, 0), nil
|
||||
}
|
||||
return nil, errors.Wrapf(err, "failed to fetch shared channel users with ChannelId=%s",
|
||||
filter.ChannelID)
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// UpdateUserLastSyncAt updates the LastSyncAt timestamp for the specified SharedChannelUser.
|
||||
func (s SqlSharedChannelStore) UpdateUserLastSyncAt(userID string, channelID string, remoteID string) error {
|
||||
args := map[string]interface{}{"UserId": userID, "ChannelId": channelID, "RemoteId": remoteID}
|
||||
|
||||
var query string
|
||||
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
|
||||
query = `
|
||||
UPDATE
|
||||
SharedChannelUsers AS scu
|
||||
SET
|
||||
LastSyncAt = GREATEST(Users.UpdateAt, Users.LastPictureUpdate)
|
||||
FROM
|
||||
Users
|
||||
WHERE
|
||||
Users.Id = scu.UserId AND scu.UserId = :UserId AND scu.ChannelId = :ChannelId AND scu.RemoteId = :RemoteId
|
||||
`
|
||||
} else if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
|
||||
query = `
|
||||
UPDATE
|
||||
SharedChannelUsers AS scu
|
||||
INNER JOIN
|
||||
Users ON scu.UserId = Users.Id
|
||||
SET
|
||||
LastSyncAt = GREATEST(Users.UpdateAt, Users.LastPictureUpdate)
|
||||
WHERE
|
||||
scu.UserId = :UserId AND scu.ChannelId = :ChannelId AND scu.RemoteId = :RemoteId
|
||||
`
|
||||
} else {
|
||||
return errors.New("unsupported DB driver " + s.DriverName())
|
||||
}
|
||||
|
||||
result, err := s.GetMaster().Exec(query, args)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update LastSyncAt for SharedChannelUser with userId=%s, channelId=%s, remoteId=%s: %w",
|
||||
userID, channelID, remoteID, err)
|
||||
}
|
||||
|
||||
count, err := result.RowsAffected()
|
||||
@@ -602,7 +692,7 @@ func (s SqlSharedChannelStore) UpdateUserLastSyncAt(id string, syncTime int64) e
|
||||
return errors.Wrap(err, "failed to determine rows affected")
|
||||
}
|
||||
if count == 0 {
|
||||
return fmt.Errorf("id not found: %s", id)
|
||||
return fmt.Errorf("SharedChannelUser not found: userId=%s, channelId=%s, remoteId=%s", userID, channelID, remoteID)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1067,6 +1067,8 @@ func upgradeDatabaseToVersion536(sqlStore *SqlStore) {
|
||||
//if shouldPerformUpgrade(sqlStore, Version5350, Version5360) {
|
||||
|
||||
sqlStore.CreateColumnIfNotExists("SharedChannelUsers", "ChannelId", "VARCHAR(26)", "VARCHAR(26)", "")
|
||||
sqlStore.CreateColumnIfNotExists("SharedChannelRemotes", "LastPostUpdateAt", "bigint", "bigint", "0")
|
||||
sqlStore.CreateColumnIfNotExists("SharedChannelRemotes", "LastPostId", "VARCHAR(26)", "VARCHAR(26)", "")
|
||||
|
||||
// timed dnd status support
|
||||
sqlStore.CreateColumnIfNotExistsNoDefault("Status", "DNDEndTime", "BIGINT", "BIGINT")
|
||||
|
||||
@@ -341,7 +341,7 @@ type PostStore interface {
|
||||
SearchPostsInTeamForUser(paramsList []*model.SearchParams, userID, teamID string, page, perPage int) (*model.PostSearchResults, error)
|
||||
GetOldestEntityCreationTime() (int64, error)
|
||||
HasAutoResponsePostByUserSince(options model.GetPostsSinceOptions, userId string) (bool, error)
|
||||
GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, allowFromCache bool) ([]*model.Post, error)
|
||||
GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, cursor model.GetPostsSinceForSyncCursor, limit int) ([]*model.Post, model.GetPostsSinceForSyncCursor, error)
|
||||
}
|
||||
|
||||
type UserStore interface {
|
||||
@@ -853,13 +853,15 @@ type SharedChannelStore interface {
|
||||
GetRemoteForUser(remoteId string, userId string) (*model.RemoteCluster, error)
|
||||
GetRemoteByIds(channelId string, remoteId string) (*model.SharedChannelRemote, error)
|
||||
GetRemotes(opts model.SharedChannelRemoteFilterOpts) ([]*model.SharedChannelRemote, error)
|
||||
UpdateRemoteNextSyncAt(id string, syncTime int64) error
|
||||
UpdateRemoteCursor(id string, cursor model.GetPostsSinceForSyncCursor) error
|
||||
DeleteRemote(remoteId string) (bool, error)
|
||||
GetRemotesStatus(channelId string) ([]*model.SharedChannelRemoteStatus, error)
|
||||
|
||||
SaveUser(remote *model.SharedChannelUser) (*model.SharedChannelUser, error)
|
||||
GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error)
|
||||
UpdateUserLastSyncAt(id string, syncTime int64) error
|
||||
GetSingleUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error)
|
||||
GetUsersForUser(userID string) ([]*model.SharedChannelUser, error)
|
||||
GetUsersForSync(filter model.GetUsersForSyncFilter) ([]*model.User, error)
|
||||
UpdateUserLastSyncAt(userID string, channelID string, remoteID string) error
|
||||
|
||||
SaveAttachment(remote *model.SharedChannelAttachment) (*model.SharedChannelAttachment, error)
|
||||
UpsertAttachment(remote *model.SharedChannelAttachment) (string, error)
|
||||
|
||||
@@ -538,27 +538,34 @@ func (_m *PostStore) GetPostsSince(options model.GetPostsSinceOptions, allowFrom
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetPostsSinceForSync provides a mock function with given fields: options, allowFromCache
|
||||
func (_m *PostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, allowFromCache bool) ([]*model.Post, error) {
|
||||
ret := _m.Called(options, allowFromCache)
|
||||
// GetPostsSinceForSync provides a mock function with given fields: options, cursor, limit
|
||||
func (_m *PostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, cursor model.GetPostsSinceForSyncCursor, limit int) ([]*model.Post, model.GetPostsSinceForSyncCursor, error) {
|
||||
ret := _m.Called(options, cursor, limit)
|
||||
|
||||
var r0 []*model.Post
|
||||
if rf, ok := ret.Get(0).(func(model.GetPostsSinceForSyncOptions, bool) []*model.Post); ok {
|
||||
r0 = rf(options, allowFromCache)
|
||||
if rf, ok := ret.Get(0).(func(model.GetPostsSinceForSyncOptions, model.GetPostsSinceForSyncCursor, int) []*model.Post); ok {
|
||||
r0 = rf(options, cursor, limit)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.Post)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(model.GetPostsSinceForSyncOptions, bool) error); ok {
|
||||
r1 = rf(options, allowFromCache)
|
||||
var r1 model.GetPostsSinceForSyncCursor
|
||||
if rf, ok := ret.Get(1).(func(model.GetPostsSinceForSyncOptions, model.GetPostsSinceForSyncCursor, int) model.GetPostsSinceForSyncCursor); ok {
|
||||
r1 = rf(options, cursor, limit)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
r1 = ret.Get(1).(model.GetPostsSinceForSyncCursor)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
var r2 error
|
||||
if rf, ok := ret.Get(2).(func(model.GetPostsSinceForSyncOptions, model.GetPostsSinceForSyncCursor, int) error); ok {
|
||||
r2 = rf(options, cursor, limit)
|
||||
} else {
|
||||
r2 = ret.Error(2)
|
||||
}
|
||||
|
||||
return r0, r1, r2
|
||||
}
|
||||
|
||||
// GetRepliesForExport provides a mock function with given fields: parentID
|
||||
|
||||
@@ -261,8 +261,8 @@ func (_m *SharedChannelStore) GetRemotesStatus(channelId string) ([]*model.Share
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUser provides a mock function with given fields: userID, channelID, remoteID
|
||||
func (_m *SharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
// GetSingleUser provides a mock function with given fields: userID, channelID, remoteID
|
||||
func (_m *SharedChannelStore) GetSingleUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
ret := _m.Called(userID, channelID, remoteID)
|
||||
|
||||
var r0 *model.SharedChannelUser
|
||||
@@ -284,6 +284,52 @@ func (_m *SharedChannelStore) GetUser(userID string, channelID string, remoteID
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUsersForSync provides a mock function with given fields: filter
|
||||
func (_m *SharedChannelStore) GetUsersForSync(filter model.GetUsersForSyncFilter) ([]*model.User, error) {
|
||||
ret := _m.Called(filter)
|
||||
|
||||
var r0 []*model.User
|
||||
if rf, ok := ret.Get(0).(func(model.GetUsersForSyncFilter) []*model.User); ok {
|
||||
r0 = rf(filter)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.User)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(model.GetUsersForSyncFilter) error); ok {
|
||||
r1 = rf(filter)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// GetUsersForUser provides a mock function with given fields: userID
|
||||
func (_m *SharedChannelStore) GetUsersForUser(userID string) ([]*model.SharedChannelUser, error) {
|
||||
ret := _m.Called(userID)
|
||||
|
||||
var r0 []*model.SharedChannelUser
|
||||
if rf, ok := ret.Get(0).(func(string) []*model.SharedChannelUser); ok {
|
||||
r0 = rf(userID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]*model.SharedChannelUser)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(userID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// HasChannel provides a mock function with given fields: channelID
|
||||
func (_m *SharedChannelStore) HasChannel(channelID string) (bool, error) {
|
||||
ret := _m.Called(channelID)
|
||||
@@ -478,13 +524,13 @@ func (_m *SharedChannelStore) UpdateRemote(remote *model.SharedChannelRemote) (*
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UpdateRemoteNextSyncAt provides a mock function with given fields: id, syncTime
|
||||
func (_m *SharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTime int64) error {
|
||||
ret := _m.Called(id, syncTime)
|
||||
// UpdateRemoteCursor provides a mock function with given fields: id, cursor
|
||||
func (_m *SharedChannelStore) UpdateRemoteCursor(id string, cursor model.GetPostsSinceForSyncCursor) error {
|
||||
ret := _m.Called(id, cursor)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, int64) error); ok {
|
||||
r0 = rf(id, syncTime)
|
||||
if rf, ok := ret.Get(0).(func(string, model.GetPostsSinceForSyncCursor) error); ok {
|
||||
r0 = rf(id, cursor)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
@@ -492,13 +538,13 @@ func (_m *SharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTime int64)
|
||||
return r0
|
||||
}
|
||||
|
||||
// UpdateUserLastSyncAt provides a mock function with given fields: id, syncTime
|
||||
func (_m *SharedChannelStore) UpdateUserLastSyncAt(id string, syncTime int64) error {
|
||||
ret := _m.Called(id, syncTime)
|
||||
// UpdateUserLastSyncAt provides a mock function with given fields: userID, channelID, remoteID
|
||||
func (_m *SharedChannelStore) UpdateUserLastSyncAt(userID string, channelID string, remoteID string) error {
|
||||
ret := _m.Called(userID, channelID, remoteID)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, int64) error); ok {
|
||||
r0 = rf(id, syncTime)
|
||||
if rf, ok := ret.Get(0).(func(string, string, string) error); ok {
|
||||
r0 = rf(userID, channelID, remoteID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ func TestPostStore(t *testing.T, ss store.Store, s SqlStore) {
|
||||
t.Run("GetDirectPostParentsForExportAfterBatched", func(t *testing.T) { testPostStoreGetDirectPostParentsForExportAfterBatched(t, ss, s) })
|
||||
t.Run("GetForThread", func(t *testing.T) { testPostStoreGetForThread(t, ss) })
|
||||
t.Run("HasAutoResponsePostByUserSince", func(t *testing.T) { testHasAutoResponsePostByUserSince(t, ss) })
|
||||
t.Run("GetPostsSinceForSync", func(t *testing.T) { testGetPostsSinceForSync(t, ss, s) })
|
||||
}
|
||||
|
||||
func testPostStoreSave(t *testing.T, ss store.Store) {
|
||||
@@ -3013,3 +3014,118 @@ func testHasAutoResponsePostByUserSince(t *testing.T, ss store.Store) {
|
||||
assert.False(t, exists)
|
||||
})
|
||||
}
|
||||
|
||||
func testGetPostsSinceForSync(t *testing.T, ss store.Store, s SqlStore) {
|
||||
// create some posts.
|
||||
channelID := model.NewId()
|
||||
remoteID := model.NewString(model.NewId())
|
||||
first := model.GetMillis()
|
||||
|
||||
data := []*model.Post{
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 0"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 1"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 2"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 3", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 4", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 5", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 6", RemoteId: remoteID},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 7"},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 8", DeleteAt: model.GetMillis()},
|
||||
{Id: model.NewId(), ChannelId: channelID, UserId: model.NewId(), Message: "test post 9", DeleteAt: model.GetMillis()},
|
||||
}
|
||||
|
||||
for i, p := range data {
|
||||
p.UpdateAt = first + (int64(i) * 300000)
|
||||
if p.RemoteId == nil {
|
||||
p.RemoteId = model.NewString(model.NewId())
|
||||
}
|
||||
_, err := ss.Post().Save(p)
|
||||
require.NoError(t, err, "couldn't save post")
|
||||
}
|
||||
|
||||
t.Run("Invalid channel id", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: model.NewId(),
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts, cursorOut, err := ss.Post().GetPostsSinceForSync(opt, cursor, 100)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, posts, "should return zero posts")
|
||||
require.Equal(t, cursor, cursorOut)
|
||||
})
|
||||
|
||||
t.Run("Get by channel, exclude remotes, exclude deleted", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
ExcludeRemoteId: *remoteID,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 100)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data[0:3], data[7]), getPostIds(posts))
|
||||
})
|
||||
|
||||
t.Run("Include deleted", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
IncludeDeleted: true,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 100)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data), getPostIds(posts))
|
||||
})
|
||||
|
||||
t.Run("Limit and cursor", func(t *testing.T) {
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts1, cursor, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts1, 5, "should get 5 posts")
|
||||
|
||||
posts2, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts2, 3, "should get 3 posts")
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data[0:8]), getPostIds(posts1, posts2...))
|
||||
})
|
||||
|
||||
t.Run("UpdateAt collisions", func(t *testing.T) {
|
||||
// this test requires all the UpdateAt timestamps to be the same.
|
||||
args := map[string]interface{}{"UpdateAt": model.GetMillis()}
|
||||
result, err := s.GetMaster().Exec("UPDATE Posts SET UpdateAt = :UpdateAt", args)
|
||||
require.NoError(t, err)
|
||||
rows, err := result.RowsAffected()
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, rows, int64(0))
|
||||
|
||||
opt := model.GetPostsSinceForSyncOptions{
|
||||
ChannelId: channelID,
|
||||
}
|
||||
cursor := model.GetPostsSinceForSyncCursor{}
|
||||
posts1, cursor, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts1, 5, "should get 5 posts")
|
||||
|
||||
posts2, _, err := ss.Post().GetPostsSinceForSync(opt, cursor, 5)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, posts2, 3, "should get 3 posts")
|
||||
|
||||
require.ElementsMatch(t, getPostIds(data[0:8]), getPostIds(posts1, posts2...))
|
||||
})
|
||||
}
|
||||
|
||||
func getPostIds(posts []*model.Post, morePosts ...*model.Post) []string {
|
||||
ids := make([]string, 0, len(posts)+len(morePosts))
|
||||
for _, p := range posts {
|
||||
ids = append(ids, p.Id)
|
||||
}
|
||||
for _, p := range morePosts {
|
||||
ids = append(ids, p.Id)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
@@ -30,11 +30,13 @@ func TestSharedChannelStore(t *testing.T, ss store.Store, s SqlStore) {
|
||||
t.Run("GetSharedChannelRemotes", func(t *testing.T) { testGetSharedChannelRemotes(t, ss) })
|
||||
t.Run("HasRemote", func(t *testing.T) { testHasRemote(t, ss) })
|
||||
t.Run("GetRemoteForUser", func(t *testing.T) { testGetRemoteForUser(t, ss) })
|
||||
t.Run("UpdateSharedChannelRemoteNextSyncAt", func(t *testing.T) { testUpdateSharedChannelRemoteNextSyncAt(t, ss) })
|
||||
t.Run("UpdateSharedChannelRemoteNextSyncAt", func(t *testing.T) { testUpdateSharedChannelRemoteCursor(t, ss) })
|
||||
t.Run("DeleteSharedChannelRemote", func(t *testing.T) { testDeleteSharedChannelRemote(t, ss) })
|
||||
|
||||
t.Run("SaveSharedChannelUser", func(t *testing.T) { testSaveSharedChannelUser(t, ss) })
|
||||
t.Run("GetSharedChannelSingleUser", func(t *testing.T) { testGetSingleSharedChannelUser(t, ss) })
|
||||
t.Run("GetSharedChannelUser", func(t *testing.T) { testGetSharedChannelUser(t, ss) })
|
||||
t.Run("GetSharedChannelUsersForSync", func(t *testing.T) { testGetSharedChannelUsersForSync(t, ss) })
|
||||
t.Run("UpdateSharedChannelUserLastSyncAt", func(t *testing.T) { testUpdateSharedChannelUserLastSyncAt(t, ss) })
|
||||
|
||||
t.Run("SaveSharedChannelAttachment", func(t *testing.T) { testSaveSharedChannelAttachment(t, ss) })
|
||||
@@ -714,7 +716,7 @@ func testGetRemoteForUser(t *testing.T, ss store.Store) {
|
||||
})
|
||||
}
|
||||
|
||||
func testUpdateSharedChannelRemoteNextSyncAt(t *testing.T, ss store.Store) {
|
||||
func testUpdateSharedChannelRemoteCursor(t *testing.T, ss store.Store) {
|
||||
channel, err := createTestChannel(ss, "test_remote_update_next_sync_at")
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -728,18 +730,25 @@ func testUpdateSharedChannelRemoteNextSyncAt(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, err, "couldn't save remote", err)
|
||||
|
||||
future := model.GetMillis() + 3600000 // 1 hour in the future
|
||||
postID := model.NewId()
|
||||
|
||||
cursor := model.GetPostsSinceForSyncCursor{
|
||||
LastPostUpdateAt: future,
|
||||
LastPostId: postID,
|
||||
}
|
||||
|
||||
t.Run("Update NextSyncAt for remote", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateRemoteNextSyncAt(remoteSaved.Id, future)
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(remoteSaved.Id, cursor)
|
||||
require.NoError(t, err, "update NextSyncAt should not error", err)
|
||||
|
||||
r, err := ss.SharedChannel().GetRemote(remoteSaved.Id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, future, r.NextSyncAt)
|
||||
require.Equal(t, future, r.LastPostUpdateAt)
|
||||
require.Equal(t, postID, r.LastPostId)
|
||||
})
|
||||
|
||||
t.Run("Update NextSyncAt for non-existent shared channel remote", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateRemoteNextSyncAt(model.NewId(), future)
|
||||
err := ss.SharedChannel().UpdateRemoteCursor(model.NewId(), cursor)
|
||||
require.Error(t, err, "update non-existent remote should error", err)
|
||||
})
|
||||
}
|
||||
@@ -862,7 +871,7 @@ func testSaveSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
})
|
||||
}
|
||||
|
||||
func testGetSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
func testGetSingleSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
scUser := &model.SharedChannelUser{
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
@@ -873,7 +882,7 @@ func testGetSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
require.NoError(t, err, "could not save user", err)
|
||||
|
||||
t.Run("Get existing shared channel user", func(t *testing.T) {
|
||||
r, err := ss.SharedChannel().GetUser(userSaved.UserId, userSaved.ChannelId, userSaved.RemoteId)
|
||||
r, err := ss.SharedChannel().GetSingleUser(userSaved.UserId, userSaved.ChannelId, userSaved.RemoteId)
|
||||
require.NoError(t, err, "couldn't get shared channel user", err)
|
||||
|
||||
require.Equal(t, userSaved.Id, r.Id)
|
||||
@@ -883,35 +892,174 @@ func testGetSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
})
|
||||
|
||||
t.Run("Get non-existent shared channel user", func(t *testing.T) {
|
||||
u, err := ss.SharedChannel().GetUser(model.NewId(), model.NewId(), model.NewId())
|
||||
u, err := ss.SharedChannel().GetSingleUser(model.NewId(), model.NewId(), model.NewId())
|
||||
require.Error(t, err)
|
||||
require.Nil(t, u)
|
||||
})
|
||||
}
|
||||
|
||||
func testUpdateSharedChannelUserLastSyncAt(t *testing.T, ss store.Store) {
|
||||
scUser := &model.SharedChannelUser{
|
||||
UserId: model.NewId(),
|
||||
RemoteId: model.NewId(),
|
||||
ChannelId: model.NewId(),
|
||||
func testGetSharedChannelUser(t *testing.T, ss store.Store) {
|
||||
userId := model.NewId()
|
||||
for i := 0; i < 10; i++ {
|
||||
scUser := &model.SharedChannelUser{
|
||||
UserId: userId,
|
||||
RemoteId: model.NewId(),
|
||||
ChannelId: model.NewId(),
|
||||
}
|
||||
_, err := ss.SharedChannel().SaveUser(scUser)
|
||||
require.NoError(t, err, "could not save user", err)
|
||||
}
|
||||
|
||||
userSaved, err := ss.SharedChannel().SaveUser(scUser)
|
||||
t.Run("Get existing shared channel user", func(t *testing.T) {
|
||||
scus, err := ss.SharedChannel().GetUsersForUser(userId)
|
||||
require.NoError(t, err, "couldn't get shared channel user", err)
|
||||
|
||||
require.Len(t, scus, 10, "should be 10 shared channel user records")
|
||||
require.Equal(t, userId, scus[0].UserId)
|
||||
})
|
||||
|
||||
t.Run("Get non-existent shared channel user", func(t *testing.T) {
|
||||
scus, err := ss.SharedChannel().GetUsersForUser(model.NewId())
|
||||
require.NoError(t, err, "should not error when not found")
|
||||
require.Empty(t, scus, "should be empty")
|
||||
})
|
||||
}
|
||||
|
||||
func testGetSharedChannelUsersForSync(t *testing.T, ss store.Store) {
|
||||
channelID := model.NewId()
|
||||
remoteID := model.NewId()
|
||||
earlier := model.GetMillis() - 300000
|
||||
later := model.GetMillis() + 300000
|
||||
|
||||
var users []*model.User
|
||||
for i := 0; i < 10; i++ { // need real users
|
||||
u := &model.User{
|
||||
Username: model.NewId(),
|
||||
Email: model.NewId() + "@example.com",
|
||||
LastPictureUpdate: model.GetMillis(),
|
||||
}
|
||||
u, err := ss.User().Save(u)
|
||||
require.NoError(t, err)
|
||||
users = append(users, u)
|
||||
}
|
||||
|
||||
data := []model.SharedChannelUser{
|
||||
{UserId: users[0].Id, ChannelId: model.NewId(), RemoteId: model.NewId(), LastSyncAt: later},
|
||||
{UserId: users[1].Id, ChannelId: model.NewId(), RemoteId: model.NewId(), LastSyncAt: earlier},
|
||||
{UserId: users[1].Id, ChannelId: model.NewId(), RemoteId: model.NewId(), LastSyncAt: earlier},
|
||||
{UserId: users[1].Id, ChannelId: channelID, RemoteId: remoteID, LastSyncAt: later},
|
||||
{UserId: users[2].Id, ChannelId: channelID, RemoteId: model.NewId(), LastSyncAt: later},
|
||||
{UserId: users[3].Id, ChannelId: channelID, RemoteId: model.NewId(), LastSyncAt: earlier},
|
||||
{UserId: users[4].Id, ChannelId: channelID, RemoteId: model.NewId(), LastSyncAt: later},
|
||||
{UserId: users[5].Id, ChannelId: channelID, RemoteId: remoteID, LastSyncAt: earlier},
|
||||
{UserId: users[6].Id, ChannelId: channelID, RemoteId: remoteID, LastSyncAt: later},
|
||||
}
|
||||
|
||||
for i, u := range data {
|
||||
scu := &model.SharedChannelUser{
|
||||
UserId: u.UserId,
|
||||
ChannelId: u.ChannelId,
|
||||
RemoteId: u.RemoteId,
|
||||
LastSyncAt: u.LastSyncAt,
|
||||
}
|
||||
_, err := ss.SharedChannel().SaveUser(scu)
|
||||
require.NoError(t, err, "could not save user #", i, err)
|
||||
}
|
||||
|
||||
t.Run("Filter by channelId", func(t *testing.T) {
|
||||
filter := model.GetUsersForSyncFilter{
|
||||
CheckProfileImage: false,
|
||||
ChannelID: channelID,
|
||||
}
|
||||
usersFound, err := ss.SharedChannel().GetUsersForSync(filter)
|
||||
require.NoError(t, err, "shouldn't error getting users", err)
|
||||
require.Len(t, usersFound, 2)
|
||||
for _, user := range usersFound {
|
||||
require.Contains(t, []string{users[3].Id, users[5].Id}, user.Id)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Filter by channelId for profile image", func(t *testing.T) {
|
||||
filter := model.GetUsersForSyncFilter{
|
||||
CheckProfileImage: true,
|
||||
ChannelID: channelID,
|
||||
}
|
||||
usersFound, err := ss.SharedChannel().GetUsersForSync(filter)
|
||||
require.NoError(t, err, "shouldn't error getting users", err)
|
||||
require.Len(t, usersFound, 2)
|
||||
for _, user := range usersFound {
|
||||
require.Contains(t, []string{users[3].Id, users[5].Id}, user.Id)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Filter by channelId with Limit", func(t *testing.T) {
|
||||
filter := model.GetUsersForSyncFilter{
|
||||
CheckProfileImage: true,
|
||||
ChannelID: channelID,
|
||||
Limit: 1,
|
||||
}
|
||||
usersFound, err := ss.SharedChannel().GetUsersForSync(filter)
|
||||
require.NoError(t, err, "shouldn't error getting users", err)
|
||||
require.Len(t, usersFound, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func testUpdateSharedChannelUserLastSyncAt(t *testing.T, ss store.Store) {
|
||||
u1 := &model.User{
|
||||
Username: model.NewId(),
|
||||
Email: model.NewId() + "@example.com",
|
||||
LastPictureUpdate: model.GetMillis() - 300000, // 5 mins
|
||||
}
|
||||
u1, err := ss.User().Save(u1)
|
||||
require.NoError(t, err)
|
||||
|
||||
u2 := &model.User{
|
||||
Username: model.NewId(),
|
||||
Email: model.NewId() + "@example.com",
|
||||
LastPictureUpdate: model.GetMillis() + 300000,
|
||||
}
|
||||
u2, err = ss.User().Save(u2)
|
||||
require.NoError(t, err)
|
||||
|
||||
channelID := model.NewId()
|
||||
remoteID := model.NewId()
|
||||
|
||||
scUser1 := &model.SharedChannelUser{
|
||||
UserId: u1.Id,
|
||||
RemoteId: remoteID,
|
||||
ChannelId: channelID,
|
||||
}
|
||||
_, err = ss.SharedChannel().SaveUser(scUser1)
|
||||
require.NoError(t, err, "couldn't save user", err)
|
||||
|
||||
future := model.GetMillis() + 3600000 // 1 hour in the future
|
||||
scUser2 := &model.SharedChannelUser{
|
||||
UserId: u2.Id,
|
||||
RemoteId: remoteID,
|
||||
ChannelId: channelID,
|
||||
}
|
||||
_, err = ss.SharedChannel().SaveUser(scUser2)
|
||||
require.NoError(t, err, "couldn't save user", err)
|
||||
|
||||
t.Run("Update LastSyncAt for user", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateUserLastSyncAt(userSaved.Id, future)
|
||||
t.Run("Update LastSyncAt for user via UpdateAt", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateUserLastSyncAt(u1.Id, channelID, remoteID)
|
||||
require.NoError(t, err, "updateLastSyncAt should not error", err)
|
||||
|
||||
u, err := ss.SharedChannel().GetUser(userSaved.UserId, userSaved.ChannelId, userSaved.RemoteId)
|
||||
scu, err := ss.SharedChannel().GetSingleUser(u1.Id, channelID, remoteID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, future, u.LastSyncAt)
|
||||
require.Equal(t, u1.UpdateAt, scu.LastSyncAt)
|
||||
})
|
||||
|
||||
t.Run("Update LastSyncAt for user via LastPictureUpdate", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateUserLastSyncAt(u2.Id, channelID, remoteID)
|
||||
require.NoError(t, err, "updateLastSyncAt should not error", err)
|
||||
|
||||
scu, err := ss.SharedChannel().GetSingleUser(u2.Id, channelID, remoteID)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, u2.LastPictureUpdate, scu.LastSyncAt)
|
||||
})
|
||||
|
||||
t.Run("Update LastSyncAt for non-existent shared channel user", func(t *testing.T) {
|
||||
err := ss.SharedChannel().UpdateUserLastSyncAt(model.NewId(), future)
|
||||
err := ss.SharedChannel().UpdateUserLastSyncAt(model.NewId(), channelID, remoteID)
|
||||
require.Error(t, err, "update non-existent user should error", err)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4890,10 +4890,10 @@ func (s *TimerLayerPostStore) GetPostsSince(options model.GetPostsSinceOptions,
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, allowFromCache bool) ([]*model.Post, error) {
|
||||
func (s *TimerLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceForSyncOptions, cursor model.GetPostsSinceForSyncCursor, limit int) ([]*model.Post, model.GetPostsSinceForSyncCursor, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
result, err := s.PostStore.GetPostsSinceForSync(options, allowFromCache)
|
||||
result, resultVar1, err := s.PostStore.GetPostsSinceForSync(options, cursor, limit)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -4903,7 +4903,7 @@ func (s *TimerLayerPostStore) GetPostsSinceForSync(options model.GetPostsSinceFo
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("PostStore.GetPostsSinceForSync", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
return result, resultVar1, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerPostStore) GetRepliesForExport(parentID string) ([]*model.ReplyForExport, error) {
|
||||
@@ -6568,10 +6568,10 @@ func (s *TimerLayerSharedChannelStore) GetRemotesStatus(channelId string) ([]*mo
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSharedChannelStore) GetUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
func (s *TimerLayerSharedChannelStore) GetSingleUser(userID string, channelID string, remoteID string) (*model.SharedChannelUser, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
result, err := s.SharedChannelStore.GetUser(userID, channelID, remoteID)
|
||||
result, err := s.SharedChannelStore.GetSingleUser(userID, channelID, remoteID)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -6579,7 +6579,39 @@ func (s *TimerLayerSharedChannelStore) GetUser(userID string, channelID string,
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetUser", success, elapsed)
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetSingleUser", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSharedChannelStore) GetUsersForSync(filter model.GetUsersForSyncFilter) ([]*model.User, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
result, err := s.SharedChannelStore.GetUsersForSync(filter)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetUsersForSync", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSharedChannelStore) GetUsersForUser(userID string) ([]*model.SharedChannelUser, error) {
|
||||
start := timemodule.Now()
|
||||
|
||||
result, err := s.SharedChannelStore.GetUsersForUser(userID)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
success := "false"
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.GetUsersForUser", success, elapsed)
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
@@ -6728,10 +6760,10 @@ func (s *TimerLayerSharedChannelStore) UpdateRemote(remote *model.SharedChannelR
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTime int64) error {
|
||||
func (s *TimerLayerSharedChannelStore) UpdateRemoteCursor(id string, cursor model.GetPostsSinceForSyncCursor) error {
|
||||
start := timemodule.Now()
|
||||
|
||||
err := s.SharedChannelStore.UpdateRemoteNextSyncAt(id, syncTime)
|
||||
err := s.SharedChannelStore.UpdateRemoteCursor(id, cursor)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
@@ -6739,15 +6771,15 @@ func (s *TimerLayerSharedChannelStore) UpdateRemoteNextSyncAt(id string, syncTim
|
||||
if err == nil {
|
||||
success = "true"
|
||||
}
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.UpdateRemoteNextSyncAt", success, elapsed)
|
||||
s.Root.Metrics.ObserveStoreMethodDuration("SharedChannelStore.UpdateRemoteCursor", success, elapsed)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *TimerLayerSharedChannelStore) UpdateUserLastSyncAt(id string, syncTime int64) error {
|
||||
func (s *TimerLayerSharedChannelStore) UpdateUserLastSyncAt(userID string, channelID string, remoteID string) error {
|
||||
start := timemodule.Now()
|
||||
|
||||
err := s.SharedChannelStore.UpdateUserLastSyncAt(id, syncTime)
|
||||
err := s.SharedChannelStore.UpdateUserLastSyncAt(userID, channelID, remoteID)
|
||||
|
||||
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
|
||||
if s.Root.Metrics != nil {
|
||||
|
||||
Ссылка в новой задаче
Block a user