summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
authorGeorge Goldberg <george@gberg.me>2018-03-13 13:36:23 +0000
committerGeorge Goldberg <george@gberg.me>2018-03-13 13:36:23 +0000
commitfadcdd271a68b38571b75d1d38ab023f940ac83a (patch)
tree7f413edd35401b54b2f4eb4a687da1ac273bcd4b /store
parentb66e4bc932ed76c1cfd2b5f4ec0cfce70cd9fbb4 (diff)
parentf2d26801b9647715fb43af873354d8def753868b (diff)
downloadchat-fadcdd271a68b38571b75d1d38ab023f940ac83a.tar.gz
chat-fadcdd271a68b38571b75d1d38ab023f940ac83a.tar.bz2
chat-fadcdd271a68b38571b75d1d38ab023f940ac83a.zip
Merge branch 'master' into advanced-permissions-phase-1
Diffstat (limited to 'store')
-rw-r--r--store/layered_store_supplier.go2
-rw-r--r--store/sqlstore/channel_store.go60
-rw-r--r--store/sqlstore/compliance_store.go9
-rw-r--r--store/sqlstore/file_info_store.go8
-rw-r--r--store/sqlstore/post_store.go12
-rw-r--r--store/sqlstore/upgrade.go14
-rw-r--r--store/sqlstore/user_store.go66
-rw-r--r--store/sqlstore/webhook_store.go15
-rw-r--r--store/store.go7
-rw-r--r--store/storetest/channel_store.go49
-rw-r--r--store/storetest/compliance_store.go300
-rw-r--r--store/storetest/mocks/ChannelStore.go21
-rw-r--r--store/storetest/mocks/FileInfoStore.go5
-rw-r--r--store/storetest/mocks/PostStore.go5
-rw-r--r--store/storetest/mocks/TeamStore.go20
-rw-r--r--store/storetest/mocks/UserStore.go21
-rw-r--r--store/storetest/mocks/WebhookStore.go5
-rw-r--r--store/storetest/user_store.go77
18 files changed, 560 insertions, 136 deletions
diff --git a/store/layered_store_supplier.go b/store/layered_store_supplier.go
index 482ccd126..80fe3cb24 100644
--- a/store/layered_store_supplier.go
+++ b/store/layered_store_supplier.go
@@ -6,8 +6,6 @@ package store
import "github.com/mattermost/mattermost-server/model"
import "context"
-type ResultHandler func(*StoreResult)
-
type LayeredStoreSupplierResult struct {
StoreResult
}
diff --git a/store/sqlstore/channel_store.go b/store/sqlstore/channel_store.go
index 131e5649b..e7a157192 100644
--- a/store/sqlstore/channel_store.go
+++ b/store/sqlstore/channel_store.go
@@ -43,12 +43,20 @@ var allChannelMembersNotifyPropsForChannelCache = utils.NewLru(ALL_CHANNEL_MEMBE
var channelCache = utils.NewLru(model.CHANNEL_CACHE_SIZE)
var channelByNameCache = utils.NewLru(model.CHANNEL_CACHE_SIZE)
-func ClearChannelCaches() {
+func (s SqlChannelStore) ClearCaches() {
channelMemberCountsCache.Purge()
allChannelMembersForUserCache.Purge()
allChannelMembersNotifyPropsForChannelCache.Purge()
channelCache.Purge()
channelByNameCache.Purge()
+
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Channel Member Counts - Purge")
+ s.metrics.IncrementMemCacheInvalidationCounter("All Channel Members for User - Purge")
+ s.metrics.IncrementMemCacheInvalidationCounter("All Channel Members Notify Props for Channel - Purge")
+ s.metrics.IncrementMemCacheInvalidationCounter("Channel - Purge")
+ s.metrics.IncrementMemCacheInvalidationCounter("Channel By Name - Purge")
+ }
}
func NewSqlChannelStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.ChannelStore {
@@ -308,12 +316,18 @@ func (s SqlChannelStore) GetChannelUnread(channelId, userId string) store.StoreC
})
}
-func (us SqlChannelStore) InvalidateChannel(id string) {
+func (s SqlChannelStore) InvalidateChannel(id string) {
channelCache.Remove(id)
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Channel - Remove by ChannelId")
+ }
}
-func (us SqlChannelStore) InvalidateChannelByName(teamId, name string) {
+func (s SqlChannelStore) InvalidateChannelByName(teamId, name string) {
channelByNameCache.Remove(teamId + name)
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Channel by Name - Remove by TeamId and Name")
+ }
}
func (s SqlChannelStore) Get(id string, allowFromCache bool) store.StoreChannel {
@@ -814,14 +828,17 @@ func (s SqlChannelStore) GetMember(channelId string, userId string) store.StoreC
})
}
-func (us SqlChannelStore) InvalidateAllChannelMembersForUser(userId string) {
+func (s SqlChannelStore) InvalidateAllChannelMembersForUser(userId string) {
allChannelMembersForUserCache.Remove(userId)
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("All Channel Members for User - Remove by UserId")
+ }
}
-func (us SqlChannelStore) IsUserInChannelUseCache(userId string, channelId string) bool {
+func (s SqlChannelStore) IsUserInChannelUseCache(userId string, channelId string) bool {
if cacheItem, ok := allChannelMembersForUserCache.Get(userId); ok {
- if us.metrics != nil {
- us.metrics.IncrementMemCacheHitCounter("All Channel Members for User")
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheHitCounter("All Channel Members for User")
}
ids := cacheItem.(map[string]string)
if _, ok := ids[channelId]; ok {
@@ -830,12 +847,12 @@ func (us SqlChannelStore) IsUserInChannelUseCache(userId string, channelId strin
return false
}
} else {
- if us.metrics != nil {
- us.metrics.IncrementMemCacheMissCounter("All Channel Members for User")
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheMissCounter("All Channel Members for User")
}
}
- if result := <-us.GetAllChannelMembersForUser(userId, true); result.Err != nil {
+ if result := <-s.GetAllChannelMembersForUser(userId, true); result.Err != nil {
l4g.Error("SqlChannelStore.IsUserInChannelUseCache: " + result.Err.Error())
return false
} else {
@@ -915,8 +932,11 @@ func (s SqlChannelStore) GetAllChannelMembersForUser(userId string, allowFromCac
})
}
-func (us SqlChannelStore) InvalidateCacheForChannelMembersNotifyProps(channelId string) {
+func (s SqlChannelStore) InvalidateCacheForChannelMembersNotifyProps(channelId string) {
allChannelMembersNotifyPropsForChannelCache.Remove(channelId)
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("All Channel Members Notify Props for Channel - Remove by ChannelId")
+ }
}
type allChannelMemberNotifyProps struct {
@@ -966,8 +986,11 @@ func (s SqlChannelStore) GetAllChannelMembersNotifyPropsForChannel(channelId str
})
}
-func (us SqlChannelStore) InvalidateMemberCount(channelId string) {
+func (s SqlChannelStore) InvalidateMemberCount(channelId string) {
channelMemberCountsCache.Remove(channelId)
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Channel Member Counts - Remove by ChannelId")
+ }
}
func (s SqlChannelStore) GetMemberCountFromCache(channelId string) int64 {
@@ -1225,19 +1248,6 @@ func (s SqlChannelStore) AnalyticsDeletedTypeCount(teamId string, channelType st
})
}
-func (s SqlChannelStore) ExtraUpdateByUser(userId string, time int64) store.StoreChannel {
- return store.Do(func(result *store.StoreResult) {
- _, err := s.GetMaster().Exec(
- `UPDATE Channels SET ExtraUpdateAt = :Time
- WHERE Id IN (SELECT ChannelId FROM ChannelMembers WHERE UserId = :UserId);`,
- map[string]interface{}{"UserId": userId, "Time": time})
-
- if err != nil {
- result.Err = model.NewAppError("SqlChannelStore.extraUpdated", "store.sql_channel.extra_updated.app_error", nil, "user_id="+userId+", "+err.Error(), http.StatusInternalServerError)
- }
- })
-}
-
func (s SqlChannelStore) GetMembersForUser(teamId string, userId string) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
members := &model.ChannelMembers{}
diff --git a/store/sqlstore/compliance_store.go b/store/sqlstore/compliance_store.go
index 03d92d5e1..c3c75581e 100644
--- a/store/sqlstore/compliance_store.go
+++ b/store/sqlstore/compliance_store.go
@@ -138,6 +138,7 @@ func (s SqlComplianceStore) ComplianceExport(job *model.Compliance) store.StoreC
Teams.DisplayName AS TeamDisplayName,
Channels.Name AS ChannelName,
Channels.DisplayName AS ChannelDisplayName,
+ Channels.Type AS ChannelType,
Users.Username AS UserUsername,
Users.Email AS UserEmail,
Users.Nickname AS UserNickname,
@@ -172,6 +173,7 @@ func (s SqlComplianceStore) ComplianceExport(job *model.Compliance) store.StoreC
'Direct Messages' AS TeamDisplayName,
Channels.Name AS ChannelName,
Channels.DisplayName AS ChannelDisplayName,
+ Channels.Type AS ChannelType,
Users.Username AS UserUsername,
Users.Email AS UserEmail,
Users.Nickname AS UserNickname,
@@ -223,7 +225,12 @@ func (s SqlComplianceStore) MessageExport(after int64, limit int) store.StoreCha
Posts.Type AS PostType,
Posts.FileIds AS PostFileIds,
Channels.Id AS ChannelId,
- Channels.DisplayName AS ChannelDisplayName,
+ CASE
+ WHEN Channels.Type = 'D' THEN 'Direct Message'
+ WHEN Channels.Type = 'G' THEN 'Group Message'
+ ELSE Channels.DisplayName
+ END AS ChannelDisplayName,
+ Channels.Type AS ChannelType,
Users.Id AS UserId,
Users.Email AS UserEmail,
Users.Username
diff --git a/store/sqlstore/file_info_store.go b/store/sqlstore/file_info_store.go
index 1d0767d1e..7559640c8 100644
--- a/store/sqlstore/file_info_store.go
+++ b/store/sqlstore/file_info_store.go
@@ -25,8 +25,11 @@ const (
var fileInfoCache *utils.Cache = utils.NewLru(FILE_INFO_CACHE_SIZE)
-func ClearFileCaches() {
+func (fs SqlFileInfoStore) ClearCaches() {
fileInfoCache.Purge()
+ if fs.metrics != nil {
+ fs.metrics.IncrementMemCacheInvalidationCounter("File Info Cache - Purge")
+ }
}
func NewSqlFileInfoStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.FileInfoStore {
@@ -118,6 +121,9 @@ func (fs SqlFileInfoStore) GetByPath(path string) store.StoreChannel {
func (fs SqlFileInfoStore) InvalidateFileInfosForPostCache(postId string) {
fileInfoCache.Remove(postId)
+ if fs.metrics != nil {
+ fs.metrics.IncrementMemCacheInvalidationCounter("File Info Cache - Remove by PostId")
+ }
}
func (fs SqlFileInfoStore) GetForPost(postId string, readFromMaster bool, allowFromCache bool) store.StoreChannel {
diff --git a/store/sqlstore/post_store.go b/store/sqlstore/post_store.go
index 25c3c4913..92ee28ffa 100644
--- a/store/sqlstore/post_store.go
+++ b/store/sqlstore/post_store.go
@@ -35,9 +35,14 @@ const (
var lastPostTimeCache = utils.NewLru(LAST_POST_TIME_CACHE_SIZE)
var lastPostsCache = utils.NewLru(LAST_POSTS_CACHE_SIZE)
-func ClearPostCaches() {
+func (s SqlPostStore) ClearCaches() {
lastPostTimeCache.Purge()
lastPostsCache.Purge()
+
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Last Post Time - Purge")
+ s.metrics.IncrementMemCacheInvalidationCounter("Last Posts Cache - Purge")
+ }
}
func NewSqlPostStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.PostStore {
@@ -326,6 +331,11 @@ func (s SqlPostStore) InvalidateLastPostTimeCache(channelId string) {
// Keys are "{channelid}{limit}" and caching only occurs on limits of 30 and 60
lastPostsCache.Remove(channelId + "30")
lastPostsCache.Remove(channelId + "60")
+
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Last Post Time - Remove by Channel Id")
+ s.metrics.IncrementMemCacheInvalidationCounter("Last Posts Cache - Remove by Channel Id")
+ }
}
func (s SqlPostStore) GetEtag(channelId string, allowFromCache bool) store.StoreChannel {
diff --git a/store/sqlstore/upgrade.go b/store/sqlstore/upgrade.go
index de4dbe095..2b4532817 100644
--- a/store/sqlstore/upgrade.go
+++ b/store/sqlstore/upgrade.go
@@ -15,6 +15,7 @@ import (
)
const (
+ VERSION_4_9_0 = "4.9.0"
VERSION_4_8_0 = "4.8.0"
VERSION_4_7_1 = "4.7.1"
VERSION_4_7_0 = "4.7.0"
@@ -68,6 +69,7 @@ func UpgradeDatabase(sqlStore SqlStore) {
UpgradeDatabaseToVersion47(sqlStore)
UpgradeDatabaseToVersion471(sqlStore)
UpgradeDatabaseToVersion48(sqlStore)
+ UpgradeDatabaseToVersion49(sqlStore)
// If the SchemaVersion is empty this this is the first time it has ran
// so lets set it to the current version.
@@ -365,13 +367,19 @@ func UpgradeDatabaseToVersion471(sqlStore SqlStore) {
}
func UpgradeDatabaseToVersion48(sqlStore SqlStore) {
+ if shouldPerformUpgrade(sqlStore, VERSION_4_7_1, VERSION_4_8_0) {
+ saveSchemaVersion(sqlStore, VERSION_4_8_0)
+ }
+}
+
+func UpgradeDatabaseToVersion49(sqlStore SqlStore) {
// This version of Mattermost includes an App-Layer migration which migrates from hard-coded roles configured by
// a number of parameters in `config.json` to a `Roles` table in the database. The migration code can be seen
// in the file `app/app.go` in the function `DoAdvancedPermissionsMigration()`.
- //TODO: Uncomment the following condition when version 4.8.0 is released
- //if shouldPerformUpgrade(sqlStore, VERSION_4_7_0, VERSION_4_8_0) {
+ //TODO: Uncomment the following condition when version 4.9.0 is released
+ //if shouldPerformUpgrade(sqlStore, VERSION_4_8_0, VERSION_4_9_0) {
sqlStore.CreateColumnIfNotExists("Teams", "LastTeamIconUpdate", "bigint", "bigint", "0")
- // saveSchemaVersion(sqlStore, VERSION_4_8_0)
+ // saveSchemaVersion(sqlStore, VERSION_4_9_0)
//}
}
diff --git a/store/sqlstore/user_store.go b/store/sqlstore/user_store.go
index d67a45704..5e84af930 100644
--- a/store/sqlstore/user_store.go
+++ b/store/sqlstore/user_store.go
@@ -38,13 +38,22 @@ type SqlUserStore struct {
var profilesInChannelCache *utils.Cache = utils.NewLru(PROFILES_IN_CHANNEL_CACHE_SIZE)
var profileByIdsCache *utils.Cache = utils.NewLru(PROFILE_BY_IDS_CACHE_SIZE)
-func ClearUserCaches() {
+func (us SqlUserStore) ClearCaches() {
profilesInChannelCache.Purge()
profileByIdsCache.Purge()
+
+ if us.metrics != nil {
+ us.metrics.IncrementMemCacheInvalidationCounter("Profiles in Channel - Purge")
+ us.metrics.IncrementMemCacheInvalidationCounter("Profile By Ids - Purge")
+ }
}
func (us SqlUserStore) InvalidatProfileCacheForUser(userId string) {
profileByIdsCache.Remove(userId)
+
+ if us.metrics != nil {
+ us.metrics.IncrementMemCacheInvalidationCounter("Profile By Ids - Remove")
+ }
}
func NewSqlUserStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.UserStore {
@@ -384,6 +393,9 @@ func (us SqlUserStore) InvalidateProfilesInChannelCacheByUser(userId string) {
userMap := cacheItem.(map[string]*model.User)
if _, userInCache := userMap[userId]; userInCache {
profilesInChannelCache.Remove(key)
+ if us.metrics != nil {
+ us.metrics.IncrementMemCacheInvalidationCounter("Profiles in Channel - Remove by User")
+ }
}
}
}
@@ -391,13 +403,27 @@ func (us SqlUserStore) InvalidateProfilesInChannelCacheByUser(userId string) {
func (us SqlUserStore) InvalidateProfilesInChannelCache(channelId string) {
profilesInChannelCache.Remove(channelId)
+ if us.metrics != nil {
+ us.metrics.IncrementMemCacheInvalidationCounter("Profiles in Channel - Remove by Channel")
+ }
}
func (us SqlUserStore) GetProfilesInChannel(channelId string, offset int, limit int) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
var users []*model.User
- query := "SELECT Users.* FROM Users, ChannelMembers WHERE ChannelMembers.ChannelId = :ChannelId AND Users.Id = ChannelMembers.UserId ORDER BY Users.Username ASC LIMIT :Limit OFFSET :Offset"
+ query := `
+ SELECT
+ Users.*
+ FROM
+ Users, ChannelMembers
+ WHERE
+ ChannelMembers.ChannelId = :ChannelId
+ AND Users.Id = ChannelMembers.UserId
+ ORDER BY
+ Users.Username ASC
+ LIMIT :Limit OFFSET :Offset
+ `
if _, err := us.GetReplica().Select(&users, query, map[string]interface{}{"ChannelId": channelId, "Offset": offset, "Limit": limit}); err != nil {
result.Err = model.NewAppError("SqlUserStore.GetProfilesInChannel", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
@@ -412,6 +438,42 @@ func (us SqlUserStore) GetProfilesInChannel(channelId string, offset int, limit
})
}
+func (us SqlUserStore) GetProfilesInChannelByStatus(channelId string, offset int, limit int) store.StoreChannel {
+ return store.Do(func(result *store.StoreResult) {
+ var users []*model.User
+
+ query := `
+ SELECT
+ Users.*
+ FROM Users
+ INNER JOIN ChannelMembers ON Users.Id = ChannelMembers.UserId
+ LEFT JOIN Status ON Users.Id = Status.UserId
+ WHERE
+ ChannelMembers.ChannelId = :ChannelId
+ ORDER BY
+ CASE Status
+ WHEN 'online' THEN 1
+ WHEN 'away' THEN 2
+ WHEN 'dnd' THEN 3
+ ELSE 4
+ END,
+ Users.Username ASC
+ LIMIT :Limit OFFSET :Offset
+ `
+
+ if _, err := us.GetReplica().Select(&users, query, map[string]interface{}{"ChannelId": channelId, "Offset": offset, "Limit": limit}); err != nil {
+ result.Err = model.NewAppError("SqlUserStore.GetProfilesInChannelByStatus", "store.sql_user.get_profiles.app_error", nil, err.Error(), http.StatusInternalServerError)
+ } else {
+
+ for _, u := range users {
+ u.Sanitize(map[string]bool{})
+ }
+
+ result.Data = users
+ }
+ })
+}
+
func (us SqlUserStore) GetAllProfilesInChannel(channelId string, allowFromCache bool) store.StoreChannel {
return store.Do(func(result *store.StoreResult) {
if allowFromCache {
diff --git a/store/sqlstore/webhook_store.go b/store/sqlstore/webhook_store.go
index 8a3720fa0..45ad90e52 100644
--- a/store/sqlstore/webhook_store.go
+++ b/store/sqlstore/webhook_store.go
@@ -26,8 +26,12 @@ const (
var webhookCache = utils.NewLru(WEBHOOK_CACHE_SIZE)
-func ClearWebhookCaches() {
+func (s SqlWebhookStore) ClearCaches() {
webhookCache.Purge()
+
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Webhook - Purge")
+ }
}
func NewSqlWebhookStore(sqlStore SqlStore, metrics einterfaces.MetricsInterface) store.WebhookStore {
@@ -78,6 +82,9 @@ func (s SqlWebhookStore) CreateIndexesIfNotExists() {
func (s SqlWebhookStore) InvalidateWebhookCache(webhookId string) {
webhookCache.Remove(webhookId)
+ if s.metrics != nil {
+ s.metrics.IncrementMemCacheInvalidationCounter("Webhook - Remove by WebhookId")
+ }
}
func (s SqlWebhookStore) SaveIncoming(webhook *model.IncomingWebhook) store.StoreChannel {
@@ -164,7 +171,7 @@ func (s SqlWebhookStore) PermanentDeleteIncomingByUser(userId string) store.Stor
result.Err = model.NewAppError("SqlWebhookStore.DeleteIncomingByUser", "store.sql_webhooks.permanent_delete_incoming_by_user.app_error", nil, "id="+userId+", err="+err.Error(), http.StatusInternalServerError)
}
- ClearWebhookCaches()
+ s.ClearCaches()
})
}
@@ -175,7 +182,7 @@ func (s SqlWebhookStore) PermanentDeleteIncomingByChannel(channelId string) stor
result.Err = model.NewAppError("SqlWebhookStore.DeleteIncomingByChannel", "store.sql_webhooks.permanent_delete_incoming_by_channel.app_error", nil, "id="+channelId+", err="+err.Error(), http.StatusInternalServerError)
}
- ClearWebhookCaches()
+ s.ClearCaches()
})
}
@@ -322,7 +329,7 @@ func (s SqlWebhookStore) PermanentDeleteOutgoingByChannel(channelId string) stor
result.Err = model.NewAppError("SqlWebhookStore.DeleteOutgoingByChannel", "store.sql_webhooks.permanent_delete_outgoing_by_channel.app_error", nil, "id="+channelId+", err="+err.Error(), http.StatusInternalServerError)
}
- ClearWebhookCaches()
+ s.ClearCaches()
})
}
diff --git a/store/store.go b/store/store.go
index 5da91c071..a4b66d2d1 100644
--- a/store/store.go
+++ b/store/store.go
@@ -154,7 +154,6 @@ type ChannelStore interface {
UpdateLastViewedAt(channelIds []string, userId string) StoreChannel
IncrementMentionCount(channelId string, userId string) StoreChannel
AnalyticsTypeCount(teamId string, channelType string) StoreChannel
- ExtraUpdateByUser(userId string, time int64) StoreChannel
GetMembersForUser(teamId string, userId string) StoreChannel
AutocompleteInTeam(teamId string, term string) StoreChannel
SearchInTeam(teamId string, term string) StoreChannel
@@ -162,6 +161,7 @@ type ChannelStore interface {
GetMembersByIds(channelId string, userIds []string) StoreChannel
AnalyticsDeletedTypeCount(teamId string, channelType string) StoreChannel
GetChannelUnread(channelId, userId string) StoreChannel
+ ClearCaches()
}
type ChannelMemberHistoryStore interface {
@@ -191,6 +191,7 @@ type PostStore interface {
AnalyticsUserCountsWithPostsByDay(teamId string) StoreChannel
AnalyticsPostCountsByDay(teamId string) StoreChannel
AnalyticsPostCount(teamId string, mustHaveFile bool, mustHaveHashtag bool) StoreChannel
+ ClearCaches()
InvalidateLastPostTimeCache(channelId string)
GetPostsCreatedAt(channelId string, time int64) StoreChannel
Overwrite(post *model.Post) StoreChannel
@@ -211,9 +212,11 @@ type UserStore interface {
UpdateMfaActive(userId string, active bool) StoreChannel
Get(id string) StoreChannel
GetAll() StoreChannel
+ ClearCaches()
InvalidateProfilesInChannelCacheByUser(userId string)
InvalidateProfilesInChannelCache(channelId string)
GetProfilesInChannel(channelId string, offset int, limit int) StoreChannel
+ GetProfilesInChannelByStatus(channelId string, offset int, limit int) StoreChannel
GetAllProfilesInChannel(channelId string, allowFromCache bool) StoreChannel
GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int) StoreChannel
GetProfilesWithoutTeam(offset int, limit int) StoreChannel
@@ -344,6 +347,7 @@ type WebhookStore interface {
AnalyticsIncomingCount(teamId string) StoreChannel
AnalyticsOutgoingCount(teamId string) StoreChannel
InvalidateWebhookCache(webhook string)
+ ClearCaches()
}
type CommandStore interface {
@@ -421,6 +425,7 @@ type FileInfoStore interface {
DeleteForPost(postId string) StoreChannel
PermanentDelete(fileId string) StoreChannel
PermanentDeleteBatch(endTime int64, limit int64) StoreChannel
+ ClearCaches()
}
type ReactionStore interface {
diff --git a/store/storetest/channel_store.go b/store/storetest/channel_store.go
index 121b40a01..d3b69edea 100644
--- a/store/storetest/channel_store.go
+++ b/store/storetest/channel_store.go
@@ -43,7 +43,6 @@ func TestChannelStore(t *testing.T, ss store.Store) {
t.Run("GetMember", func(t *testing.T) { testGetMember(t, ss) })
t.Run("GetMemberForPost", func(t *testing.T) { testChannelStoreGetMemberForPost(t, ss) })
t.Run("GetMemberCount", func(t *testing.T) { testGetMemberCount(t, ss) })
- t.Run("UpdateExtrasByUser", func(t *testing.T) { testUpdateExtrasByUser(t, ss) })
t.Run("SearchMore", func(t *testing.T) { testChannelStoreSearchMore(t, ss) })
t.Run("SearchInTeam", func(t *testing.T) { testChannelStoreSearchInTeam(t, ss) })
t.Run("GetMembersByIds", func(t *testing.T) { testChannelStoreGetMembersByIds(t, ss) })
@@ -1641,54 +1640,6 @@ func testGetMemberCount(t *testing.T, ss store.Store) {
}
}
-func testUpdateExtrasByUser(t *testing.T, ss store.Store) {
- teamId := model.NewId()
-
- c1 := model.Channel{
- TeamId: teamId,
- DisplayName: "Channel1",
- Name: "zz" + model.NewId() + "b",
- Type: model.CHANNEL_OPEN,
- }
- store.Must(ss.Channel().Save(&c1, -1))
-
- c2 := model.Channel{
- TeamId: teamId,
- DisplayName: "Channel2",
- Name: "zz" + model.NewId() + "b",
- Type: model.CHANNEL_OPEN,
- }
- store.Must(ss.Channel().Save(&c2, -1))
-
- u1 := &model.User{
- Email: model.NewId(),
- DeleteAt: 0,
- }
- store.Must(ss.User().Save(u1))
- store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}, -1))
-
- m1 := model.ChannelMember{
- ChannelId: c1.Id,
- UserId: u1.Id,
- NotifyProps: model.GetDefaultChannelNotifyProps(),
- }
- store.Must(ss.Channel().SaveMember(&m1))
-
- u1.DeleteAt = model.GetMillis()
- store.Must(ss.User().Update(u1, true))
-
- if result := <-ss.Channel().ExtraUpdateByUser(u1.Id, u1.DeleteAt); result.Err != nil {
- t.Fatalf("failed to update extras by user: %v", result.Err)
- }
-
- u1.DeleteAt = 0
- store.Must(ss.User().Update(u1, true))
-
- if result := <-ss.Channel().ExtraUpdateByUser(u1.Id, u1.DeleteAt); result.Err != nil {
- t.Fatalf("failed to update extras by user: %v", result.Err)
- }
-}
-
func testChannelStoreSearchMore(t *testing.T, ss store.Store) {
o1 := model.Channel{}
o1.TeamId = model.NewId()
diff --git a/store/storetest/compliance_store.go b/store/storetest/compliance_store.go
index eb29bedc7..50a62531f 100644
--- a/store/storetest/compliance_store.go
+++ b/store/storetest/compliance_store.go
@@ -16,7 +16,10 @@ func TestComplianceStore(t *testing.T, ss store.Store) {
t.Run("", func(t *testing.T) { testComplianceStore(t, ss) })
t.Run("ComplianceExport", func(t *testing.T) { testComplianceExport(t, ss) })
t.Run("ComplianceExportDirectMessages", func(t *testing.T) { testComplianceExportDirectMessages(t, ss) })
- t.Run("MessageExport", func(t *testing.T) { testComplianceMessageExport(t, ss) })
+ t.Run("MessageExportPublicChannel", func(t *testing.T) { testMessageExportPublicChannel(t, ss) })
+ t.Run("MessageExportPrivateChannel", func(t *testing.T) { testMessageExportPrivateChannel(t, ss) })
+ t.Run("MessageExportDirectMessageChannel", func(t *testing.T) { testMessageExportDirectMessageChannel(t, ss) })
+ t.Run("MessageExportGroupMessageChannel", func(t *testing.T) { testMessageExportGroupMessageChannel(t, ss) })
}
func testComplianceStore(t *testing.T, ss store.Store) {
@@ -319,7 +322,7 @@ func testComplianceExportDirectMessages(t *testing.T, ss store.Store) {
}
}
-func testComplianceMessageExport(t *testing.T, ss store.Store) {
+func testMessageExportPublicChannel(t *testing.T, ss store.Store) {
// get the starting number of message export entries
startTime := model.GetMillis()
var numMessageExports = 0
@@ -360,15 +363,14 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
UserId: user2.Id,
}, -1))
- // need a public channel as well as a DM channel between the two users
+ // need a public channel
channel := &model.Channel{
TeamId: team.Id,
Name: model.NewId(),
- DisplayName: "Channel2",
+ DisplayName: "Public Channel",
Type: model.CHANNEL_OPEN,
}
channel = store.Must(ss.Channel().Save(channel, -1)).(*model.Channel)
- directMessageChannel := store.Must(ss.Channel().CreateDirectChannel(user1.Id, user2.Id)).(*model.Channel)
// user1 posts twice in the public channel
post1 := &model.Post{
@@ -387,22 +389,114 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
}
post2 = store.Must(ss.Post().Save(post2)).(*model.Post)
- // user1 also sends a DM to user2
- post3 := &model.Post{
- ChannelId: directMessageChannel.Id,
+ // fetch the message exports for both posts that user1 sent
+ messageExportMap := map[string]model.MessageExport{}
+ if r1 := <-ss.Compliance().MessageExport(startTime-10, 10); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ messages := r1.Data.([]*model.MessageExport)
+ assert.Equal(t, numMessageExports+2, len(messages))
+
+ for _, v := range messages {
+ messageExportMap[*v.PostId] = *v
+ }
+ }
+
+ // post1 was made by user1 in channel1 and team1
+ assert.Equal(t, post1.Id, *messageExportMap[post1.Id].PostId)
+ assert.Equal(t, post1.CreateAt, *messageExportMap[post1.Id].PostCreateAt)
+ assert.Equal(t, post1.Message, *messageExportMap[post1.Id].PostMessage)
+ assert.Equal(t, channel.Id, *messageExportMap[post1.Id].ChannelId)
+ assert.Equal(t, channel.DisplayName, *messageExportMap[post1.Id].ChannelDisplayName)
+ assert.Equal(t, user1.Id, *messageExportMap[post1.Id].UserId)
+ assert.Equal(t, user1.Email, *messageExportMap[post1.Id].UserEmail)
+ assert.Equal(t, user1.Username, *messageExportMap[post1.Id].Username)
+
+ // post2 was made by user1 in channel1 and team1
+ assert.Equal(t, post2.Id, *messageExportMap[post2.Id].PostId)
+ assert.Equal(t, post2.CreateAt, *messageExportMap[post2.Id].PostCreateAt)
+ assert.Equal(t, post2.Message, *messageExportMap[post2.Id].PostMessage)
+ assert.Equal(t, channel.Id, *messageExportMap[post2.Id].ChannelId)
+ assert.Equal(t, channel.DisplayName, *messageExportMap[post2.Id].ChannelDisplayName)
+ assert.Equal(t, user1.Id, *messageExportMap[post2.Id].UserId)
+ assert.Equal(t, user1.Email, *messageExportMap[post2.Id].UserEmail)
+ assert.Equal(t, user1.Username, *messageExportMap[post2.Id].Username)
+}
+
+func testMessageExportPrivateChannel(t *testing.T, ss store.Store) {
+ // get the starting number of message export entries
+ startTime := model.GetMillis()
+ var numMessageExports = 0
+ if r1 := <-ss.Compliance().MessageExport(startTime-10, 10); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ messages := r1.Data.([]*model.MessageExport)
+ numMessageExports = len(messages)
+ }
+
+ // need a team
+ team := &model.Team{
+ DisplayName: "DisplayName",
+ Name: "zz" + model.NewId() + "b",
+ Email: model.NewId() + "@nowhere.com",
+ Type: model.TEAM_OPEN,
+ }
+ team = store.Must(ss.Team().Save(team)).(*model.Team)
+
+ // and two users that are a part of that team
+ user1 := &model.User{
+ Email: model.NewId(),
+ Username: model.NewId(),
+ }
+ user1 = store.Must(ss.User().Save(user1)).(*model.User)
+ store.Must(ss.Team().SaveMember(&model.TeamMember{
+ TeamId: team.Id,
+ UserId: user1.Id,
+ }, -1))
+
+ user2 := &model.User{
+ Email: model.NewId(),
+ Username: model.NewId(),
+ }
+ user2 = store.Must(ss.User().Save(user2)).(*model.User)
+ store.Must(ss.Team().SaveMember(&model.TeamMember{
+ TeamId: team.Id,
+ UserId: user2.Id,
+ }, -1))
+
+ // need a private channel
+ channel := &model.Channel{
+ TeamId: team.Id,
+ Name: model.NewId(),
+ DisplayName: "Private Channel",
+ Type: model.CHANNEL_PRIVATE,
+ }
+ channel = store.Must(ss.Channel().Save(channel, -1)).(*model.Channel)
+
+ // user1 posts twice in the private channel
+ post1 := &model.Post{
+ ChannelId: channel.Id,
UserId: user1.Id,
- CreateAt: startTime + 20,
- Message: "zz" + model.NewId() + "c",
+ CreateAt: startTime,
+ Message: "zz" + model.NewId() + "a",
+ }
+ post1 = store.Must(ss.Post().Save(post1)).(*model.Post)
+
+ post2 := &model.Post{
+ ChannelId: channel.Id,
+ UserId: user1.Id,
+ CreateAt: startTime + 10,
+ Message: "zz" + model.NewId() + "b",
}
- post3 = store.Must(ss.Post().Save(post3)).(*model.Post)
+ post2 = store.Must(ss.Post().Save(post2)).(*model.Post)
- // fetch the message exports for all three posts that user1 sent
+ // fetch the message exports for both posts that user1 sent
messageExportMap := map[string]model.MessageExport{}
if r1 := <-ss.Compliance().MessageExport(startTime-10, 10); r1.Err != nil {
t.Fatal(r1.Err)
} else {
messages := r1.Data.([]*model.MessageExport)
- assert.Equal(t, numMessageExports+3, len(messages))
+ assert.Equal(t, numMessageExports+2, len(messages))
for _, v := range messages {
messageExportMap[*v.PostId] = *v
@@ -415,6 +509,7 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
assert.Equal(t, post1.Message, *messageExportMap[post1.Id].PostMessage)
assert.Equal(t, channel.Id, *messageExportMap[post1.Id].ChannelId)
assert.Equal(t, channel.DisplayName, *messageExportMap[post1.Id].ChannelDisplayName)
+ assert.Equal(t, channel.Type, *messageExportMap[post1.Id].ChannelType)
assert.Equal(t, user1.Id, *messageExportMap[post1.Id].UserId)
assert.Equal(t, user1.Email, *messageExportMap[post1.Id].UserEmail)
assert.Equal(t, user1.Username, *messageExportMap[post1.Id].Username)
@@ -425,16 +520,179 @@ func testComplianceMessageExport(t *testing.T, ss store.Store) {
assert.Equal(t, post2.Message, *messageExportMap[post2.Id].PostMessage)
assert.Equal(t, channel.Id, *messageExportMap[post2.Id].ChannelId)
assert.Equal(t, channel.DisplayName, *messageExportMap[post2.Id].ChannelDisplayName)
+ assert.Equal(t, channel.Type, *messageExportMap[post2.Id].ChannelType)
assert.Equal(t, user1.Id, *messageExportMap[post2.Id].UserId)
assert.Equal(t, user1.Email, *messageExportMap[post2.Id].UserEmail)
assert.Equal(t, user1.Username, *messageExportMap[post2.Id].Username)
+}
+
+func testMessageExportDirectMessageChannel(t *testing.T, ss store.Store) {
+ // get the starting number of message export entries
+ startTime := model.GetMillis()
+ var numMessageExports = 0
+ if r1 := <-ss.Compliance().MessageExport(startTime-10, 10); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ messages := r1.Data.([]*model.MessageExport)
+ numMessageExports = len(messages)
+ }
+
+ // need a team
+ team := &model.Team{
+ DisplayName: "DisplayName",
+ Name: "zz" + model.NewId() + "b",
+ Email: model.NewId() + "@nowhere.com",
+ Type: model.TEAM_OPEN,
+ }
+ team = store.Must(ss.Team().Save(team)).(*model.Team)
+
+ // and two users that are a part of that team
+ user1 := &model.User{
+ Email: model.NewId(),
+ Username: model.NewId(),
+ }
+ user1 = store.Must(ss.User().Save(user1)).(*model.User)
+ store.Must(ss.Team().SaveMember(&model.TeamMember{
+ TeamId: team.Id,
+ UserId: user1.Id,
+ }, -1))
+
+ user2 := &model.User{
+ Email: model.NewId(),
+ Username: model.NewId(),
+ }
+ user2 = store.Must(ss.User().Save(user2)).(*model.User)
+ store.Must(ss.Team().SaveMember(&model.TeamMember{
+ TeamId: team.Id,
+ UserId: user2.Id,
+ }, -1))
+
+ // as well as a DM channel between those users
+ directMessageChannel := store.Must(ss.Channel().CreateDirectChannel(user1.Id, user2.Id)).(*model.Channel)
+
+ // user1 also sends a DM to user2
+ post := &model.Post{
+ ChannelId: directMessageChannel.Id,
+ UserId: user1.Id,
+ CreateAt: startTime + 20,
+ Message: "zz" + model.NewId() + "c",
+ }
+ post = store.Must(ss.Post().Save(post)).(*model.Post)
+
+ // fetch the message export for the post that user1 sent
+ messageExportMap := map[string]model.MessageExport{}
+ if r1 := <-ss.Compliance().MessageExport(startTime-10, 10); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ messages := r1.Data.([]*model.MessageExport)
+ assert.Equal(t, numMessageExports+1, len(messages))
+
+ for _, v := range messages {
+ messageExportMap[*v.PostId] = *v
+ }
+ }
+
+ // post is a DM between user1 and user2
+ // there is no channel display name for direct messages, so we sub in the string "Direct Message" instead
+ assert.Equal(t, post.Id, *messageExportMap[post.Id].PostId)
+ assert.Equal(t, post.CreateAt, *messageExportMap[post.Id].PostCreateAt)
+ assert.Equal(t, post.Message, *messageExportMap[post.Id].PostMessage)
+ assert.Equal(t, directMessageChannel.Id, *messageExportMap[post.Id].ChannelId)
+ assert.Equal(t, "Direct Message", *messageExportMap[post.Id].ChannelDisplayName)
+ assert.Equal(t, user1.Id, *messageExportMap[post.Id].UserId)
+ assert.Equal(t, user1.Email, *messageExportMap[post.Id].UserEmail)
+ assert.Equal(t, user1.Username, *messageExportMap[post.Id].Username)
+}
+
+func testMessageExportGroupMessageChannel(t *testing.T, ss store.Store) {
+ // get the starting number of message export entries
+ startTime := model.GetMillis()
+ var numMessageExports = 0
+ if r1 := <-ss.Compliance().MessageExport(startTime-10, 10); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ messages := r1.Data.([]*model.MessageExport)
+ numMessageExports = len(messages)
+ }
+
+ // need a team
+ team := &model.Team{
+ DisplayName: "DisplayName",
+ Name: "zz" + model.NewId() + "b",
+ Email: model.NewId() + "@nowhere.com",
+ Type: model.TEAM_OPEN,
+ }
+ team = store.Must(ss.Team().Save(team)).(*model.Team)
+
+ // and three users that are a part of that team
+ user1 := &model.User{
+ Email: model.NewId(),
+ Username: model.NewId(),
+ }
+ user1 = store.Must(ss.User().Save(user1)).(*model.User)
+ store.Must(ss.Team().SaveMember(&model.TeamMember{
+ TeamId: team.Id,
+ UserId: user1.Id,
+ }, -1))
+
+ user2 := &model.User{
+ Email: model.NewId(),
+ Username: model.NewId(),
+ }
+ user2 = store.Must(ss.User().Save(user2)).(*model.User)
+ store.Must(ss.Team().SaveMember(&model.TeamMember{
+ TeamId: team.Id,
+ UserId: user2.Id,
+ }, -1))
+
+ user3 := &model.User{
+ Email: model.NewId(),
+ Username: model.NewId(),
+ }
+ user3 = store.Must(ss.User().Save(user3)).(*model.User)
+ store.Must(ss.Team().SaveMember(&model.TeamMember{
+ TeamId: team.Id,
+ UserId: user3.Id,
+ }, -1))
+
+ // can't create a group channel directly, because importing app creates an import cycle, so we have to fake it
+ groupMessageChannel := &model.Channel{
+ TeamId: team.Id,
+ Name: model.NewId(),
+ Type: model.CHANNEL_GROUP,
+ }
+ groupMessageChannel = store.Must(ss.Channel().Save(groupMessageChannel, -1)).(*model.Channel)
+
+ // user1 posts in the GM
+ post := &model.Post{
+ ChannelId: groupMessageChannel.Id,
+ UserId: user1.Id,
+ CreateAt: startTime + 20,
+ Message: "zz" + model.NewId() + "c",
+ }
+ post = store.Must(ss.Post().Save(post)).(*model.Post)
+
+ // fetch the message export for the post that user1 sent
+ messageExportMap := map[string]model.MessageExport{}
+ if r1 := <-ss.Compliance().MessageExport(startTime-10, 10); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ messages := r1.Data.([]*model.MessageExport)
+ assert.Equal(t, numMessageExports+1, len(messages))
+
+ for _, v := range messages {
+ messageExportMap[*v.PostId] = *v
+ }
+ }
- // post3 is a DM between user1 and user2
- assert.Equal(t, post3.Id, *messageExportMap[post3.Id].PostId)
- assert.Equal(t, post3.CreateAt, *messageExportMap[post3.Id].PostCreateAt)
- assert.Equal(t, post3.Message, *messageExportMap[post3.Id].PostMessage)
- assert.Equal(t, directMessageChannel.Id, *messageExportMap[post3.Id].ChannelId)
- assert.Equal(t, user1.Id, *messageExportMap[post3.Id].UserId)
- assert.Equal(t, user1.Email, *messageExportMap[post3.Id].UserEmail)
- assert.Equal(t, user1.Username, *messageExportMap[post3.Id].Username)
+ // post is a DM between user1 and user2
+ // there is no channel display name for direct messages, so we sub in the string "Direct Message" instead
+ assert.Equal(t, post.Id, *messageExportMap[post.Id].PostId)
+ assert.Equal(t, post.CreateAt, *messageExportMap[post.Id].PostCreateAt)
+ assert.Equal(t, post.Message, *messageExportMap[post.Id].PostMessage)
+ assert.Equal(t, groupMessageChannel.Id, *messageExportMap[post.Id].ChannelId)
+ assert.Equal(t, "Group Message", *messageExportMap[post.Id].ChannelDisplayName)
+ assert.Equal(t, user1.Id, *messageExportMap[post.Id].UserId)
+ assert.Equal(t, user1.Email, *messageExportMap[post.Id].UserEmail)
+ assert.Equal(t, user1.Username, *messageExportMap[post.Id].Username)
}
diff --git a/store/storetest/mocks/ChannelStore.go b/store/storetest/mocks/ChannelStore.go
index 5379c2fb4..6eab47073 100644
--- a/store/storetest/mocks/ChannelStore.go
+++ b/store/storetest/mocks/ChannelStore.go
@@ -61,6 +61,11 @@ func (_m *ChannelStore) AutocompleteInTeam(teamId string, term string) store.Sto
return r0
}
+// ClearCaches provides a mock function with given fields:
+func (_m *ChannelStore) ClearCaches() {
+ _m.Called()
+}
+
// CreateDirectChannel provides a mock function with given fields: userId, otherUserId
func (_m *ChannelStore) CreateDirectChannel(userId string, otherUserId string) store.StoreChannel {
ret := _m.Called(userId, otherUserId)
@@ -93,22 +98,6 @@ func (_m *ChannelStore) Delete(channelId string, time int64) store.StoreChannel
return r0
}
-// ExtraUpdateByUser provides a mock function with given fields: userId, time
-func (_m *ChannelStore) ExtraUpdateByUser(userId string, time int64) store.StoreChannel {
- ret := _m.Called(userId, time)
-
- var r0 store.StoreChannel
- if rf, ok := ret.Get(0).(func(string, int64) store.StoreChannel); ok {
- r0 = rf(userId, time)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(store.StoreChannel)
- }
- }
-
- return r0
-}
-
// Get provides a mock function with given fields: id, allowFromCache
func (_m *ChannelStore) Get(id string, allowFromCache bool) store.StoreChannel {
ret := _m.Called(id, allowFromCache)
diff --git a/store/storetest/mocks/FileInfoStore.go b/store/storetest/mocks/FileInfoStore.go
index 9b479ff3a..4dddf0bd7 100644
--- a/store/storetest/mocks/FileInfoStore.go
+++ b/store/storetest/mocks/FileInfoStore.go
@@ -29,6 +29,11 @@ func (_m *FileInfoStore) AttachToPost(fileId string, postId string) store.StoreC
return r0
}
+// ClearCaches provides a mock function with given fields:
+func (_m *FileInfoStore) ClearCaches() {
+ _m.Called()
+}
+
// DeleteForPost provides a mock function with given fields: postId
func (_m *FileInfoStore) DeleteForPost(postId string) store.StoreChannel {
ret := _m.Called(postId)
diff --git a/store/storetest/mocks/PostStore.go b/store/storetest/mocks/PostStore.go
index 05e3bde34..c405d5030 100644
--- a/store/storetest/mocks/PostStore.go
+++ b/store/storetest/mocks/PostStore.go
@@ -61,6 +61,11 @@ func (_m *PostStore) AnalyticsUserCountsWithPostsByDay(teamId string) store.Stor
return r0
}
+// ClearCaches provides a mock function with given fields:
+func (_m *PostStore) ClearCaches() {
+ _m.Called()
+}
+
// Delete provides a mock function with given fields: postId, time
func (_m *PostStore) Delete(postId string, time int64) store.StoreChannel {
ret := _m.Called(postId, time)
diff --git a/store/storetest/mocks/TeamStore.go b/store/storetest/mocks/TeamStore.go
index 8a7f030dc..d38fb5f27 100644
--- a/store/storetest/mocks/TeamStore.go
+++ b/store/storetest/mocks/TeamStore.go
@@ -461,13 +461,13 @@ func (_m *TeamStore) UpdateDisplayName(name string, teamId string) store.StoreCh
return r0
}
-// UpdateMember provides a mock function with given fields: member
-func (_m *TeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel {
- ret := _m.Called(member)
+// UpdateLastTeamIconUpdate provides a mock function with given fields: teamId, curTime
+func (_m *TeamStore) UpdateLastTeamIconUpdate(teamId string, curTime int64) store.StoreChannel {
+ ret := _m.Called(teamId, curTime)
var r0 store.StoreChannel
- if rf, ok := ret.Get(0).(func(*model.TeamMember) store.StoreChannel); ok {
- r0 = rf(member)
+ if rf, ok := ret.Get(0).(func(string, int64) store.StoreChannel); ok {
+ r0 = rf(teamId, curTime)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
@@ -477,13 +477,13 @@ func (_m *TeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel {
return r0
}
-// UpdateLastTeamIconUpdate provides a mock function with given fields: teamId
-func (_m *TeamStore) UpdateLastTeamIconUpdate(teamId string, curTime int64) store.StoreChannel {
- ret := _m.Called(teamId)
+// UpdateMember provides a mock function with given fields: member
+func (_m *TeamStore) UpdateMember(member *model.TeamMember) store.StoreChannel {
+ ret := _m.Called(member)
var r0 store.StoreChannel
- if rf, ok := ret.Get(0).(func(string, int64) store.StoreChannel); ok {
- r0 = rf(teamId, curTime)
+ if rf, ok := ret.Get(0).(func(*model.TeamMember) store.StoreChannel); ok {
+ r0 = rf(member)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel)
diff --git a/store/storetest/mocks/UserStore.go b/store/storetest/mocks/UserStore.go
index 7d1fd8c38..369a29e7a 100644
--- a/store/storetest/mocks/UserStore.go
+++ b/store/storetest/mocks/UserStore.go
@@ -77,6 +77,11 @@ func (_m *UserStore) AnalyticsUniqueUserCount(teamId string) store.StoreChannel
return r0
}
+// ClearCaches provides a mock function with given fields:
+func (_m *UserStore) ClearCaches() {
+ _m.Called()
+}
+
// Get provides a mock function with given fields: id
func (_m *UserStore) Get(id string) store.StoreChannel {
ret := _m.Called(id)
@@ -349,6 +354,22 @@ func (_m *UserStore) GetProfilesInChannel(channelId string, offset int, limit in
return r0
}
+// GetProfilesInChannelByStatus provides a mock function with given fields: channelId, offset, limit
+func (_m *UserStore) GetProfilesInChannelByStatus(channelId string, offset int, limit int) store.StoreChannel {
+ ret := _m.Called(channelId, offset, limit)
+
+ var r0 store.StoreChannel
+ if rf, ok := ret.Get(0).(func(string, int, int) store.StoreChannel); ok {
+ r0 = rf(channelId, offset, limit)
+ } else {
+ if ret.Get(0) != nil {
+ r0 = ret.Get(0).(store.StoreChannel)
+ }
+ }
+
+ return r0
+}
+
// GetProfilesNotInChannel provides a mock function with given fields: teamId, channelId, offset, limit
func (_m *UserStore) GetProfilesNotInChannel(teamId string, channelId string, offset int, limit int) store.StoreChannel {
ret := _m.Called(teamId, channelId, offset, limit)
diff --git a/store/storetest/mocks/WebhookStore.go b/store/storetest/mocks/WebhookStore.go
index aa66e0600..bf5b636eb 100644
--- a/store/storetest/mocks/WebhookStore.go
+++ b/store/storetest/mocks/WebhookStore.go
@@ -45,6 +45,11 @@ func (_m *WebhookStore) AnalyticsOutgoingCount(teamId string) store.StoreChannel
return r0
}
+// ClearCaches provides a mock function with given fields:
+func (_m *WebhookStore) ClearCaches() {
+ _m.Called()
+}
+
// DeleteIncoming provides a mock function with given fields: webhookId, time
func (_m *WebhookStore) DeleteIncoming(webhookId string, time int64) store.StoreChannel {
ret := _m.Called(webhookId, time)
diff --git a/store/storetest/user_store.go b/store/storetest/user_store.go
index 47f04d1bb..2fd7d4190 100644
--- a/store/storetest/user_store.go
+++ b/store/storetest/user_store.go
@@ -25,6 +25,7 @@ func TestUserStore(t *testing.T, ss store.Store) {
t.Run("GetAllProfiles", func(t *testing.T) { testUserStoreGetAllProfiles(t, ss) })
t.Run("GetProfiles", func(t *testing.T) { testUserStoreGetProfiles(t, ss) })
t.Run("GetProfilesInChannel", func(t *testing.T) { testUserStoreGetProfilesInChannel(t, ss) })
+ t.Run("GetProfilesInChannelByStatus", func(t *testing.T) { testUserStoreGetProfilesInChannelByStatus(t, ss) })
t.Run("GetProfilesWithoutTeam", func(t *testing.T) { testUserStoreGetProfilesWithoutTeam(t, ss) })
t.Run("GetAllProfilesInChannel", func(t *testing.T) { testUserStoreGetAllProfilesInChannel(t, ss) })
t.Run("GetProfilesNotInChannel", func(t *testing.T) { testUserStoreGetProfilesNotInChannel(t, ss) })
@@ -464,6 +465,82 @@ func testUserStoreGetProfilesInChannel(t *testing.T, ss store.Store) {
}
}
+func testUserStoreGetProfilesInChannelByStatus(t *testing.T, ss store.Store) {
+ teamId := model.NewId()
+
+ u1 := &model.User{}
+ u1.Email = model.NewId()
+ store.Must(ss.User().Save(u1))
+ store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u1.Id}, -1))
+
+ u2 := &model.User{}
+ u2.Email = model.NewId()
+ store.Must(ss.User().Save(u2))
+ store.Must(ss.Team().SaveMember(&model.TeamMember{TeamId: teamId, UserId: u2.Id}, -1))
+
+ c1 := model.Channel{}
+ c1.TeamId = teamId
+ c1.DisplayName = "Profiles in channel"
+ c1.Name = "profiles-" + model.NewId()
+ c1.Type = model.CHANNEL_OPEN
+
+ c2 := model.Channel{}
+ c2.TeamId = teamId
+ c2.DisplayName = "Profiles in private"
+ c2.Name = "profiles-" + model.NewId()
+ c2.Type = model.CHANNEL_PRIVATE
+
+ store.Must(ss.Channel().Save(&c1, -1))
+ store.Must(ss.Channel().Save(&c2, -1))
+
+ m1 := model.ChannelMember{}
+ m1.ChannelId = c1.Id
+ m1.UserId = u1.Id
+ m1.NotifyProps = model.GetDefaultChannelNotifyProps()
+
+ m2 := model.ChannelMember{}
+ m2.ChannelId = c1.Id
+ m2.UserId = u2.Id
+ m2.NotifyProps = model.GetDefaultChannelNotifyProps()
+
+ m3 := model.ChannelMember{}
+ m3.ChannelId = c2.Id
+ m3.UserId = u1.Id
+ m3.NotifyProps = model.GetDefaultChannelNotifyProps()
+
+ store.Must(ss.Channel().SaveMember(&m1))
+ store.Must(ss.Channel().SaveMember(&m2))
+ store.Must(ss.Channel().SaveMember(&m3))
+
+ if r1 := <-ss.User().GetProfilesInChannelByStatus(c1.Id, 0, 100); r1.Err != nil {
+ t.Fatal(r1.Err)
+ } else {
+ users := r1.Data.([]*model.User)
+ if len(users) != 2 {
+ t.Fatal("invalid returned users")
+ }
+
+ found := false
+ for _, u := range users {
+ if u.Id == u1.Id {
+ found = true
+ }
+ }
+
+ if !found {
+ t.Fatal("missing user")
+ }
+ }
+
+ if r2 := <-ss.User().GetProfilesInChannelByStatus(c2.Id, 0, 1); r2.Err != nil {
+ t.Fatal(r2.Err)
+ } else {
+ if len(r2.Data.([]*model.User)) != 1 {
+ t.Fatal("should have returned only 1 user")
+ }
+ }
+}
+
func testUserStoreGetProfilesWithoutTeam(t *testing.T, ss store.Store) {
teamId := model.NewId()