Remove unused GetChannelCounts store and app methods (#36351)

GetChannelCounts was only reachable from App and had no callers.
Remove SqlChannelStore implementation, store interface, timer/retry
layers, tests, mock, model.ChannelCounts, and the orphaned i18n key.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Julien Tant <JulienTant@users.noreply.github.com>
This commit is contained in:
Julien Tant
2026-05-05 10:04:36 -07:00
committed by GitHub
co-authored by Cursor Agent Julien Tant
parent c787d06506
commit 2b753c49f2
9 changed files with 0 additions and 201 deletions
-9
View File
@@ -2518,15 +2518,6 @@ func (a *App) GetChannelPinnedPostCount(rctx request.CTX, channelID string) (int
return count, nil
}
func (a *App) GetChannelCounts(rctx request.CTX, teamID string, userID string) (*model.ChannelCounts, *model.AppError) {
counts, err := a.Srv().Store().Channel().GetChannelCounts(teamID, userID)
if err != nil {
return nil, model.NewAppError("SqlChannelStore.GetChannelCounts", "app.channel.get_channel_counts.get.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
}
return counts, nil
}
func (a *App) GetChannelUnread(rctx request.CTX, channelID, userID string) (*model.ChannelUnread, *model.AppError) {
channelUnread, err := a.Srv().Store().Channel().GetChannelUnread(channelID, userID)
if err != nil {
@@ -1941,27 +1941,6 @@ func (s *RetryLayerChannelStore) GetByNamesIncludeDeleted(teamID string, names [
}
func (s *RetryLayerChannelStore) GetChannelCounts(teamID string, userID string) (*model.ChannelCounts, error) {
tries := 0
for {
result, err := s.ChannelStore.GetChannelCounts(teamID, userID)
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
}
timepkg.Sleep(100 * timepkg.Millisecond)
}
}
func (s *RetryLayerChannelStore) GetChannelMembersForExport(userID string, teamID string, includeArchivedChannel bool) ([]*model.ChannelMemberForExport, error) {
tries := 0
@@ -1429,38 +1429,6 @@ func (s SqlChannelStore) GetPublicChannelsByIdsForTeam(teamId string, channelIds
return data, nil
}
func (s SqlChannelStore) GetChannelCounts(teamId string, userId string) (*model.ChannelCounts, error) {
data := []struct {
Id string
TotalMsgCount int64
TotalMsgCountRoot int64
UpdateAt int64
}{}
err := s.GetReplica().Select(&data, `SELECT Id, TotalMsgCount, TotalMsgCountRoot, UpdateAt
FROM Channels
WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = ?)
AND (TeamId = ? OR TeamId = '')
AND DeleteAt = 0
ORDER BY DisplayName`, userId, teamId)
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),
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
}
return counts, nil
}
func (s SqlChannelStore) GetTeamChannels(teamId string) (model.ChannelList, error) {
data := model.ChannelList{}
query := s.tableSelectQuery.Where(sq.And{sq.Eq{"TeamId": teamId}, sq.NotEq{"Type": model.ChannelTypeDirect}}).OrderBy("DisplayName")
-1
View File
@@ -223,7 +223,6 @@ type ChannelStore interface {
GetPrivateChannelsForTeam(teamID string, offset int, limit int) (model.ChannelList, error)
GetPublicChannelsForTeam(teamID string, offset int, limit int) (model.ChannelList, error)
GetPublicChannelsByIdsForTeam(teamID string, channelIds []string) (model.ChannelList, error)
GetChannelCounts(teamID string, userID string) (*model.ChannelCounts, error)
GetTeamChannels(teamID string) (model.ChannelList, error)
GetAll(teamID string) ([]*model.Channel, error)
GetChannelsByIds(channelIds []string, includeDeleted bool) ([]*model.Channel, error)
@@ -119,7 +119,6 @@ func TestChannelStore(t *testing.T, rctx request.CTX, ss store.Store, s SqlStore
t.Run("GetPrivateChannelsForTeam", func(t *testing.T) { testChannelStoreGetPrivateChannelsForTeam(t, rctx, ss) })
t.Run("GetPublicChannelsForTeam", func(t *testing.T) { testChannelStoreGetPublicChannelsForTeam(t, rctx, ss) })
t.Run("GetPublicChannelsByIdsForTeam", func(t *testing.T) { testChannelStoreGetPublicChannelsByIdsForTeam(t, rctx, ss) })
t.Run("GetChannelCounts", func(t *testing.T) { testChannelStoreGetChannelCounts(t, rctx, ss) })
t.Run("GetMembersForUser", func(t *testing.T) { testChannelStoreGetMembersForUser(t, rctx, ss) })
t.Run("GetMembersForUserWithPagination", func(t *testing.T) { testChannelStoreGetMembersForUserWithPagination(t, rctx, ss) })
t.Run("GetMembersForUserWithCursorPagination", func(t *testing.T) { testChannelStoreGetMembersForUserWithCursorPagination(t, rctx, ss) })
@@ -4612,50 +4611,6 @@ func testChannelStoreGetPublicChannelsByIdsForTeam(t *testing.T, rctx request.CT
})
}
func testChannelStoreGetChannelCounts(t *testing.T, rctx request.CTX, ss store.Store) {
o2 := model.Channel{}
o2.TeamId = model.NewId()
o2.DisplayName = "Channel2"
o2.Name = NewTestID()
o2.Type = model.ChannelTypeOpen
_, nErr := ss.Channel().Save(rctx, &o2, -1)
require.NoError(t, nErr)
o1 := model.Channel{}
o1.TeamId = model.NewId()
o1.DisplayName = "Channel1"
o1.Name = NewTestID()
o1.Type = model.ChannelTypeOpen
_, nErr = ss.Channel().Save(rctx, &o1, -1)
require.NoError(t, nErr)
m1 := model.ChannelMember{}
m1.ChannelId = o1.Id
m1.UserId = model.NewId()
m1.NotifyProps = model.GetDefaultChannelNotifyProps()
_, err := ss.Channel().SaveMember(rctx, &m1)
require.NoError(t, err)
m2 := model.ChannelMember{}
m2.ChannelId = o1.Id
m2.UserId = model.NewId()
m2.NotifyProps = model.GetDefaultChannelNotifyProps()
_, err = ss.Channel().SaveMember(rctx, &m2)
require.NoError(t, err)
m3 := model.ChannelMember{}
m3.ChannelId = o2.Id
m3.UserId = model.NewId()
m3.NotifyProps = model.GetDefaultChannelNotifyProps()
_, err = ss.Channel().SaveMember(rctx, &m3)
require.NoError(t, err)
counts, _ := ss.Channel().GetChannelCounts(o1.TeamId, m1.UserId)
require.Len(t, counts.Counts, 1, "wrong number of counts")
require.Len(t, counts.UpdateTimes, 1, "wrong number of update times")
}
func testChannelStoreGetMembersForUser(t *testing.T, rctx request.CTX, ss store.Store) {
t1 := model.Team{}
t1.DisplayName = "Name"
@@ -889,36 +889,6 @@ func (_m *ChannelStore) GetByNamesIncludeDeleted(teamID string, names []string,
return r0, r1
}
// GetChannelCounts provides a mock function with given fields: teamID, userID
func (_m *ChannelStore) GetChannelCounts(teamID string, userID string) (*model.ChannelCounts, error) {
ret := _m.Called(teamID, userID)
if len(ret) == 0 {
panic("no return value specified for GetChannelCounts")
}
var r0 *model.ChannelCounts
var r1 error
if rf, ok := ret.Get(0).(func(string, string) (*model.ChannelCounts, error)); ok {
return rf(teamID, userID)
}
if rf, ok := ret.Get(0).(func(string, string) *model.ChannelCounts); ok {
r0 = rf(teamID, userID)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.ChannelCounts)
}
}
if rf, ok := ret.Get(1).(func(string, string) error); ok {
r1 = rf(teamID, userID)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetChannelMembersForExport provides a mock function with given fields: userID, teamID, includeArchivedChannel
func (_m *ChannelStore) GetChannelMembersForExport(userID string, teamID string, includeArchivedChannel bool) ([]*model.ChannelMemberForExport, error) {
ret := _m.Called(userID, teamID, includeArchivedChannel)
@@ -1673,22 +1673,6 @@ func (s *TimerLayerChannelStore) GetByNamesIncludeDeleted(teamID string, names [
return result, err
}
func (s *TimerLayerChannelStore) GetChannelCounts(teamID string, userID string) (*model.ChannelCounts, error) {
start := time.Now()
result, err := s.ChannelStore.GetChannelCounts(teamID, userID)
elapsed := float64(time.Since(start)) / float64(time.Second)
if s.Root.Metrics != nil {
success := "false"
if err == nil {
success = "true"
}
s.Root.Metrics.ObserveStoreMethodDuration("ChannelStore.GetChannelCounts", success, elapsed)
}
return result, err
}
func (s *TimerLayerChannelStore) GetChannelMembersForExport(userID string, teamID string, includeArchivedChannel bool) ([]*model.ChannelMemberForExport, error) {
start := time.Now()
-4
View File
@@ -5478,10 +5478,6 @@
"id": "app.channel.get_by_scheme.app_error",
"translation": "Unable to get the channels for the provided scheme."
},
{
"id": "app.channel.get_channel_counts.get.app_error",
"translation": "Unable to get the channel counts."
},
{
"id": "app.channel.get_channels.get.app_error",
"translation": "Unable to get the channels."
-43
View File
@@ -1,43 +0,0 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package model
import (
"crypto/md5"
"fmt"
"sort"
"strconv"
"strings"
)
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 derivative
ids := []string{}
for id := range o.Counts {
ids = append(ids, id)
}
sort.Strings(ids)
var str strings.Builder
for _, id := range ids {
str.WriteString(id + strconv.FormatInt(o.Counts[id], 10))
}
md5Counts := fmt.Sprintf("%x", md5.Sum([]byte(str.String())))
var update int64
for _, u := range o.UpdateTimes {
if u > update {
update = u
}
}
return Etag(md5Counts, update)
}