Migrates Channel.UpdateLastViewedAt to sync by default (#11240)

Этот коммит содержится в:
Rodrigo Villablanca Vásquez
2019-06-26 05:52:43 -04:00
коммит произвёл Hanzei
родитель 6df57d7a83
Коммит 4cf6ae6808
5 изменённых файлов: 97 добавлений и 92 удалений

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

@@ -1708,8 +1708,8 @@ func (a *App) SetActiveChannel(userId string, channelId string) *model.AppError
} }
func (a *App) UpdateChannelLastViewedAt(channelIds []string, userId string) *model.AppError { func (a *App) UpdateChannelLastViewedAt(channelIds []string, userId string) *model.AppError {
if result := <-a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId); result.Err != nil { if _, err := a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId); err != nil {
return result.Err return err
} }
if *a.Config().ServiceSettings.EnableChannelViewedMessages { if *a.Config().ServiceSettings.EnableChannelViewedMessages {
@@ -1856,12 +1856,11 @@ func (a *App) MarkChannelsAsViewed(channelIds []string, userId string, currentSe
} }
} }
} }
result := <-a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId) times, err := a.Srv.Store.Channel().UpdateLastViewedAt(channelIds, userId)
if result.Err != nil { if err != nil {
return nil, result.Err return nil, err
} }
times := result.Data.(map[string]int64)
if *a.Config().ServiceSettings.EnableChannelViewedMessages { if *a.Config().ServiceSettings.EnableChannelViewedMessages {
for _, channelId := range channelIds { for _, channelId := range channelIds {
message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil) message := model.NewWebSocketEvent(model.WEBSOCKET_EVENT_CHANNEL_VIEWED, "", "", userId, nil)

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

@@ -1725,93 +1725,89 @@ func (s SqlChannelStore) PermanentDeleteMembersByUser(userId string) store.Store
}) })
} }
func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string) store.StoreChannel { func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string) (map[string]int64, *model.AppError) {
return store.Do(func(result *store.StoreResult) { props := make(map[string]interface{})
props := make(map[string]interface{})
updateIdQuery := "" updateIdQuery := ""
for index, channelId := range channelIds { for index, channelId := range channelIds {
if len(updateIdQuery) > 0 { if len(updateIdQuery) > 0 {
updateIdQuery += " OR " updateIdQuery += " OR "
}
props["channelId"+strconv.Itoa(index)] = channelId
updateIdQuery += "ChannelId = :channelId" + strconv.Itoa(index)
} }
selectIdQuery := strings.Replace(updateIdQuery, "ChannelId", "Id", -1) props["channelId"+strconv.Itoa(index)] = channelId
updateIdQuery += "ChannelId = :channelId" + strconv.Itoa(index)
}
var lastPostAtTimes []struct { selectIdQuery := strings.Replace(updateIdQuery, "ChannelId", "Id", -1)
Id string
LastPostAt int64 var lastPostAtTimes []struct {
TotalMsgCount int64 Id string
LastPostAt int64
TotalMsgCount int64
}
selectQuery := "SELECT Id, LastPostAt, TotalMsgCount FROM Channels WHERE (" + selectIdQuery + ")"
if _, err := s.GetMaster().Select(&lastPostAtTimes, selectQuery, props); err != nil || len(lastPostAtTimes) <= 0 {
var extra string
status := http.StatusInternalServerError
if err == nil {
status = http.StatusBadRequest
extra = "No channels found"
} else {
extra = err.Error()
} }
return nil, model.NewAppError("SqlChannelStore.UpdateLastViewedAt", "store.sql_channel.update_last_viewed_at.app_error", nil, "channel_ids="+strings.Join(channelIds, ",")+", user_id="+userId+", "+extra, status)
}
selectQuery := "SELECT Id, LastPostAt, TotalMsgCount FROM Channels WHERE (" + selectIdQuery + ")" times := map[string]int64{}
msgCountQuery := ""
lastViewedQuery := ""
for index, t := range lastPostAtTimes {
times[t.Id] = t.LastPostAt
if _, err := s.GetMaster().Select(&lastPostAtTimes, selectQuery, props); err != nil || len(lastPostAtTimes) <= 0 { props["msgCount"+strconv.Itoa(index)] = t.TotalMsgCount
var extra string msgCountQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(MsgCount, :msgCount%d) ", index, index)
status := http.StatusInternalServerError
if err == nil {
status = http.StatusBadRequest
extra = "No channels found"
} else {
extra = err.Error()
}
result.Err = model.NewAppError("SqlChannelStore.UpdateLastViewedAt", "store.sql_channel.update_last_viewed_at.app_error", nil, "channel_ids="+strings.Join(channelIds, ",")+", user_id="+userId+", "+extra, status)
return
}
times := map[string]int64{} props["lastViewed"+strconv.Itoa(index)] = t.LastPostAt
msgCountQuery := "" lastViewedQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(LastViewedAt, :lastViewed%d) ", index, index)
lastViewedQuery := ""
for index, t := range lastPostAtTimes {
times[t.Id] = t.LastPostAt
props["msgCount"+strconv.Itoa(index)] = t.TotalMsgCount props["channelId"+strconv.Itoa(index)] = t.Id
msgCountQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(MsgCount, :msgCount%d) ", index, index) }
props["lastViewed"+strconv.Itoa(index)] = t.LastPostAt var updateQuery string
lastViewedQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(LastViewedAt, :lastViewed%d) ", index, index)
props["channelId"+strconv.Itoa(index)] = t.Id if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
} updateQuery = `UPDATE
ChannelMembers
SET
MentionCount = 0,
MsgCount = CAST(CASE ChannelId ` + msgCountQuery + ` END AS BIGINT),
LastViewedAt = CAST(CASE ChannelId ` + lastViewedQuery + ` END AS BIGINT),
LastUpdateAt = CAST(CASE ChannelId ` + lastViewedQuery + ` END AS BIGINT)
WHERE
UserId = :UserId
AND (` + updateIdQuery + `)`
} else if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
updateQuery = `UPDATE
ChannelMembers
SET
MentionCount = 0,
MsgCount = CASE ChannelId ` + msgCountQuery + ` END,
LastViewedAt = CASE ChannelId ` + lastViewedQuery + ` END,
LastUpdateAt = CASE ChannelId ` + lastViewedQuery + ` END
WHERE
UserId = :UserId
AND (` + updateIdQuery + `)`
}
var updateQuery string props["UserId"] = userId
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES { if _, err := s.GetMaster().Exec(updateQuery, props); err != nil {
updateQuery = `UPDATE return nil, model.NewAppError("SqlChannelStore.UpdateLastViewedAt", "store.sql_channel.update_last_viewed_at.app_error", nil, "channel_ids="+strings.Join(channelIds, ",")+", user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
ChannelMembers }
SET
MentionCount = 0,
MsgCount = CAST(CASE ChannelId ` + msgCountQuery + ` END AS BIGINT),
LastViewedAt = CAST(CASE ChannelId ` + lastViewedQuery + ` END AS BIGINT),
LastUpdateAt = CAST(CASE ChannelId ` + lastViewedQuery + ` END AS BIGINT)
WHERE
UserId = :UserId
AND (` + updateIdQuery + `)`
} else if s.DriverName() == model.DATABASE_DRIVER_MYSQL {
updateQuery = `UPDATE
ChannelMembers
SET
MentionCount = 0,
MsgCount = CASE ChannelId ` + msgCountQuery + ` END,
LastViewedAt = CASE ChannelId ` + lastViewedQuery + ` END,
LastUpdateAt = CASE ChannelId ` + lastViewedQuery + ` END
WHERE
UserId = :UserId
AND (` + updateIdQuery + `)`
}
props["UserId"] = userId return times, nil
if _, err := s.GetMaster().Exec(updateQuery, props); err != nil {
result.Err = model.NewAppError("SqlChannelStore.UpdateLastViewedAt", "store.sql_channel.update_last_viewed_at.app_error", nil, "channel_ids="+strings.Join(channelIds, ",")+", user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
return
}
result.Data = times
})
} }
func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string) *model.AppError { func (s SqlChannelStore) IncrementMentionCount(channelId string, userId string) *model.AppError {

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

@@ -176,7 +176,7 @@ type ChannelStore interface {
RemoveMember(channelId string, userId string) *model.AppError RemoveMember(channelId string, userId string) *model.AppError
PermanentDeleteMembersByUser(userId string) StoreChannel PermanentDeleteMembersByUser(userId string) StoreChannel
PermanentDeleteMembersByChannel(channelId string) *model.AppError PermanentDeleteMembersByChannel(channelId string) *model.AppError
UpdateLastViewedAt(channelIds []string, userId string) StoreChannel UpdateLastViewedAt(channelIds []string, userId string) (map[string]int64, *model.AppError)
IncrementMentionCount(channelId string, userId string) *model.AppError IncrementMentionCount(channelId string, userId string) *model.AppError
AnalyticsTypeCount(teamId string, channelType string) (int64, *model.AppError) AnalyticsTypeCount(teamId string, channelType string) (int64, *model.AppError)
GetMembersForUser(teamId string, userId string) (*model.ChannelMembers, *model.AppError) GetMembersForUser(teamId string, userId string) (*model.ChannelMembers, *model.AppError)

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

@@ -1686,15 +1686,16 @@ func testChannelStoreUpdateLastViewedAt(t *testing.T, ss store.Store) {
m2.NotifyProps = model.GetDefaultChannelNotifyProps() m2.NotifyProps = model.GetDefaultChannelNotifyProps()
store.Must(ss.Channel().SaveMember(&m2)) store.Must(ss.Channel().SaveMember(&m2))
if result := <-ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, m1.UserId); result.Err != nil { var times map[string]int64
t.Fatal("failed to update", result.Err) if times, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, m1.UserId); err != nil {
} else if result.Data.(map[string]int64)[o1.Id] != o1.LastPostAt { t.Fatal("failed to update", err)
} else if times[o1.Id] != o1.LastPostAt {
t.Fatal("last viewed at time incorrect") t.Fatal("last viewed at time incorrect")
} }
if result := <-ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId, m2.ChannelId}, m1.UserId); result.Err != nil { if times, err = ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId, m2.ChannelId}, m1.UserId); err != nil {
t.Fatal("failed to update", result.Err) t.Fatal("failed to update", err)
} else if result.Data.(map[string]int64)[o2.Id] != o2.LastPostAt { } else if times[o2.Id] != o2.LastPostAt {
t.Fatal("last viewed at time incorrect") t.Fatal("last viewed at time incorrect")
} }
@@ -1710,7 +1711,7 @@ func testChannelStoreUpdateLastViewedAt(t *testing.T, ss store.Store) {
assert.Equal(t, rm2.LastUpdateAt, o2.LastPostAt) assert.Equal(t, rm2.LastUpdateAt, o2.LastPostAt)
assert.Equal(t, rm2.MsgCount, o2.TotalMsgCount) assert.Equal(t, rm2.MsgCount, o2.TotalMsgCount)
if result := <-ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, "missing id"); result.Err != nil { if _, err := ss.Channel().UpdateLastViewedAt([]string{m1.ChannelId}, "missing id"); err != nil {
t.Fatal("failed to update") t.Fatal("failed to update")
} }
} }

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

@@ -1450,19 +1450,28 @@ func (_m *ChannelStore) Update(channel *model.Channel) (*model.Channel, *model.A
} }
// UpdateLastViewedAt provides a mock function with given fields: channelIds, userId // UpdateLastViewedAt provides a mock function with given fields: channelIds, userId
func (_m *ChannelStore) UpdateLastViewedAt(channelIds []string, userId string) store.StoreChannel { func (_m *ChannelStore) UpdateLastViewedAt(channelIds []string, userId string) (map[string]int64, *model.AppError) {
ret := _m.Called(channelIds, userId) ret := _m.Called(channelIds, userId)
var r0 store.StoreChannel var r0 map[string]int64
if rf, ok := ret.Get(0).(func([]string, string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func([]string, string) map[string]int64); ok {
r0 = rf(channelIds, userId) r0 = rf(channelIds, userId)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(map[string]int64)
} }
} }
return r0 var r1 *model.AppError
if rf, ok := ret.Get(1).(func([]string, string) *model.AppError); ok {
r1 = rf(channelIds, userId)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
} }
// UpdateMember provides a mock function with given fields: member // UpdateMember provides a mock function with given fields: member