MM-33746 Add TotalMsgCountRoot and MsgCountRoot columns (#17150)

Этот коммит содержится в:
Eli Yukelzon
2021-03-31 16:51:02 +03:00
коммит произвёл GitHub
родитель ee3f986da0
Коммит ab5925c4de
22 изменённых файлов: 356 добавлений и 103 удалений

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

@@ -320,6 +320,10 @@ jobs:
mattermost/mattermost-build-server:20201119_golang-1.15.5 \
bash -c "ulimit -n 8096; make ARGS='version' run-cli && make MM_SQLSETTINGS_DATASOURCE='postgres://mmuser:mostest@postgres:5432/latest?sslmode=disable&connect_timeout=10' ARGS='version' run-cli"
echo "Ignoring known mismatch: ChannelMembers.MsgCountRoot"
docker-compose --no-ansi exec -T postgres sh -c 'exec echo "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;" | exec psql -U mmuser -d migrated'
docker-compose --no-ansi exec -T postgres sh -c 'exec echo "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;" | exec psql -U mmuser -d latest'
echo "Generating dump"
docker-compose --no-ansi exec -T postgres pg_dump --schema-only -d migrated -U mmuser > migrated.sql
docker-compose --no-ansi exec -T postgres pg_dump --schema-only -d latest -U mmuser > latest.sql
@@ -349,9 +353,13 @@ jobs:
mattermost/mattermost-build-server:20201119_golang-1.15.5 \
bash -c "ulimit -n 8096; make ARGS='version' run-cli && make MM_SQLSETTINGS_DATASOURCE='mmuser:mostest@tcp(mysql:3306)/latest?charset=utf8mb4,utf8&readTimeout=30s&writeTimeout=30s' ARGS='version' run-cli"
echo "Ignoring known MySQL mismatch: ChannelMembers.SchemeGuest"
docker-compose --no-ansi exec -T mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN SchemeGuest;"
docker-compose --no-ansi exec -T mysql mysql -D latest -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN SchemeGuest;"
echo "Ignoring known MySQL mismatch: ChannelMembers.MentionCountRoot"
docker-compose --no-ansi exec -T mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;"
docker-compose --no-ansi exec -T mysql mysql -D latest -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN MsgCountRoot;"
echo "Generating dump"
docker-compose --no-ansi exec -T mysql mysqldump --skip-opt --no-data --compact -u root -pmostest migrated > migrated.sql

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

@@ -1871,6 +1871,7 @@ func (a *App) GetChannelUnread(channelID, userID string) (*model.ChannelUnread,
if channelUnread.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] == model.CHANNEL_MARK_UNREAD_MENTION {
channelUnread.MsgCount = 0
channelUnread.MsgCountRoot = 0
}
return channelUnread, nil

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

@@ -1411,7 +1411,7 @@ func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, *m
if channel.Type == model.CHANNEL_DIRECT {
// In a DM channel, every post made by the other user is a mention
count, nErr := a.Srv().Store.Channel().CountPostsAfter(post.ChannelId, post.CreateAt-1, channel.GetOtherUserIdForDM(user.Id))
count, _, nErr := a.Srv().Store.Channel().CountPostsAfter(post.ChannelId, post.CreateAt-1, channel.GetOtherUserIdForDM(user.Id))
if nErr != nil {
return 0, model.NewAppError("countMentionsFromPost", "app.channel.count_posts_since.app_error", nil, nErr.Error(), http.StatusInternalServerError)
}

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

@@ -1133,12 +1133,14 @@ func (a *App) AddTeamMemberByInviteId(inviteId, userID string) (*model.TeamMembe
func (a *App) GetTeamUnread(teamID, userID string) (*model.TeamUnread, *model.AppError) {
channelUnreads, err := a.Srv().Store.Team().GetChannelUnreadsForTeam(teamID, userID)
if err != nil {
return nil, model.NewAppError("GetTeamUnread", "app.team.get_unread.app_error", nil, err.Error(), http.StatusInternalServerError)
}
var teamUnread = &model.TeamUnread{
MsgCount: 0,
MsgCountRoot: 0,
MentionCount: 0,
TeamId: teamID,
}
@@ -1148,6 +1150,7 @@ func (a *App) GetTeamUnread(teamID, userID string) (*model.TeamUnread, *model.Ap
if cu.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != model.CHANNEL_MARK_UNREAD_MENTION {
teamUnread.MsgCount += cu.MsgCount
teamUnread.MsgCountRoot += cu.MsgCountRoot
}
}
@@ -1677,6 +1680,7 @@ func (a *App) GetTeamsUnreadForUser(excludeTeamId string, userID string) ([]*mod
if cu.NotifyProps[model.MARK_UNREAD_NOTIFY_PROP] != model.CHANNEL_MARK_UNREAD_MENTION {
tu.MsgCount += cu.MsgCount
tu.MsgCountRoot += cu.MsgCountRoot
}
return tu
@@ -1689,6 +1693,7 @@ func (a *App) GetTeamsUnreadForUser(excludeTeamId string, userID string) ([]*mod
} else {
membersMap[id] = unreads(data[i], &model.TeamUnread{
MsgCount: 0,
MsgCountRoot: 0,
MentionCount: 0,
TeamId: id,
})

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

@@ -34,24 +34,25 @@ const (
)
type Channel struct {
Id string `json:"id"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`
TeamId string `json:"team_id"`
Type string `json:"type"`
DisplayName string `json:"display_name"`
Name string `json:"name"`
Header string `json:"header"`
Purpose string `json:"purpose"`
LastPostAt int64 `json:"last_post_at"`
TotalMsgCount int64 `json:"total_msg_count"`
ExtraUpdateAt int64 `json:"extra_update_at"`
CreatorId string `json:"creator_id"`
SchemeId *string `json:"scheme_id"`
Props map[string]interface{} `json:"props" db:"-"`
GroupConstrained *bool `json:"group_constrained"`
Shared *bool `json:"shared"`
Id string `json:"id"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`
TeamId string `json:"team_id"`
Type string `json:"type"`
DisplayName string `json:"display_name"`
Name string `json:"name"`
Header string `json:"header"`
Purpose string `json:"purpose"`
LastPostAt int64 `json:"last_post_at"`
TotalMsgCount int64 `json:"total_msg_count"`
ExtraUpdateAt int64 `json:"extra_update_at"`
CreatorId string `json:"creator_id"`
SchemeId *string `json:"scheme_id"`
Props map[string]interface{} `json:"props" db:"-"`
GroupConstrained *bool `json:"group_constrained"`
Shared *bool `json:"shared"`
TotalMsgCountRoot int64 `json:"total_msg_count_root"`
}
type ChannelWithTeamData struct {

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

@@ -14,11 +14,12 @@ import (
type ChannelCounts struct {
Counts map[string]int64 `json:"counts"`
CountsRoot map[string]int64 `json:"counts_root"`
UpdateTimes map[string]int64 `json:"update_times"`
}
func (o *ChannelCounts) Etag() string {
// we don't include CountsRoot in ETag calculation, since it's a deriviative
ids := []string{}
for id := range o.Counts {
ids = append(ids, id)

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

@@ -27,6 +27,7 @@ type ChannelUnread struct {
TeamId string `json:"team_id"`
ChannelId string `json:"channel_id"`
MsgCount int64 `json:"msg_count"`
MsgCountRoot int64 `json:"msg_count_root"`
MentionCount int64 `json:"mention_count"`
NotifyProps StringMap `json:"-"`
}
@@ -36,6 +37,7 @@ type ChannelUnreadAt struct {
UserId string `json:"user_id"`
ChannelId string `json:"channel_id"`
MsgCount int64 `json:"msg_count"`
MsgCountRoot int64 `json:"msg_count_root"`
MentionCount int64 `json:"mention_count"`
LastViewedAt int64 `json:"last_viewed_at"`
NotifyProps StringMap `json:"-"`
@@ -54,6 +56,7 @@ type ChannelMember struct {
SchemeUser bool `json:"scheme_user"`
SchemeAdmin bool `json:"scheme_admin"`
ExplicitRoles string `json:"explicit_roles"`
MsgCountRoot int64 `json:"msg_count_root"`
}
type ChannelMembers []ChannelMember

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

@@ -33,6 +33,7 @@ type TeamMember struct {
type TeamUnread struct {
TeamId string `json:"team_id"`
MsgCount int64 `json:"msg_count"`
MsgCountRoot int64 `json:"msg_count_root"`
MentionCount int64 `json:"mention_count"`
}

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

@@ -22,9 +22,12 @@ make ARGS="config set SqlSettings.DataSource 'mmuser:mostest@tcp(localhost:3306)
echo "Setting up fresh db"
make ARGS="version --config $TMPDIR/config.json" run-cli
echo "Ignoring known MySQL mismatch: ChannelMembers.SchemeGuest"
docker exec mattermost-mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN SchemeGuest;"
docker exec mattermost-mysql mysql -D latest -uroot -pmostest -e "ALTER TABLE ChannelMembers DROP COLUMN SchemeGuest;"
for i in "ChannelMembers SchemeGuest" "ChannelMembers MsgCountRoot"; do
a=( $i );
echo "Ignoring known MySQL mismatch: ${a[0]}.${a[1]}"
docker exec mattermost-mysql mysql -D migrated -uroot -pmostest -e "ALTER TABLE ${a[0]} DROP COLUMN ${a[1]};"
docker exec mattermost-mysql mysql -D latest -uroot -pmostest -e "ALTER TABLE ${a[0]} DROP COLUMN ${a[1]};"
done
echo "Generating dump"
docker exec mattermost-mysql mysqldump --skip-opt --no-data --compact -u root -pmostest migrated > $DUMPDIR/migrated.sql

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

@@ -22,6 +22,13 @@ make ARGS="config set SqlSettings.DataSource 'postgres://mmuser:mostest@localhos
echo "Setting up fresh db"
make ARGS="version --config $TMPDIR/config.json" run-cli
for i in "ChannelMembers MsgCountRoot"; do
a=( $i );
echo "Ignoring known Postgres mismatch: ${a[0]}.${a[1]}"
docker exec mattermost-postgres psql -U mmuser -d migrated -c "ALTER TABLE ${a[0]} DROP COLUMN ${a[1]};"
docker exec mattermost-postgres psql -U mmuser -d latest -c "ALTER TABLE ${a[0]} DROP COLUMN ${a[1]};"
done
echo "Generating dump"
docker exec mattermost-postgres pg_dump --schema-only -d migrated -U mmuser > $DUMPDIR/migrated.sql
docker exec mattermost-postgres pg_dump --schema-only -d latest -U mmuser > $DUMPDIR/latest.sql

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

@@ -625,7 +625,7 @@ func (s *OpenTracingLayerChannelStore) ClearSidebarOnTeamLeave(userId string, te
return err
}
func (s *OpenTracingLayerChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, error) {
func (s *OpenTracingLayerChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, int, error) {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "ChannelStore.CountPostsAfter")
s.Root.Store.SetContext(newCtx)
@@ -634,13 +634,13 @@ func (s *OpenTracingLayerChannelStore) CountPostsAfter(channelID string, timesta
}()
defer span.Finish()
result, err := s.ChannelStore.CountPostsAfter(channelID, timestamp, userId)
result, resultVar1, err := s.ChannelStore.CountPostsAfter(channelID, timestamp, userId)
if err != nil {
span.LogFields(spanlog.Error(err))
ext.Error.Set(span, true)
}
return result, err
return result, resultVar1, err
}
func (s *OpenTracingLayerChannelStore) CreateDirectChannel(userId *model.User, otherUserId *model.User) (*model.Channel, error) {

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

@@ -664,21 +664,21 @@ func (s *RetryLayerChannelStore) ClearSidebarOnTeamLeave(userId string, teamID s
}
func (s *RetryLayerChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, error) {
func (s *RetryLayerChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, int, error) {
tries := 0
for {
result, err := s.ChannelStore.CountPostsAfter(channelID, timestamp, userId)
result, resultVar1, err := s.ChannelStore.CountPostsAfter(channelID, timestamp, userId)
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
}
}

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

@@ -50,6 +50,7 @@ type channelMember struct {
SchemeUser sql.NullBool
SchemeAdmin sql.NullBool
SchemeGuest sql.NullBool
MsgCountRoot int64
}
func NewChannelMemberFromModel(cm *model.ChannelMember) *channelMember {
@@ -59,6 +60,7 @@ func NewChannelMemberFromModel(cm *model.ChannelMember) *channelMember {
Roles: cm.ExplicitRoles,
LastViewedAt: cm.LastViewedAt,
MsgCount: cm.MsgCount,
MsgCountRoot: cm.MsgCountRoot,
MentionCount: cm.MentionCount,
NotifyProps: cm.NotifyProps,
LastUpdateAt: cm.LastUpdateAt,
@@ -86,10 +88,11 @@ type channelMemberWithSchemeRoles struct {
ChannelSchemeDefaultGuestRole sql.NullString
ChannelSchemeDefaultUserRole sql.NullString
ChannelSchemeDefaultAdminRole sql.NullString
MsgCountRoot int64
}
func channelMemberSliceColumns() []string {
return []string{"ChannelId", "UserId", "Roles", "LastViewedAt", "MsgCount", "MentionCount", "NotifyProps", "LastUpdateAt", "SchemeUser", "SchemeAdmin", "SchemeGuest"}
return []string{"ChannelId", "UserId", "Roles", "LastViewedAt", "MsgCount", "MsgCountRoot", "MentionCount", "NotifyProps", "LastUpdateAt", "SchemeUser", "SchemeAdmin", "SchemeGuest"}
}
func channelMemberToSlice(member *model.ChannelMember) []interface{} {
@@ -99,6 +102,7 @@ func channelMemberToSlice(member *model.ChannelMember) []interface{} {
resultSlice = append(resultSlice, member.ExplicitRoles)
resultSlice = append(resultSlice, member.LastViewedAt)
resultSlice = append(resultSlice, member.MsgCount)
resultSlice = append(resultSlice, member.MsgCountRoot)
resultSlice = append(resultSlice, member.MentionCount)
resultSlice = append(resultSlice, model.MapToJson(member.NotifyProps))
resultSlice = append(resultSlice, member.LastUpdateAt)
@@ -230,6 +234,7 @@ func (db channelMemberWithSchemeRoles) ToModel() *model.ChannelMember {
Roles: strings.Join(rolesResult.roles, " "),
LastViewedAt: db.LastViewedAt,
MsgCount: db.MsgCount,
MsgCountRoot: db.MsgCountRoot,
MentionCount: db.MentionCount,
NotifyProps: db.NotifyProps,
LastUpdateAt: db.LastUpdateAt,
@@ -712,7 +717,10 @@ func (s SqlChannelStore) GetChannelUnread(channelId, userId string) (*model.Chan
var unreadChannel model.ChannelUnread
err := s.GetReplica().SelectOne(&unreadChannel,
`SELECT
Channels.TeamId TeamId, Channels.Id ChannelId, (Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount, ChannelMembers.MentionCount MentionCount, ChannelMembers.NotifyProps NotifyProps
Channels.TeamId TeamId, Channels.Id ChannelId,
(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount,
(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot,
ChannelMembers.MentionCount MentionCount, ChannelMembers.NotifyProps NotifyProps
FROM
Channels, ChannelMembers
WHERE
@@ -1181,23 +1189,25 @@ func (s SqlChannelStore) GetPublicChannelsByIdsForTeam(teamId string, channelIds
}
type channelIdWithCountAndUpdateAt struct {
Id string
TotalMsgCount int64
UpdateAt int64
Id string
TotalMsgCount int64
TotalMsgCountRoot int64
UpdateAt int64
}
func (s SqlChannelStore) GetChannelCounts(teamId string, userId string) (*model.ChannelCounts, error) {
var data []channelIdWithCountAndUpdateAt
_, err := s.GetReplica().Select(&data, "SELECT Id, TotalMsgCount, UpdateAt FROM Channels WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = :UserId) AND (TeamId = :TeamId OR TeamId = '') AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
_, err := s.GetReplica().Select(&data, "SELECT Id, TotalMsgCount, TotalMsgCountRoot, UpdateAt FROM Channels WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = :UserId) AND (TeamId = :TeamId OR TeamId = '') AND DeleteAt = 0 ORDER BY DisplayName", map[string]interface{}{"TeamId": teamId, "UserId": userId})
if err != nil {
return nil, errors.Wrapf(err, "failed to get channels count with teamId=%s and userId=%s", teamId, userId)
}
counts := &model.ChannelCounts{Counts: make(map[string]int64), UpdateTimes: make(map[string]int64)}
counts := &model.ChannelCounts{Counts: make(map[string]int64), CountsRoot: make(map[string]int64), UpdateTimes: make(map[string]int64)}
for i := range data {
v := data[i]
counts.Counts[v.Id] = v.TotalMsgCount
counts.CountsRoot[v.Id] = v.TotalMsgCountRoot
counts.UpdateTimes[v.Id] = v.UpdateAt
}
@@ -2061,12 +2071,13 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
props["UserId"] = userId
var lastPostAtTimes []struct {
Id string
LastPostAt int64
TotalMsgCount int64
Id string
LastPostAt int64
TotalMsgCount int64
TotalMsgCountRoot int64
}
query := `SELECT Id, LastPostAt, TotalMsgCount FROM Channels WHERE Id IN ` + keys
query := `SELECT Id, LastPostAt, TotalMsgCount, TotalMsgCountRoot FROM Channels WHERE Id IN ` + keys
// TODO: use a CTE for mysql too when version 8 becomes the minimum supported version.
if s.DriverName() == model.DATABASE_DRIVER_POSTGRES {
query = `WITH c AS ( ` + query + `),
@@ -2076,6 +2087,7 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
SET
MentionCount = 0,
MsgCount = greatest(cm.MsgCount, c.TotalMsgCount),
MsgCountRoot = greatest(cm.MsgCountRoot, c.TotalMsgCountRoot),
LastViewedAt = greatest(cm.LastViewedAt, c.LastPostAt),
LastUpdateAt = greatest(cm.LastViewedAt, c.LastPostAt)
FROM c
@@ -2106,6 +2118,7 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
}
msgCountQuery := ""
msgCountQueryRoot := ""
lastViewedQuery := ""
for index, t := range lastPostAtTimes {
@@ -2114,6 +2127,9 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
props["msgCount"+strconv.Itoa(index)] = t.TotalMsgCount
msgCountQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(MsgCount, :msgCount%d) ", index, index)
props["msgCountRoot"+strconv.Itoa(index)] = t.TotalMsgCountRoot
msgCountQueryRoot += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(MsgCountRoot, :msgCountRoot%d) ", index, index)
props["lastViewed"+strconv.Itoa(index)] = t.LastPostAt
lastViewedQuery += fmt.Sprintf("WHEN :channelId%d THEN GREATEST(LastViewedAt, :lastViewed%d) ", index, index)
@@ -2125,6 +2141,7 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
SET
MentionCount = 0,
MsgCount = CASE ChannelId ` + msgCountQuery + ` END,
MsgCountRoot = CASE ChannelId ` + msgCountQueryRoot + ` END,
LastViewedAt = CASE ChannelId ` + lastViewedQuery + ` END,
LastUpdateAt = LastViewedAt
WHERE
@@ -2142,8 +2159,8 @@ func (s SqlChannelStore) UpdateLastViewedAt(channelIds []string, userId string,
}
// CountPostsAfter returns the number of posts in the given channel created after but not including the given timestamp. If given a non-empty user ID, only counts posts made by that user.
func (s SqlChannelStore) CountPostsAfter(channelId string, timestamp int64, userId string) (int, error) {
joinLeavePostTypes, params := MapStringsToQueryParams([]string{
func (s SqlChannelStore) CountPostsAfter(channelId string, timestamp int64, userId string) (int, int, error) {
joinLeavePostTypes := []string{
// These types correspond to the ones checked by Post.IsJoinLeaveMessage
model.POST_JOIN_LEAVE,
model.POST_ADD_REMOVE,
@@ -2155,31 +2172,25 @@ func (s SqlChannelStore) CountPostsAfter(channelId string, timestamp int64, user
model.POST_REMOVE_FROM_CHANNEL,
model.POST_ADD_TO_TEAM,
model.POST_REMOVE_FROM_TEAM,
}, "PostType")
query := `
SELECT count(*)
FROM Posts
WHERE
ChannelId = :ChannelId
AND CreateAt > :CreateAt
AND Type NOT IN ` + joinLeavePostTypes + `
AND DeleteAt = 0
`
params["ChannelId"] = channelId
params["CreateAt"] = timestamp
}
query := s.getQueryBuilder().Select("count(*)").From("Posts").Where(sq.Eq{"ChannelId": channelId}).Where(sq.Gt{"CreateAt": timestamp}).Where(sq.NotEq{"Type": joinLeavePostTypes}).Where(sq.Eq{"DeleteAt": 0})
if userId != "" {
query += " AND UserId = :UserId"
params["UserId"] = userId
query = query.Where(sq.Eq{"UserId": userId})
}
sql, args, _ := query.ToSql()
unread, err := s.GetReplica().SelectInt(query, params)
unread, err := s.GetReplica().SelectInt(sql, args...)
if err != nil {
return 0, errors.Wrap(err, "failed to count Posts")
return 0, 0, errors.Wrap(err, "failed to count Posts")
}
return int(unread), nil
sql2, args2, _ := query.Where(sq.Eq{"RootId": ""}).ToSql()
unreadRoot, err := s.GetReplica().SelectInt(sql2, args2...)
if err != nil {
return 0, 0, errors.Wrap(err, "failed to count root Posts")
}
return int(unread), int(unreadRoot), nil
}
// UpdateLastViewedAtPost updates a ChannelMember as if the user last read the channel at the time of the given post.
@@ -2196,18 +2207,19 @@ func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID s
}
}
unread, err := s.CountPostsAfter(unreadPost.ChannelId, unreadDate, "")
unread, unreadRoot, err := s.CountPostsAfter(unreadPost.ChannelId, unreadDate, "")
if err != nil {
return nil, err
}
params := map[string]interface{}{
"mentions": mentionCount,
"unreadCount": unread,
"lastViewedAt": unreadDate,
"userId": userID,
"channelId": unreadPost.ChannelId,
"updatedAt": model.GetMillis(),
"mentions": mentionCount,
"unreadCount": unread,
"unreadCountRoot": unreadRoot,
"lastViewedAt": unreadDate,
"userId": userID,
"channelId": unreadPost.ChannelId,
"updatedAt": model.GetMillis(),
}
// msg count uses the value from channels to prevent counting on older channels where no. of messages can be high.
@@ -2218,6 +2230,7 @@ func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID s
SET
MentionCount = :mentions,
MsgCount = (SELECT TotalMsgCount FROM Channels WHERE ID = :channelId) - :unreadCount,
MsgCountRoot = (SELECT TotalMsgCountRoot FROM Channels WHERE ID = :channelId) - :unreadCountRoot,
LastViewedAt = :lastViewedAt,
LastUpdateAt = :updatedAt
WHERE
@@ -2235,6 +2248,7 @@ func (s SqlChannelStore) UpdateLastViewedAtPost(unreadPost *model.Post, userID s
cm.UserId UserId,
cm.ChannelId ChannelId,
cm.MsgCount MsgCount,
cm.MsgCountRoot MsgCountRoot,
cm.MentionCount MentionCount,
cm.LastViewedAt LastViewedAt,
cm.NotifyProps NotifyProps

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

@@ -917,6 +917,7 @@ func (s *SqlGroupStore) ChannelMembersToRemove(channelID *string) ([]*model.Chan
"ChannelMembers.UserId",
"ChannelMembers.LastViewedAt",
"ChannelMembers.MsgCount",
"ChannelMembers.MsgCountRoot",
"ChannelMembers.MentionCount",
"ChannelMembers.NotifyProps",
"ChannelMembers.LastUpdateAt",

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

@@ -112,6 +112,7 @@ func (s *SqlPostStore) createIndexesIfNotExists() {
func (s *SqlPostStore) SaveMultiple(posts []*model.Post) ([]*model.Post, int, error) {
channelNewPosts := make(map[string]int)
channelNewRootPosts := make(map[string]int)
maxDateNewPosts := make(map[string]int64)
rootIds := make(map[string]int)
maxDateRootIds := make(map[string]int64)
@@ -125,8 +126,7 @@ func (s *SqlPostStore) SaveMultiple(posts []*model.Post) ([]*model.Post, int, er
return nil, idx, err
}
currentChannelCount, ok := channelNewPosts[post.ChannelId]
if !ok {
if currentChannelCount, ok := channelNewPosts[post.ChannelId]; !ok {
if post.IsJoinLeaveMessage() {
channelNewPosts[post.ChannelId] = 0
} else {
@@ -143,11 +143,21 @@ func (s *SqlPostStore) SaveMultiple(posts []*model.Post) ([]*model.Post, int, er
}
if post.RootId == "" {
if currentChannelCount, ok := channelNewRootPosts[post.ChannelId]; !ok {
if post.IsJoinLeaveMessage() {
channelNewRootPosts[post.ChannelId] = 0
} else {
channelNewRootPosts[post.ChannelId] = 1
}
} else {
if !post.IsJoinLeaveMessage() {
channelNewRootPosts[post.ChannelId] = currentChannelCount + 1
}
}
continue
}
currentRootCount, ok := rootIds[post.RootId]
if !ok {
if currentRootCount, ok := rootIds[post.RootId]; !ok {
rootIds[post.RootId] = 1
maxDateRootIds[post.RootId] = post.CreateAt
} else {
@@ -188,7 +198,9 @@ func (s *SqlPostStore) SaveMultiple(posts []*model.Post) ([]*model.Post, int, er
}
for channelId, count := range channelNewPosts {
if _, err = s.GetMaster().Exec("UPDATE Channels SET LastPostAt = GREATEST(:LastPostAt, LastPostAt), TotalMsgCount = TotalMsgCount + :Count WHERE Id = :ChannelId", map[string]interface{}{"LastPostAt": maxDateNewPosts[channelId], "ChannelId": channelId, "Count": count}); err != nil {
countRoot := channelNewRootPosts[channelId]
if _, err = s.GetMaster().Exec("UPDATE Channels SET LastPostAt = GREATEST(:LastPostAt, LastPostAt), TotalMsgCount = TotalMsgCount + :Count, TotalMsgCountRoot = TotalMsgCountRoot + :CountRoot WHERE Id = :ChannelId", map[string]interface{}{"LastPostAt": maxDateNewPosts[channelId], "ChannelId": channelId, "Count": count, "CountRoot": countRoot}); err != nil {
mlog.Warn("Error updating Channel LastPostAt.", mlog.Err(err))
}
}

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

@@ -1177,7 +1177,7 @@ func (s SqlTeamStore) GetTeamsForUserWithPagination(userId string, page, perPage
// for all the channels in all the teams except the excluded ones.
func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string) ([]*model.ChannelUnread, error) {
query, args, err := s.getQueryBuilder().
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
From("Channels").
Join("ChannelMembers ON Id = ChannelId").
Where(sq.Eq{"UserId": userId, "DeleteAt": 0}).
@@ -1199,7 +1199,7 @@ func (s SqlTeamStore) GetChannelUnreadsForAllTeams(excludeTeamId, userId string)
// GetChannelUnreadsForTeam returns unreads msg count, mention counts and notifyProps for all the channels in a single team.
func (s SqlTeamStore) GetChannelUnreadsForTeam(teamId, userId string) ([]*model.ChannelUnread, error) {
query, args, err := s.getQueryBuilder().
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
Select("Channels.TeamId TeamId", "Channels.Id ChannelId", "(Channels.TotalMsgCount - ChannelMembers.MsgCount) MsgCount", "(Channels.TotalMsgCountRoot - ChannelMembers.MsgCountRoot) MsgCountRoot", "ChannelMembers.MentionCount MentionCount", "ChannelMembers.NotifyProps NotifyProps").
From("Channels").
Join("ChannelMembers ON Id = ChannelId").
Where(sq.Eq{"UserId": userId, "TeamId": teamId, "DeleteAt": 0}).ToSql()

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

@@ -1011,6 +1011,57 @@ func upgradeDatabaseToVersion535(sqlStore *SqlStore) {
sqlStore.CreateColumnIfNotExists("SidebarCategories", "Collapsed", "tinyint(1)", "boolean", "0")
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "TotalMsgCountRoot", "bigint", "bigint")
sqlStore.CreateColumnIfNotExistsNoDefault("Channels", "LastRootPostAt", "bigint", "bigint")
defer sqlStore.RemoveColumnIfExists("Channels", "LastRootPostAt")
// note: setting default 0 on pre-5.0 tables causes test-db-migration script to fail, so this column will be added to ignore list
sqlStore.CreateColumnIfNotExists("ChannelMembers", "MsgCountRoot", "bigint", "bigint", "0")
sqlStore.AlterColumnDefaultIfExists("ChannelMembers", "MsgCountRoot", model.NewString("0"), model.NewString("0"))
forceIndex := ""
if sqlStore.DriverName() == model.DATABASE_DRIVER_MYSQL {
forceIndex = "FORCE INDEX(idx_posts_channel_id)"
}
totalMsgCountRootCTE := `
SELECT Channels.Id channelid, COALESCE(COUNT(*),0) newcount, COALESCE(MAX(Posts.CreateAt), 0) as lastpost
FROM Channels
LEFT JOIN Posts ` + forceIndex + ` ON Channels.Id = Posts.ChannelId
WHERE Posts.RootId = ''
GROUP BY Channels.Id
`
channelsCTE := "SELECT TotalMsgCountRoot, Id, LastRootPostAt from Channels"
updateChannels := `
WITH q AS (` + totalMsgCountRootCTE + `)
UPDATE Channels SET TotalMsgCountRoot = q.newcount, LastRootPostAt=q.lastpost
FROM q where q.channelid=Channels.Id;
`
updateChannelMembers := `
WITH q as (` + channelsCTE + `)
UPDATE ChannelMembers CM SET MsgCountRoot=TotalMsgCountRoot
FROM q WHERE q.id=CM.ChannelId AND LastViewedAt >= q.lastrootpostat;
`
if sqlStore.DriverName() == model.DATABASE_DRIVER_MYSQL {
updateChannels = `
UPDATE Channels
INNER Join (` + totalMsgCountRootCTE + `) as q
ON q.channelid=Channels.Id
SET TotalMsgCountRoot = q.newcount, LastRootPostAt=q.lastpost;
`
updateChannelMembers = `
UPDATE ChannelMembers CM
INNER JOIN (` + channelsCTE + `) as q
ON q.id=CM.ChannelId and LastViewedAt >= q.lastrootpostat
SET MsgCountRoot=TotalMsgCountRoot
`
}
if _, err := sqlStore.GetMaster().Exec(updateChannels); err != nil {
mlog.Error("Error updating Channels table", mlog.Err(err))
}
if _, err := sqlStore.GetMaster().Exec(updateChannelMembers); err != nil {
mlog.Error("Error updating ChannelMembers table", mlog.Err(err))
}
// saveSchemaVersion(sqlStore, Version5350)
// }
}

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

@@ -6,8 +6,10 @@ package sqlstore
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/v5/model"
"github.com/mattermost/mattermost-server/v5/store"
)
@@ -103,3 +105,139 @@ func TestSaveSchemaVersion(t *testing.T) {
})
})
}
func createChannelMemberWithLastViewAt(ss store.Store, channelId, userId string, lastViewAt int64) *model.ChannelMember {
m := model.ChannelMember{}
m.ChannelId = channelId
m.UserId = userId
m.LastViewedAt = lastViewAt
m.NotifyProps = model.GetDefaultChannelNotifyProps()
cm, _ := ss.Channel().SaveMember(&m)
return cm
}
func createPostWithTimestamp(ss store.Store, channelId, userId, rootId, parentId string, timestamp int64) *model.Post {
m := model.Post{}
m.CreateAt = timestamp
m.ChannelId = channelId
m.UserId = userId
m.RootId = rootId
m.ParentId = parentId
m.Message = "zz" + model.NewId() + "b"
p, _ := ss.Post().Save(&m)
return p
}
func createChannelWithLastPostAt(ss store.Store, teamId, creatorId string, lastPostAt, msgCount, rootCount int64) (*model.Channel, error) {
m := model.Channel{}
m.TeamId = teamId
m.TotalMsgCount = msgCount
m.TotalMsgCountRoot = rootCount
m.LastPostAt = lastPostAt
m.CreatorId = creatorId
m.DisplayName = "Name"
m.Name = "zz" + model.NewId() + "b"
m.Type = model.CHANNEL_OPEN
return ss.Channel().Save(&m, -1)
}
func TestMsgCountRootMigration(t *testing.T) {
type TestCaseChannel struct {
Name string
PostTimes []int64
ReplyTimes []int64
MembershipsLastViewAt []int64
ExpectedMembershipMsgCountRoot []int64
}
type TestTableEntry struct {
name string
data []TestCaseChannel
}
testTable := []TestTableEntry{
{
name: "test1",
data: []TestCaseChannel{
{
Name: "channel with one post",
PostTimes: []int64{1000},
ReplyTimes: []int64{0},
MembershipsLastViewAt: []int64{1},
ExpectedMembershipMsgCountRoot: []int64{0},
},
{
Name: "channel with one post, read",
PostTimes: []int64{1000},
ReplyTimes: []int64{0},
MembershipsLastViewAt: []int64{1000},
ExpectedMembershipMsgCountRoot: []int64{1},
},
{
Name: "with one reply, viewed after 2nd root",
PostTimes: []int64{1000, 2000, 3000, 4000},
ReplyTimes: []int64{1001, 0, 0, 0},
MembershipsLastViewAt: []int64{2001},
ExpectedMembershipMsgCountRoot: []int64{0},
},
{
Name: "two replies, 3 memberships",
PostTimes: []int64{1000, 2000, 3000},
ReplyTimes: []int64{1001, 2001, 0},
MembershipsLastViewAt: []int64{2000, 5000, 0},
ExpectedMembershipMsgCountRoot: []int64{0, 3, 0},
},
},
},
}
for _, testCase := range testTable {
t.Run(testCase.name, func(t *testing.T) {
StoreTest(t, func(t *testing.T, ss store.Store) {
sqlStore := ss.(*SqlStore)
team := createTeam(ss)
for _, testChannel := range testCase.data {
t.Run(testChannel.Name, func(t *testing.T) {
lastPostAt := int64(0)
for i := range testChannel.PostTimes {
if testChannel.PostTimes[i] > lastPostAt {
lastPostAt = testChannel.PostTimes[i]
}
if testChannel.ReplyTimes[i] > lastPostAt {
lastPostAt = testChannel.ReplyTimes[i]
}
}
channel, err := createChannelWithLastPostAt(ss, team.Id, model.NewId(), lastPostAt, int64(len(testChannel.PostTimes)+len(testChannel.ReplyTimes)), int64(len(testChannel.PostTimes)))
require.NoError(t, err)
var userIds []string
for _, md := range testChannel.MembershipsLastViewAt {
user := createUser(ss)
userIds = append(userIds, user.Id)
require.NotNil(t, user)
cm := createChannelMemberWithLastViewAt(ss, channel.Id, user.Id, md)
require.NotNil(t, cm)
}
for i, pt := range testChannel.PostTimes {
rt := testChannel.ReplyTimes[i]
post := createPostWithTimestamp(ss, channel.Id, model.NewId(), "", "", pt)
require.NotNil(t, post)
if rt > 0 {
reply := createPostWithTimestamp(ss, channel.Id, model.NewId(), post.Id, post.Id, rt)
require.NotNil(t, reply)
}
}
upgradeDatabaseToVersion535(sqlStore)
members, err := ss.Channel().GetMembersByIds(channel.Id, userIds)
require.NoError(t, err)
for _, m := range *members {
for i, uid := range userIds {
if m.UserId == uid {
assert.Equal(t, testChannel.ExpectedMembershipMsgCountRoot[i], m.MsgCountRoot)
break
}
}
}
})
}
})
})
}
}

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

@@ -194,7 +194,7 @@ type ChannelStore interface {
PermanentDeleteMembersByChannel(channelID string) error
UpdateLastViewedAt(channelIds []string, userId string, updateThreads bool) (map[string]int64, error)
UpdateLastViewedAtPost(unreadPost *model.Post, userID string, mentionCount int, updateThreads bool) (*model.ChannelUnreadAt, error)
CountPostsAfter(channelID string, timestamp int64, userId string) (int, error)
CountPostsAfter(channelID string, timestamp int64, userId string) (int, int, error)
IncrementMentionCount(channelID string, userId string, updateThreads bool) error
AnalyticsTypeCount(teamID string, channelType string) (int64, error)
GetMembersForUser(teamID string, userId string) (*model.ChannelMembers, error)

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

@@ -327,20 +327,20 @@ func testGetChannelUnread(t *testing.T, ss store.Store) {
notifyPropsModel := model.GetDefaultChannelNotifyProps()
// Setup Channel 1
c1 := &model.Channel{TeamId: m1.TeamId, Name: model.NewId(), DisplayName: "Downtown", Type: model.CHANNEL_OPEN, TotalMsgCount: 100}
c1 := &model.Channel{TeamId: m1.TeamId, Name: model.NewId(), DisplayName: "Downtown", Type: model.CHANNEL_OPEN, TotalMsgCount: 100, TotalMsgCountRoot: 99}
_, nErr = ss.Channel().Save(c1, -1)
require.NoError(t, nErr)
cm1 := &model.ChannelMember{ChannelId: c1.Id, UserId: m1.UserId, NotifyProps: notifyPropsModel, MsgCount: 90}
cm1 := &model.ChannelMember{ChannelId: c1.Id, UserId: m1.UserId, NotifyProps: notifyPropsModel, MsgCount: 90, MsgCountRoot: 80}
_, err := ss.Channel().SaveMember(cm1)
require.NoError(t, err)
// Setup Channel 2
c2 := &model.Channel{TeamId: m2.TeamId, Name: model.NewId(), DisplayName: "Cultural", Type: model.CHANNEL_OPEN, TotalMsgCount: 100}
c2 := &model.Channel{TeamId: m2.TeamId, Name: model.NewId(), DisplayName: "Cultural", Type: model.CHANNEL_OPEN, TotalMsgCount: 100, TotalMsgCountRoot: 100}
_, nErr = ss.Channel().Save(c2, -1)
require.NoError(t, nErr)
cm2 := &model.ChannelMember{ChannelId: c2.Id, UserId: m2.UserId, NotifyProps: notifyPropsModel, MsgCount: 90, MentionCount: 5}
cm2 := &model.ChannelMember{ChannelId: c2.Id, UserId: m2.UserId, NotifyProps: notifyPropsModel, MsgCount: 90, MsgCountRoot: 90, MentionCount: 5}
_, err = ss.Channel().SaveMember(cm2)
require.NoError(t, err)
@@ -353,7 +353,7 @@ func testGetChannelUnread(t *testing.T, ss store.Store) {
require.NotNil(t, ch.NotifyProps, "wrong props for channel 1")
require.EqualValues(t, 0, ch.MentionCount, "wrong MentionCount for channel 1")
require.EqualValues(t, 10, ch.MsgCount, "wrong MsgCount for channel 1")
require.EqualValues(t, 19, ch.MsgCountRoot, "wrong MsgCountRoot for channel 1")
// Check for Channel 2
ch2, nErr := ss.Channel().GetChannelUnread(c2.Id, uid)
@@ -4007,19 +4007,19 @@ func testCountPostsAfter(t *testing.T, ss store.Store) {
})
require.NoError(t, err)
count, err := ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, "")
count, _, err := ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, "")
require.NoError(t, err)
assert.Equal(t, 3, count)
count, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, "")
count, _, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, "")
require.NoError(t, err)
assert.Equal(t, 2, count)
count, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, userId1)
count, _, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, userId1)
require.NoError(t, err)
assert.Equal(t, 2, count)
count, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, userId1)
count, _, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, userId1)
require.NoError(t, err)
assert.Equal(t, 1, count)
})
@@ -4044,11 +4044,11 @@ func testCountPostsAfter(t *testing.T, ss store.Store) {
})
require.NoError(t, err)
count, err := ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, "")
count, _, err := ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, "")
require.NoError(t, err)
assert.Equal(t, 1, count)
count, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, "")
count, _, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, "")
require.NoError(t, err)
assert.Equal(t, 0, count)
})
@@ -4105,19 +4105,19 @@ func testCountPostsAfter(t *testing.T, ss store.Store) {
})
require.NoError(t, err)
count, err := ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, "")
count, _, err := ss.Channel().CountPostsAfter(channelId, p1.CreateAt-1, "")
require.NoError(t, err)
assert.Equal(t, 3, count)
count, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, "")
count, _, err = ss.Channel().CountPostsAfter(channelId, p1.CreateAt, "")
require.NoError(t, err)
assert.Equal(t, 2, count)
count, err = ss.Channel().CountPostsAfter(channelId, p5.CreateAt-1, "")
count, _, err = ss.Channel().CountPostsAfter(channelId, p5.CreateAt-1, "")
require.NoError(t, err)
assert.Equal(t, 2, count)
count, err = ss.Channel().CountPostsAfter(channelId, p5.CreateAt, "")
count, _, err = ss.Channel().CountPostsAfter(channelId, p5.CreateAt, "")
require.NoError(t, err)
assert.Equal(t, 1, count)
})
@@ -6345,9 +6345,9 @@ func testMaterializedPublicChannels(t *testing.T, ss store.Store, s SqlStore) {
_, execerr = s.GetMaster().ExecNoTimeout(`
INSERT INTO
Channels(Id, CreateAt, UpdateAt, DeleteAt, TeamId, Type, DisplayName, Name, Header, Purpose, LastPostAt, TotalMsgCount, ExtraUpdateAt, CreatorId)
Channels(Id, CreateAt, UpdateAt, DeleteAt, TeamId, Type, DisplayName, Name, Header, Purpose, LastPostAt, TotalMsgCount, ExtraUpdateAt, CreatorId, TotalMsgCountRoot)
VALUES
(:Id, :CreateAt, :UpdateAt, :DeleteAt, :TeamId, :Type, :DisplayName, :Name, :Header, :Purpose, :LastPostAt, :TotalMsgCount, :ExtraUpdateAt, :CreatorId);
(:Id, :CreateAt, :UpdateAt, :DeleteAt, :TeamId, :Type, :DisplayName, :Name, :Header, :Purpose, :LastPostAt, :TotalMsgCount, :ExtraUpdateAt, :CreatorId, 0);
`, map[string]interface{}{
"Id": o3.Id,
"CreateAt": o3.CreateAt,

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

@@ -140,7 +140,7 @@ func (_m *ChannelStore) ClearSidebarOnTeamLeave(userId string, teamID string) er
}
// CountPostsAfter provides a mock function with given fields: channelID, timestamp, userId
func (_m *ChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, error) {
func (_m *ChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, int, error) {
ret := _m.Called(channelID, timestamp, userId)
var r0 int
@@ -150,14 +150,21 @@ func (_m *ChannelStore) CountPostsAfter(channelID string, timestamp int64, userI
r0 = ret.Get(0).(int)
}
var r1 error
if rf, ok := ret.Get(1).(func(string, int64, string) error); ok {
var r1 int
if rf, ok := ret.Get(1).(func(string, int64, string) int); ok {
r1 = rf(channelID, timestamp, userId)
} else {
r1 = ret.Error(1)
r1 = ret.Get(1).(int)
}
return r0, r1
var r2 error
if rf, ok := ret.Get(2).(func(string, int64, string) error); ok {
r2 = rf(channelID, timestamp, userId)
} else {
r2 = ret.Error(2)
}
return r0, r1, r2
}
// CreateDirectChannel provides a mock function with given fields: userId, otherUserId

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

@@ -599,10 +599,10 @@ func (s *TimerLayerChannelStore) ClearSidebarOnTeamLeave(userId string, teamID s
return err
}
func (s *TimerLayerChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, error) {
func (s *TimerLayerChannelStore) CountPostsAfter(channelID string, timestamp int64, userId string) (int, int, error) {
start := timemodule.Now()
result, err := s.ChannelStore.CountPostsAfter(channelID, timestamp, userId)
result, resultVar1, err := s.ChannelStore.CountPostsAfter(channelID, timestamp, userId)
elapsed := float64(timemodule.Since(start)) / float64(timemodule.Second)
if s.Root.Metrics != nil {
@@ -612,7 +612,7 @@ func (s *TimerLayerChannelStore) CountPostsAfter(channelID string, timestamp int
}
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.CountPostsAfter", success, elapsed)
}
return result, err
return result, resultVar1, err
}
func (s *TimerLayerChannelStore) CreateDirectChannel(userId *model.User, otherUserId *model.User) (*model.Channel, error) {