MM-45956: Optimize FileInfo stats query (#22603)

* MM-45956: Optimize FileInfo stats query

We Denormalize Post.ChannelId on FileInfo.ChannelId

```release-note
The file info stats query is now optimized by denormalizing the channelID column into the table itself. This will speed up the query to get the file count for a channel on clicking the RHS.

Migration times:
On a MySQL 8.0.31 DB with
1405 rows in FileInfo and 11M posts, it took around 0.3s

On a Postgres 12.14 DB with
1731 rows in FileInfo and 11M posts, it took around 0.27s
```

https://mattermost.atlassian.net/browse/MM-45956
This commit is contained in:
Agniva De Sarker
2023-03-23 22:14:04 +05:30
committed by GitHub
parent 1edbde8aa3
commit 56b18ca7bf
25 changed files with 266 additions and 138 deletions

View File

@@ -36,10 +36,14 @@ type GetFileInfosOptions struct {
}
type FileInfo struct {
Id string `json:"id"`
CreatorId string `json:"user_id"`
PostId string `json:"post_id,omitempty"`
ChannelId string `db:"-" json:"channel_id"`
Id string `json:"id"`
CreatorId string `json:"user_id"`
PostId string `json:"post_id,omitempty"`
// ChannelId is the denormalized value from the corresponding post. Note that this value is
// potentially distinct from the ChannelId provided when the file is first uploaded and
// used to organize the directories in the file store, since in theory that same file
// could be attached to a post from a different channel (or not attached to a post at all).
ChannelId string `json:"channel_id"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`

View File

@@ -916,7 +916,7 @@ func TestGetFileLink(t *testing.T) {
CheckBadRequestStatus(t, resp)
// Hacky way to assign file to a post (usually would be done by CreatePost call)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicUser.Id)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicPost.ChannelId, th.BasicUser.Id)
require.NoError(t, err)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false })
@@ -1074,7 +1074,7 @@ func TestGetPublicFile(t *testing.T) {
fileId := fileResp.FileInfos[0].Id
// Hacky way to assign file to a post (usually would be done by CreatePost call)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicUser.Id)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileId, th.BasicPost.Id, th.BasicPost.ChannelId, th.BasicUser.Id)
require.NoError(t, err)
info, err := th.App.Srv().Store().FileInfo().Get(fileId)
@@ -1139,25 +1139,25 @@ func TestSearchFiles(t *testing.T) {
filename := "search for fileInfo1"
fileInfo1, appErr := th.App.UploadFile(th.Context, data, th.BasicChannel.Id, filename)
require.Nil(t, appErr)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo1.Id, th.BasicPost.Id, th.BasicUser.Id)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo1.Id, th.BasicPost.Id, th.BasicPost.ChannelId, th.BasicUser.Id)
require.NoError(t, err)
filename = "search for fileInfo2"
fileInfo2, appErr := th.App.UploadFile(th.Context, data, th.BasicChannel.Id, filename)
require.Nil(t, appErr)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo2.Id, th.BasicPost.Id, th.BasicUser.Id)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo2.Id, th.BasicPost.Id, th.BasicPost.ChannelId, th.BasicUser.Id)
require.NoError(t, err)
filename = "tagged search for fileInfo3"
fileInfo3, appErr := th.App.UploadFile(th.Context, data, th.BasicChannel.Id, filename)
require.Nil(t, appErr)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo3.Id, th.BasicPost.Id, th.BasicUser.Id)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo3.Id, th.BasicPost.Id, th.BasicPost.ChannelId, th.BasicUser.Id)
require.NoError(t, err)
filename = "tagged for fileInfo4"
fileInfo4, appErr := th.App.UploadFile(th.Context, data, th.BasicChannel.Id, filename)
require.Nil(t, appErr)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo4.Id, th.BasicPost.Id, th.BasicUser.Id)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo4.Id, th.BasicPost.Id, th.BasicPost.ChannelId, th.BasicUser.Id)
require.NoError(t, err)
archivedChannel := th.CreatePublicChannel()
@@ -1166,7 +1166,7 @@ func TestSearchFiles(t *testing.T) {
post := &model.Post{ChannelId: archivedChannel.Id, Message: model.NewId() + "a"}
rpost, _, err := client.CreatePost(post)
require.NoError(t, err)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo5.Id, rpost.Id, th.BasicUser.Id)
err = th.App.Srv().Store().FileInfo().AttachToPost(fileInfo5.Id, rpost.Id, rpost.ChannelId, th.BasicUser.Id)
require.NoError(t, err)
th.Client.DeleteChannel(archivedChannel.Id)

View File

@@ -274,6 +274,7 @@ func (a *App) getInfoForFilename(post *model.Post, teamID, channelID, userID, ol
info.Id = model.NewId()
info.CreatorId = post.UserId
info.PostId = post.Id
info.ChannelId = post.ChannelId
info.CreateAt = post.CreateAt
info.UpdateAt = post.UpdateAt
info.Path = path
@@ -1214,6 +1215,7 @@ func (a *App) CopyFileInfos(userID string, fileIDs []string) ([]string, *model.A
fileInfo.CreateAt = now
fileInfo.UpdateAt = now
fileInfo.PostId = ""
fileInfo.ChannelId = ""
if _, err := a.Srv().Store().FileInfo().Save(fileInfo); err != nil {
var appErr *model.AppError

View File

@@ -368,6 +368,7 @@ func TestSearchFilesInTeamForUser(t *testing.T) {
fileInfo, err := th.App.Srv().Store().FileInfo().Save(&model.FileInfo{
CreatorId: th.BasicUser.Id,
PostId: th.BasicPost.Id,
ChannelId: th.BasicPost.ChannelId,
Name: searchTerm,
Path: searchTerm,
Extension: "jpg",

View File

@@ -1638,7 +1638,7 @@ func (a *App) uploadAttachments(c request.CTX, attachments *[]imports.Attachment
func (a *App) updateFileInfoWithPostId(post *model.Post) {
for _, fileID := range post.FileIds {
if err := a.Srv().Store().FileInfo().AttachToPost(fileID, post.Id, post.UserId); err != nil {
if err := a.Srv().Store().FileInfo().AttachToPost(fileID, post.Id, post.ChannelId, post.UserId); err != nil {
mlog.Error("Error attaching files to post.", mlog.String("post_id", post.Id), mlog.Any("post_file_ids", post.FileIds), mlog.Err(err))
}
}

View File

@@ -416,7 +416,7 @@ func (a *App) addPostPreviewProp(post *model.Post) (*model.Post, error) {
func (a *App) attachFilesToPost(post *model.Post) *model.AppError {
var attachedIds []string
for _, fileID := range post.FileIds {
err := a.Srv().Store().FileInfo().AttachToPost(fileID, post.Id, post.UserId)
err := a.Srv().Store().FileInfo().AttachToPost(fileID, post.Id, post.ChannelId, post.UserId)
if err != nil {
mlog.Warn("Failed to attach file to post", mlog.String("file_id", fileID), mlog.String("post_id", post.Id), mlog.Err(err))
continue

View File

@@ -210,6 +210,8 @@ channels/db/migrations/mysql/000104_upgrade_notifyadmin.down.sql
channels/db/migrations/mysql/000104_upgrade_notifyadmin.up.sql
channels/db/migrations/mysql/000105_remove_tokens.down.sql
channels/db/migrations/mysql/000105_remove_tokens.up.sql
channels/db/migrations/mysql/000106_fileinfo_channelid.down.sql
channels/db/migrations/mysql/000106_fileinfo_channelid.up.sql
channels/db/migrations/postgres/000001_create_teams.down.sql
channels/db/migrations/postgres/000001_create_teams.up.sql
channels/db/migrations/postgres/000002_create_team_members.down.sql
@@ -420,3 +422,5 @@ channels/db/migrations/postgres/000104_upgrade_notifyadmin.down.sql
channels/db/migrations/postgres/000104_upgrade_notifyadmin.up.sql
channels/db/migrations/postgres/000105_remove_tokens.down.sql
channels/db/migrations/postgres/000105_remove_tokens.up.sql
channels/db/migrations/postgres/000106_fileinfo_channelid.down.sql
channels/db/migrations/postgres/000106_fileinfo_channelid.up.sql

View File

@@ -0,0 +1,29 @@
SET @preparedStatement = (SELECT IF(
EXISTS(
SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'FileInfo'
AND table_schema = DATABASE()
AND index_name = 'idx_fileinfo_channel_id_create_at'
) > 0,
'DROP INDEX idx_fileinfo_channel_id_create_at ON FileInfo;',
'SELECT 1'
));
PREPARE removeIndexIfExists FROM @preparedStatement;
EXECUTE removeIndexIfExists;
DEALLOCATE PREPARE removeIndexIfExists;
SET @preparedStatement = (SELECT IF(
EXISTS(
SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'FileInfo'
AND table_schema = DATABASE()
AND column_name = 'ChannelId'
) > 0,
'ALTER TABLE FileInfo DROP COLUMN ChannelId;',
'SELECT 1;'
));
PREPARE removeColumnIfExists FROM @preparedStatement;
EXECUTE removeColumnIfExists;
DEALLOCATE PREPARE removeColumnIfExists;

View File

@@ -0,0 +1,34 @@
SET @preparedStatement = (SELECT IF(
NOT EXISTS(
SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'FileInfo'
AND table_schema = DATABASE()
AND column_name = 'ChannelId'
),
'ALTER TABLE FileInfo ADD COLUMN ChannelId varchar(26);',
'SELECT 1;'
));
PREPARE addColumnIfNotExists FROM @preparedStatement;
EXECUTE addColumnIfNotExists;
DEALLOCATE PREPARE addColumnIfNotExists;
UPDATE FileInfo, Posts
SET FileInfo.ChannelId = Posts.ChannelId
WHERE FileInfo.PostId = Posts.Id
AND FileInfo.ChannelId IS NULL;
SET @preparedStatement = (SELECT IF(
NOT EXISTS(
SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS
WHERE table_name = 'FileInfo'
AND table_schema = DATABASE()
AND index_name = 'idx_fileinfo_channel_id_create_at'
),
'CREATE INDEX idx_fileinfo_channel_id_create_at ON FileInfo(ChannelId, CreateAt);',
'SELECT 1'
));
PREPARE createIndexIfNotExists FROM @preparedStatement;
EXECUTE createIndexIfNotExists;
DEALLOCATE PREPARE createIndexIfNotExists;

View File

@@ -0,0 +1,2 @@
DROP INDEX IF EXISTS idx_fileinfo_channel_id_create_at;
ALTER TABLE fileinfo DROP COLUMN IF EXISTS channelid;

View File

@@ -0,0 +1,3 @@
ALTER TABLE fileinfo ADD COLUMN IF NOT EXISTS channelid varchar(26);
UPDATE fileinfo SET channelid = posts.channelid FROM posts WHERE fileinfo.channelid IS NULL AND fileinfo.postid = posts.id;
CREATE INDEX IF NOT EXISTS idx_fileinfo_channel_id_create_at ON fileinfo(channelid, createat);

View File

@@ -3477,7 +3477,7 @@ func (s *OpenTracingLayerEmojiStore) Search(name string, prefixOnly bool, limit
return result, err
}
func (s *OpenTracingLayerFileInfoStore) AttachToPost(fileID string, postID string, creatorID string) error {
func (s *OpenTracingLayerFileInfoStore) AttachToPost(fileID string, postID string, channelID string, creatorID string) error {
origCtx := s.Root.Store.Context()
span, newCtx := tracing.StartSpanWithParentByContext(s.Root.Store.Context(), "FileInfoStore.AttachToPost")
s.Root.Store.SetContext(newCtx)
@@ -3486,7 +3486,7 @@ func (s *OpenTracingLayerFileInfoStore) AttachToPost(fileID string, postID strin
}()
defer span.Finish()
err := s.FileInfoStore.AttachToPost(fileID, postID, creatorID)
err := s.FileInfoStore.AttachToPost(fileID, postID, channelID, creatorID)
if err != nil {
span.LogFields(spanlog.Error(err))
ext.Error.Set(span, true)

View File

@@ -3892,11 +3892,11 @@ func (s *RetryLayerEmojiStore) Search(name string, prefixOnly bool, limit int) (
}
func (s *RetryLayerFileInfoStore) AttachToPost(fileID string, postID string, creatorID string) error {
func (s *RetryLayerFileInfoStore) AttachToPost(fileID string, postID string, channelID string, creatorID string) error {
tries := 0
for {
err := s.FileInfoStore.AttachToPost(fileID, postID, creatorID)
err := s.FileInfoStore.AttachToPost(fileID, postID, channelID, creatorID)
if err == nil {
return nil
}

View File

@@ -112,8 +112,8 @@ func (s SearchFileInfoStore) SetContent(fileID, content string) error {
return err
}
func (s SearchFileInfoStore) AttachToPost(fileId, postId, creatorId string) error {
err := s.FileInfoStore.AttachToPost(fileId, postId, creatorId)
func (s SearchFileInfoStore) AttachToPost(fileId, postId, channelId, creatorId string) error {
err := s.FileInfoStore.AttachToPost(fileId, postId, channelId, creatorId)
if err == nil {
nFileInfo, err2 := s.FileInfoStore.GetFromMaster(fileId)
if err2 == nil {

View File

@@ -207,11 +207,11 @@ func testFileInfoSearchFileInfosIncludingDMs(t *testing.T, th *SearchTestHelper)
post2, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "dm test", "", model.PostTypeDefault, 0, false)
require.NoError(t, err)
p1, err := th.createFileInfo(th.User.Id, post.Id, "dm test filename", "dm contenttest filename", "jpg", "image/jpeg", 0, 1)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "dm test filename", "dm contenttest filename", "jpg", "image/jpeg", 0, 1)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "dm other filename", "dm other filename", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "dm other filename", "dm other filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post2.Id, "channel test filename", "channel contenttest filename", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "channel test filename", "channel contenttest filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -248,11 +248,11 @@ func testFileInfoSearchFileInfosWithPagination(t *testing.T, th *SearchTestHelpe
post2, err := th.createPost(th.User.Id, th.ChannelBasic.Id, "dm test", "", model.PostTypeDefault, 20000, false)
require.NoError(t, err)
p1, err := th.createFileInfo(th.User.Id, post.Id, "dm test filename", "dm contenttest filename", "jpg", "image/jpeg", 10000, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "dm test filename", "dm contenttest filename", "jpg", "image/jpeg", 10000, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "dm other filename", "dm other filename", "jpg", "image/jpeg", 20000, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "dm other filename", "dm other filename", "jpg", "image/jpeg", 20000, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post2.Id, "channel test filename", "channel contenttest filename", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "channel test filename", "channel contenttest filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -292,9 +292,9 @@ func testFileInfoSearchExactPhraseInQuotes(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "channel test 1 2 3 filename", "channel content test 1 2 3 filename", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "channel test 1 2 3 filename", "channel content test 1 2 3 filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "channel test 123 filename", "channel content test 123 filename", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "channel test 123 filename", "channel content test 123 filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -322,9 +322,9 @@ func testFileInfoSearchEmailAddresses(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "test email test@test.com", "test email test@content.com", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "test email test@test.com", "test email test@content.com", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "test email test2@test.com", "test email test2@content.com", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "test email test2@test.com", "test email test2@content.com", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -373,7 +373,7 @@ func testFileInfoSearchMarkdownUnderscores(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "_start middle end_ _another_", "_start middle end_ _another_", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "_start middle end_ _another_", "_start middle end_ _another_", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -420,9 +420,9 @@ func testFileInfoSearchNonLatinWords(t *testing.T, th *SearchTestHelper) {
defer th.deleteUserPosts(th.User.Id)
t.Run("Should be able to search chinese words", func(t *testing.T) {
p1, err := th.createFileInfo(th.User.Id, post.Id, "你好", "你好", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "你好", "你好", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "你", "你", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "你", "你", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -453,7 +453,7 @@ func testFileInfoSearchNonLatinWords(t *testing.T, th *SearchTestHelper) {
})
})
t.Run("Should be able to search cyrillic words", func(t *testing.T) {
p1, err := th.createFileInfo(th.User.Id, post.Id, "слово test", "слово test", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "слово test", "слово test", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -476,9 +476,9 @@ func testFileInfoSearchNonLatinWords(t *testing.T, th *SearchTestHelper) {
})
t.Run("Should be able to search japanese words", func(t *testing.T) {
p1, err := th.createFileInfo(th.User.Id, post.Id, "本", "本", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "本", "本", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "本木", "本木", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "本木", "本木", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -511,9 +511,9 @@ func testFileInfoSearchNonLatinWords(t *testing.T, th *SearchTestHelper) {
})
t.Run("Should be able to search korean words", func(t *testing.T) {
p1, err := th.createFileInfo(th.User.Id, post.Id, "불", "불", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "불", "불", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "불다", "불다", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "불다", "불다", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -550,9 +550,9 @@ func testFileInfoSearchAlternativeSpellings(t *testing.T, th *SearchTestHelper)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "Straße test", "Straße test", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "Straße test", "Straße test", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "Strasse test", "Strasse test", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "Strasse test", "Strasse test", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -578,9 +578,9 @@ func testFileInfoSearchAlternativeSpellingsAccents(t *testing.T, th *SearchTestH
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "café", "café", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "café", "café", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "café", "café", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "café", "café", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -612,9 +612,9 @@ func testFileInfoSearchOrExcludeFileInfosBySpecificUser(t *testing.T, th *Search
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User2.Id, post.Id, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User2.Id, post.Id, post.ChannelId, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
defer th.deleteUserFileInfos(th.User2.Id)
@@ -635,9 +635,9 @@ func testFileInfoSearchOrExcludeFileInfosInChannel(t *testing.T, th *SearchTestH
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post2.Id, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "test fromuser filename", "test fromuser filename", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
defer th.deleteUserFileInfos(th.User2.Id)
@@ -666,9 +666,9 @@ func testFileInfoSearchOrExcludeFileInfosInDMGM(t *testing.T, th *SearchTestHelp
defer th.deleteUserPosts(th.User.Id)
defer th.deleteUserPosts(th.User2.Id)
p1, err := th.createFileInfo(th.User.Id, post1.Id, "test fromuser", "test fromuser", "jpg", "image/jpg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "test fromuser", "test fromuser", "jpg", "image/jpg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User2.Id, post2.Id, "test fromuser 2", "test fromuser 2", "jpg", "image/jpg", 0, 0)
p2, err := th.createFileInfo(th.User2.Id, post2.Id, post2.ChannelId, "test fromuser 2", "test fromuser 2", "jpg", "image/jpg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
defer th.deleteUserFileInfos(th.User2.Id)
@@ -716,11 +716,11 @@ func testFileInfoSearchOrExcludeByExtensions(t *testing.T, th *SearchTestHelper)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "test", "test", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "test", "test", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "test", "test", "png", "image/png", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "test", "test", "png", "image/png", 0, 0)
require.NoError(t, err)
p3, err := th.createFileInfo(th.User.Id, post.Id, "test", "test", "bmp", "image/bmp", 0, 0)
p3, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "test", "test", "bmp", "image/bmp", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -787,13 +787,13 @@ func testFileInfoFilterFilesInSpecificDate(t *testing.T, th *SearchTestHelper) {
defer th.deleteUserPosts(th.User.Id)
creationDate := model.GetMillisForTime(time.Date(2020, 03, 22, 12, 0, 0, 0, time.UTC))
p1, err := th.createFileInfo(th.User.Id, post1.Id, "test in specific date", "test in specific date", "jpg", "image/jpeg", creationDate, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "test in specific date", "test in specific date", "jpg", "image/jpeg", creationDate, 0)
require.NoError(t, err)
creationDate2 := model.GetMillisForTime(time.Date(2020, 03, 23, 0, 0, 0, 0, time.UTC))
p2, err := th.createFileInfo(th.User.Id, post2.Id, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate2, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate2, 0)
require.NoError(t, err)
creationDate3 := model.GetMillisForTime(time.Date(2020, 03, 21, 23, 59, 59, 0, time.UTC))
p3, err := th.createFileInfo(th.User.Id, post1.Id, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate3, 0)
p3, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate3, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -830,13 +830,13 @@ func testFileInfoFilterFilesBeforeSpecificDate(t *testing.T, th *SearchTestHelpe
defer th.deleteUserPosts(th.User.Id)
creationDate := model.GetMillisForTime(time.Date(2020, 03, 01, 12, 0, 0, 0, time.UTC))
p1, err := th.createFileInfo(th.User.Id, post1.Id, "test in specific date", "test in specific date", "jpg", "image/jpeg", creationDate, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "test in specific date", "test in specific date", "jpg", "image/jpeg", creationDate, 0)
require.NoError(t, err)
creationDate2 := model.GetMillisForTime(time.Date(2020, 03, 22, 23, 59, 59, 0, time.UTC))
p2, err := th.createFileInfo(th.User.Id, post2.Id, "test in specific date 2", "test in specific date 2", "jpg", "image/jpeg", creationDate2, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "test in specific date 2", "test in specific date 2", "jpg", "image/jpeg", creationDate2, 0)
require.NoError(t, err)
creationDate3 := model.GetMillisForTime(time.Date(2020, 03, 26, 16, 55, 0, 0, time.UTC))
p3, err := th.createFileInfo(th.User.Id, post1.Id, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate3, 0)
p3, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate3, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -874,13 +874,13 @@ func testFileInfoFilterFilesAfterSpecificDate(t *testing.T, th *SearchTestHelper
defer th.deleteUserPosts(th.User.Id)
creationDate := model.GetMillisForTime(time.Date(2020, 03, 01, 12, 0, 0, 0, time.UTC))
p1, err := th.createFileInfo(th.User.Id, post1.Id, "test in specific date", "test in specific date", "jpg", "image/jpeg", creationDate, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "test in specific date", "test in specific date", "jpg", "image/jpeg", creationDate, 0)
require.NoError(t, err)
creationDate2 := model.GetMillisForTime(time.Date(2020, 03, 22, 23, 59, 59, 0, time.UTC))
p2, err := th.createFileInfo(th.User.Id, post2.Id, "test in specific date 2", "test in specific date 2", "jpg", "image/jpeg", creationDate2, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "test in specific date 2", "test in specific date 2", "jpg", "image/jpeg", creationDate2, 0)
require.NoError(t, err)
creationDate3 := model.GetMillisForTime(time.Date(2020, 03, 26, 16, 55, 0, 0, time.UTC))
p3, err := th.createFileInfo(th.User.Id, post1.Id, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate3, 0)
p3, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "test in the present", "test in the present", "jpg", "image/jpeg", creationDate3, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -917,11 +917,11 @@ func testFileInfoFilterFilesWithATerm(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post1.Id, "one two three", "one two three", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "one two three", "one two three", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post2.Id, "one four five six", "one four five six", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "one four five six", "one four five six", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post1.Id, "one seven eight nine", "one seven eight nine", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "one seven eight nine", "one seven eight nine", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -956,11 +956,11 @@ func testFileInfoSearchUsingBooleanOperators(t *testing.T, th *SearchTestHelper)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "one two three message", "one two three message", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "one two three message", "one two three message", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "two messages", "two messages", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "two messages", "two messages", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "another message", "another message", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "another message", "another message", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -998,13 +998,13 @@ func testFileInfoSearchUsingCombinedFilters(t *testing.T, th *SearchTestHelper)
defer th.deleteUserPosts(th.User.Id)
creationDate := model.GetMillisForTime(time.Date(2020, 03, 01, 12, 0, 0, 0, time.UTC))
p1, err := th.createFileInfo(th.User.Id, post2.Id, "one two three message", "one two three message", "jpg", "image/jpeg", creationDate, 0)
p1, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "one two three message", "one two three message", "jpg", "image/jpeg", creationDate, 0)
require.NoError(t, err)
creationDate2 := model.GetMillisForTime(time.Date(2020, 03, 10, 12, 0, 0, 0, time.UTC))
p2, err := th.createFileInfo(th.User2.Id, post2.Id, "two messages", "two messages", "jpg", "image/jpeg", creationDate2, 0)
p2, err := th.createFileInfo(th.User2.Id, post2.Id, post2.ChannelId, "two messages", "two messages", "jpg", "image/jpeg", creationDate2, 0)
require.NoError(t, err)
creationDate3 := model.GetMillisForTime(time.Date(2020, 03, 20, 12, 0, 0, 0, time.UTC))
p3, err := th.createFileInfo(th.User.Id, post1.Id, "two another message", "two another message", "jpg", "image/jpeg", creationDate3, 0)
p3, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "two another message", "two another message", "jpg", "image/jpeg", creationDate3, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
defer th.deleteUserFileInfos(th.User2.Id)
@@ -1067,13 +1067,13 @@ func testFileInfoSearchIgnoringStopWords(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "the search for a bunch of stop words", "the search for a bunch of stop words", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "the search for a bunch of stop words", "the search for a bunch of stop words", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "the objective is to avoid a bunch of stop words", "the objective is to avoid a bunch of stop words", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "the objective is to avoid a bunch of stop words", "the objective is to avoid a bunch of stop words", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p3, err := th.createFileInfo(th.User.Id, post.Id, "in the a on to where you", "in the a on to where you", "jpg", "image/jpeg", 0, 0)
p3, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "in the a on to where you", "in the a on to where you", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p4, err := th.createFileInfo(th.User.Id, post.Id, "where is the car?", "where is the car?", "jpg", "image/jpeg", 0, 0)
p4, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "where is the car?", "where is the car?", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1129,11 +1129,11 @@ func testFileInfoSupportStemming(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "search post", "search post", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "search post", "search post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "searching post", "searching post", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "searching post", "searching post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "another post", "another post", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "another post", "another post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1153,11 +1153,11 @@ func testFileInfoSupportWildcards(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "search post", "search post", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "search post", "search post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "searching", "searching", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "searching", "searching", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "another post", "another post", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "another post", "another post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1190,11 +1190,11 @@ func testFileInfoNotSupportPrecedingWildcards(t *testing.T, th *SearchTestHelper
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
_, err = th.createFileInfo(th.User.Id, post.Id, "search post", "search post", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "search post", "search post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "searching post", "searching post", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "searching post", "searching post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "another post", "another post", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "another post", "another post", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1212,9 +1212,9 @@ func testFileInfoSearchDiscardWildcardAlone(t *testing.T, th *SearchTestHelper)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "qwerty", "qwerty", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "qwerty", "qwerty", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "qwertyjkl", "qwertyjkl", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "qwertyjkl", "qwertyjkl", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1233,9 +1233,9 @@ func testFileInfoSupportTermsWithDash(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "search term-with-dash", "search term-with-dash", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "search term-with-dash", "search term-with-dash", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "searching term with dash", "searching term with dash", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "searching term with dash", "searching term with dash", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1267,9 +1267,9 @@ func testFileInfoSupportTermsWithUnderscore(t *testing.T, th *SearchTestHelper)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "search term_with_underscore", "search term_with_underscore", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "search term_with_underscore", "search term_with_underscore", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "searching term with underscore", "searching term with underscore", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "searching term with underscore", "searching term with underscore", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1307,11 +1307,11 @@ func testFileInfoSearchInDeletedOrArchivedChannels(t *testing.T, th *SearchTestH
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post1.Id, "message in deleted channel", "message in deleted channel", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "message in deleted channel", "message in deleted channel", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post2.Id, "message in regular channel", "message in regular channel", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "message in regular channel", "message in regular channel", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p3, err := th.createFileInfo(th.User.Id, post3.Id, "message in private channel", "message in private channel", "jpg", "image/jpeg", 0, 0)
p3, err := th.createFileInfo(th.User.Id, post3.Id, post3.ChannelId, "message in private channel", "message in private channel", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1382,9 +1382,9 @@ func testFileInfoSearchTermsWithDashes(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "message with-dash-term", "message with-dash-term", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message with-dash-term", "message with-dash-term", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "message with dash term", "message with dash term", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message with dash term", "message with dash term", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1431,9 +1431,9 @@ func testFileInfoSearchTermsWithDots(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "message with.dots.term", "message with.dots.term", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message with.dots.term", "message with.dots.term", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "message with dots term", "message with dots term", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message with dots term", "message with dots term", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1480,9 +1480,9 @@ func testFileInfoSearchTermsWithUnderscores(t *testing.T, th *SearchTestHelper)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "message with_underscores_term", "message with_underscores_term", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message with_underscores_term", "message with_underscores_term", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post.Id, "message with underscores term", "message with underscores term", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message with underscores term", "message with underscores term", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1532,11 +1532,11 @@ func testFileInfoSupportStemmingAndWildcards(t *testing.T, th *SearchTestHelper)
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post1.Id, "approve", "approve", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "approve", "approve", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post2.Id, "approved", "approved", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "approved", "approved", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p3, err := th.createFileInfo(th.User.Id, post2.Id, "approvedz", "approvedz", "jpg", "image/jpeg", 0, 0)
p3, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "approvedz", "approvedz", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1568,9 +1568,9 @@ func testFileInfoSupportWildcardOutsideQuotes(t *testing.T, th *SearchTestHelper
post2, err := th.createPost(th.User.Id, th.ChannelPrivate.Id, "testmessage", "", model.PostTypeDefault, 0, false)
require.NoError(t, err)
p1, err := th.createFileInfo(th.User.Id, post1.Id, "hello world", "hello world", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post1.Id, post1.ChannelId, "hello world", "hello world", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
p2, err := th.createFileInfo(th.User.Id, post2.Id, "hell or heaven", "hell or heaven", "jpg", "image/jpeg", 0, 0)
p2, err := th.createFileInfo(th.User.Id, post2.Id, post2.ChannelId, "hell or heaven", "hell or heaven", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1600,7 +1600,7 @@ func testFileInfoSlashShouldNotBeCharSeparator(t *testing.T, th *SearchTestHelpe
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "alpha/beta gamma, theta", "alpha/beta gamma, theta", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "alpha/beta gamma, theta", "alpha/beta gamma, theta", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)
@@ -1631,9 +1631,9 @@ func testFileInfoSearchEmailsWithoutQuotes(t *testing.T, th *SearchTestHelper) {
require.NoError(t, err)
defer th.deleteUserPosts(th.User.Id)
p1, err := th.createFileInfo(th.User.Id, post.Id, "message test@test.com", "message test@test.com", "jpg", "image/jpeg", 0, 0)
p1, err := th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message test@test.com", "message test@test.com", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
_, err = th.createFileInfo(th.User.Id, post.Id, "message test2@test.com", "message test2@test.com", "jpg", "image/jpeg", 0, 0)
_, err = th.createFileInfo(th.User.Id, post.Id, post.ChannelId, "message test2@test.com", "message test2@test.com", "jpg", "image/jpeg", 0, 0)
require.NoError(t, err)
defer th.deleteUserFileInfos(th.User.Id)

View File

@@ -371,10 +371,11 @@ func (th *SearchTestHelper) createPost(userID, channelID, message, hashtags, pos
return th.Store.Post().Save(postModel)
}
func (th *SearchTestHelper) createFileInfoModel(creatorID, postID, name, content, extension, mimeType string, createAt, size int64) *model.FileInfo {
func (th *SearchTestHelper) createFileInfoModel(creatorID, postID, channelID, name, content, extension, mimeType string, createAt, size int64) *model.FileInfo {
return &model.FileInfo{
CreatorId: creatorID,
PostId: postID,
ChannelId: channelID,
CreateAt: createAt,
UpdateAt: createAt,
DeleteAt: 0,
@@ -387,12 +388,12 @@ func (th *SearchTestHelper) createFileInfoModel(creatorID, postID, name, content
}
}
func (th *SearchTestHelper) createFileInfo(creatorID, postID, name, content, extension, mimeType string, createAt, size int64) (*model.FileInfo, error) {
func (th *SearchTestHelper) createFileInfo(creatorID, postID, channelID, name, content, extension, mimeType string, createAt, size int64) (*model.FileInfo, error) {
var creationTime int64 = 1000000
if createAt > 0 {
creationTime = createAt
}
fileInfoModel := th.createFileInfoModel(creatorID, postID, name, content, extension, mimeType, creationTime, size)
fileInfoModel := th.createFileInfoModel(creatorID, postID, channelID, name, content, extension, mimeType, creationTime, size)
return th.Store.FileInfo().Save(fileInfoModel)
}

View File

@@ -2265,7 +2265,7 @@ func (s SqlChannelStore) GetFileCount(channelId string) (int64, error) {
FileInfo
WHERE
FileInfo.DeleteAt = 0
AND FileInfo.PostId IN (SELECT id FROM Posts WHERE ChannelId = ?)`,
AND FileInfo.ChannelId = ?`,
channelId)
if err != nil {
return 0, errors.Wrapf(err, "failed to count files with channelId=%s", channelId)

View File

@@ -88,6 +88,7 @@ func newSqlFileInfoStore(sqlStore *SqlStore, metrics einterfaces.MetricsInterfac
"FileInfo.Id",
"FileInfo.CreatorId",
"FileInfo.PostId",
"COALESCE(FileInfo.ChannelId, '') AS ChannelId",
"FileInfo.CreateAt",
"FileInfo.UpdateAt",
"FileInfo.DeleteAt",
@@ -118,10 +119,10 @@ func (fs SqlFileInfoStore) Save(info *model.FileInfo) (*model.FileInfo, error) {
query := `
INSERT INTO FileInfo
(Id, CreatorId, PostId, CreateAt, UpdateAt, DeleteAt, Path, ThumbnailPath, PreviewPath,
(Id, CreatorId, PostId, ChannelId, CreateAt, UpdateAt, DeleteAt, Path, ThumbnailPath, PreviewPath,
Name, Extension, Size, MimeType, Width, Height, HasPreviewImage, MiniPreview, Content, RemoteId)
VALUES
(:Id, :CreatorId, :PostId, :CreateAt, :UpdateAt, :DeleteAt, :Path, :ThumbnailPath, :PreviewPath,
(:Id, :CreatorId, :PostId, :ChannelId, :CreateAt, :UpdateAt, :DeleteAt, :Path, :ThumbnailPath, :PreviewPath,
:Name, :Extension, :Size, :MimeType, :Width, :Height, :HasPreviewImage, :MiniPreview, :Content, :RemoteId)
`
@@ -133,9 +134,8 @@ func (fs SqlFileInfoStore) Save(info *model.FileInfo) (*model.FileInfo, error) {
func (fs SqlFileInfoStore) GetByIds(ids []string) ([]*model.FileInfo, error) {
query := fs.getQueryBuilder().
Select(append(fs.queryFields, "COALESCE(P.ChannelId, '') as ChannelId")...).
Select(fs.queryFields...).
From("FileInfo").
LeftJoin("Posts as P ON FileInfo.PostId=P.Id").
Where(sq.Eq{"FileInfo.Id": ids}).
Where(sq.Eq{"FileInfo.DeleteAt": 0}).
OrderBy("FileInfo.CreateAt DESC")
@@ -166,6 +166,8 @@ func (fs SqlFileInfoStore) Upsert(info *model.FileInfo) (*model.FileInfo, error)
return nil, err
}
// PostID and ChannelID are deliberately ignored
// from the list of fields to keep those two immutable.
queryString, args, err := fs.getQueryBuilder().
Update("FileInfo").
SetMap(map[string]any{
@@ -261,8 +263,7 @@ func (fs SqlFileInfoStore) GetWithOptions(page, perPage int, opt *model.GetFileI
From("FileInfo")
if len(opt.ChannelIds) > 0 {
query = query.Join("Posts ON FileInfo.PostId = Posts.Id").
Where(sq.Eq{"Posts.ChannelId": opt.ChannelIds})
query = query.Where(sq.Eq{"FileInfo.ChannelId": opt.ChannelIds})
}
if len(opt.UserIds) > 0 {
@@ -388,10 +389,11 @@ func (fs SqlFileInfoStore) GetForUser(userId string) ([]*model.FileInfo, error)
return infos, nil
}
func (fs SqlFileInfoStore) AttachToPost(fileId, postId, creatorId string) error {
func (fs SqlFileInfoStore) AttachToPost(fileId, postId, channelId, creatorId string) error {
query := fs.getQueryBuilder().
Update("FileInfo").
Set("PostId", postId).
Set("ChannelId", channelId).
Where(sq.And{
sq.Eq{"Id": fileId},
sq.Eq{"PostId": ""},
@@ -506,10 +508,9 @@ func (fs SqlFileInfoStore) Search(paramsList []*model.SearchParams, userId, team
return nil, err
}
query := fs.getQueryBuilder().
Select(append(fs.queryFields, "Coalesce(P.ChannelId, '') AS ChannelId")...).
Select(fs.queryFields...).
From("FileInfo").
LeftJoin("Posts as P ON FileInfo.PostId=P.Id").
LeftJoin("Channels as C ON C.Id=P.ChannelId").
LeftJoin("Channels as C ON C.Id=FileInfo.ChannelId").
LeftJoin("ChannelMembers as CM ON C.Id=CM.ChannelId").
Where(sq.Eq{"FileInfo.DeleteAt": 0}).
OrderBy("FileInfo.CreateAt DESC").
@@ -715,9 +716,8 @@ func (fs SqlFileInfoStore) CountAll() (int64, error) {
func (fs SqlFileInfoStore) GetFilesBatchForIndexing(startTime int64, startFileID string, limit int) ([]*model.FileForIndexing, error) {
files := []*model.FileForIndexing{}
sql, args, _ := fs.getQueryBuilder().
Select(append(fs.queryFields, "Coalesce(p.ChannelId, '') AS ChannelId")...).
Select(fs.queryFields...).
From("FileInfo").
LeftJoin("Posts AS p ON FileInfo.PostId = p.Id").
Where(sq.Or{
sq.Gt{"FileInfo.CreateAt": startTime},
sq.And{

View File

@@ -134,6 +134,15 @@ func checkChannelsPostsIntegrity(ss *SqlStore) model.IntegrityCheckResult {
})
}
func checkChannelsFileInfoIntegrity(ss *SqlStore) model.IntegrityCheckResult {
return checkParentChildIntegrity(ss, relationalCheckConfig{
parentName: "Channels",
parentIdAttr: "ChannelId",
childName: "FileInfo",
childIdAttr: "Id",
})
}
func checkCommandsCommandWebhooksIntegrity(ss *SqlStore) model.IntegrityCheckResult {
return checkParentChildIntegrity(ss, relationalCheckConfig{
parentName: "Commands",
@@ -458,6 +467,7 @@ func checkChannelsIntegrity(ss *SqlStore, results chan<- model.IntegrityCheckRes
results <- checkChannelsIncomingWebhooksIntegrity(ss)
results <- checkChannelsOutgoingWebhooksIntegrity(ss)
results <- checkChannelsPostsIntegrity(ss)
results <- checkChannelsFileInfoIntegrity(ss)
}
func checkCommandsIntegrity(ss *SqlStore, results chan<- model.IntegrityCheckResult) {

View File

@@ -115,7 +115,7 @@ func createEmoji(ss store.Store, userId string) *model.Emoji {
return emoji
}
func createFileInfo(ss store.Store, postId, userId string) *model.FileInfo {
func createFileInfo(ss store.Store, postId, channelId, userId string) *model.FileInfo {
m := model.FileInfo{}
m.PostId = postId
m.CreatorId = userId
@@ -623,7 +623,7 @@ func TestCheckPostsFileInfoIntegrity(t *testing.T) {
t.Run("should generate a report with one record", func(t *testing.T) {
postId := model.NewId()
info := createFileInfo(ss, postId, model.NewId())
info := createFileInfo(ss, postId, model.NewId(), model.NewId())
result := checkPostsFileInfoIntegrity(store)
require.NoError(t, result.Err)
data := result.Data.(model.RelationalIntegrityCheckData)
@@ -1226,7 +1226,7 @@ func TestCheckUsersFileInfoIntegrity(t *testing.T) {
t.Run("should generate a report with one record", func(t *testing.T) {
user := createUser(ss)
userId := user.Id
info := createFileInfo(ss, model.NewId(), userId)
info := createFileInfo(ss, model.NewId(), model.NewId(), userId)
dbmap.Exec(`DELETE FROM Users WHERE Id=?`, user.Id)
result := checkUsersFileInfoIntegrity(store)
require.NoError(t, result.Err)

View File

@@ -699,7 +699,7 @@ type FileInfoStore interface {
GetForUser(userID string) ([]*model.FileInfo, error)
GetWithOptions(page, perPage int, opt *model.GetFileInfosOptions) ([]*model.FileInfo, error)
InvalidateFileInfosForPostCache(postID string, deleted bool)
AttachToPost(fileID string, postID string, creatorID string) error
AttachToPost(fileID string, postID string, channelID, creatorID string) error
DeleteForPost(postID string) (string, error)
PermanentDelete(fileID string) error
PermanentDeleteBatch(endTime int64, limit int64) (int64, error)

View File

@@ -106,26 +106,31 @@ func testFileInfoSaveGetByPath(t *testing.T, ss store.Store) {
func testFileInfoGetForPost(t *testing.T, ss store.Store) {
userId := model.NewId()
postId := model.NewId()
channelId := model.NewId()
infos := []*model.FileInfo{
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
DeleteAt: 123,
},
{
PostId: model.NewId(),
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
@@ -225,25 +230,30 @@ func testFileInfoGetForUser(t *testing.T, ss store.Store) {
userId := model.NewId()
userId2 := model.NewId()
postId := model.NewId()
channelId := model.NewId()
infos := []*model.FileInfo{
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
{
PostId: model.NewId(),
ChannelId: channelId,
CreatorId: userId2,
Path: "file.txt",
},
@@ -289,6 +299,9 @@ func testFileInfoGetWithOptions(t *testing.T, ss store.Store) {
if post.Id != "" {
fileInfo.PostId = post.Id
}
if post.ChannelId != "" {
fileInfo.ChannelId = post.ChannelId
}
_, err := ss.FileInfo().Save(&fileInfo)
require.NoError(t, err)
return fileInfo
@@ -414,6 +427,7 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
t.Run("should attach files", func(t *testing.T) {
userId := model.NewId()
postId := model.NewId()
channelId := model.NewId()
info1, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: userId,
@@ -429,13 +443,15 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
require.Equal(t, "", info1.PostId)
require.Equal(t, "", info2.PostId)
err = ss.FileInfo().AttachToPost(info1.Id, postId, userId)
err = ss.FileInfo().AttachToPost(info1.Id, postId, channelId, userId)
assert.NoError(t, err)
info1.PostId = postId
info1.ChannelId = channelId
err = ss.FileInfo().AttachToPost(info2.Id, postId, userId)
err = ss.FileInfo().AttachToPost(info2.Id, postId, channelId, userId)
assert.NoError(t, err)
info2.PostId = postId
info2.ChannelId = channelId
data, err := ss.FileInfo().GetForPost(postId, true, false, false)
require.NoError(t, err)
@@ -449,6 +465,7 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
t.Run("should not attach files to multiple posts", func(t *testing.T) {
userId := model.NewId()
postId := model.NewId()
channelId := model.NewId()
info, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: userId,
@@ -458,16 +475,17 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
require.Equal(t, "", info.PostId)
err = ss.FileInfo().AttachToPost(info.Id, model.NewId(), userId)
err = ss.FileInfo().AttachToPost(info.Id, model.NewId(), channelId, userId)
require.NoError(t, err)
err = ss.FileInfo().AttachToPost(info.Id, postId, userId)
err = ss.FileInfo().AttachToPost(info.Id, postId, channelId, userId)
require.Error(t, err)
})
t.Run("should not attach files owned from a different user", func(t *testing.T) {
userId := model.NewId()
postId := model.NewId()
channelId := model.NewId()
info, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(),
@@ -477,12 +495,13 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
require.Equal(t, "", info.PostId)
err = ss.FileInfo().AttachToPost(info.Id, postId, userId)
err = ss.FileInfo().AttachToPost(info.Id, postId, channelId, userId)
assert.Error(t, err)
})
t.Run("should attach files uploaded by nouser", func(t *testing.T) {
postId := model.NewId()
channelId := model.NewId()
info, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: "nouser",
@@ -491,12 +510,13 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
require.NoError(t, err)
assert.Equal(t, "", info.PostId)
err = ss.FileInfo().AttachToPost(info.Id, postId, model.NewId())
err = ss.FileInfo().AttachToPost(info.Id, postId, channelId, model.NewId())
require.NoError(t, err)
data, err := ss.FileInfo().GetForPost(postId, true, false, false)
require.NoError(t, err)
info.PostId = postId
info.ChannelId = channelId
assert.EqualValues(t, []*model.FileInfo{info}, data)
})
}
@@ -504,26 +524,31 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
func testFileInfoDeleteForPost(t *testing.T, ss store.Store) {
userId := model.NewId()
postId := model.NewId()
channelId := model.NewId()
infos := []*model.FileInfo{
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
DeleteAt: 123,
},
{
PostId: model.NewId(),
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
},
@@ -549,6 +574,7 @@ func testFileInfoDeleteForPost(t *testing.T, ss store.Store) {
func testFileInfoPermanentDelete(t *testing.T, ss store.Store) {
info, err := ss.FileInfo().Save(&model.FileInfo{
PostId: model.NewId(),
ChannelId: model.NewId(),
CreatorId: model.NewId(),
Path: "file.txt",
})
@@ -560,9 +586,11 @@ func testFileInfoPermanentDelete(t *testing.T, ss store.Store) {
func testFileInfoPermanentDeleteBatch(t *testing.T, ss store.Store) {
postId := model.NewId()
channelId := model.NewId()
_, err := ss.FileInfo().Save(&model.FileInfo{
PostId: postId,
ChannelId: channelId,
CreatorId: model.NewId(),
Path: "file.txt",
CreateAt: 1000,
@@ -571,6 +599,7 @@ func testFileInfoPermanentDeleteBatch(t *testing.T, ss store.Store) {
_, err = ss.FileInfo().Save(&model.FileInfo{
PostId: postId,
ChannelId: channelId,
CreatorId: model.NewId(),
Path: "file.txt",
CreateAt: 1200,
@@ -579,6 +608,7 @@ func testFileInfoPermanentDeleteBatch(t *testing.T, ss store.Store) {
_, err = ss.FileInfo().Save(&model.FileInfo{
PostId: postId,
ChannelId: channelId,
CreatorId: model.NewId(),
Path: "file.txt",
CreateAt: 2000,
@@ -600,9 +630,11 @@ func testFileInfoPermanentDeleteBatch(t *testing.T, ss store.Store) {
func testFileInfoPermanentDeleteByUser(t *testing.T, ss store.Store) {
userId := model.NewId()
postId := model.NewId()
channelId := model.NewId()
_, err := ss.FileInfo().Save(&model.FileInfo{
PostId: postId,
ChannelId: channelId,
CreatorId: userId,
Path: "file.txt",
})
@@ -668,6 +700,7 @@ func testFileInfoStoreGetFilesBatchForIndexing(t *testing.T, ss store.Store) {
require.NoError(t, err)
f1, err := ss.FileInfo().Save(&model.FileInfo{
PostId: o1.Id,
ChannelId: o1.ChannelId,
CreatorId: model.NewId(),
Path: "file1.txt",
})
@@ -686,6 +719,7 @@ func testFileInfoStoreGetFilesBatchForIndexing(t *testing.T, ss store.Store) {
f2, err := ss.FileInfo().Save(&model.FileInfo{
PostId: o2.Id,
ChannelId: o2.ChannelId,
CreatorId: model.NewId(),
Path: "file2.txt",
})
@@ -705,6 +739,7 @@ func testFileInfoStoreGetFilesBatchForIndexing(t *testing.T, ss store.Store) {
f3, err := ss.FileInfo().Save(&model.FileInfo{
PostId: o3.Id,
ChannelId: o3.ChannelId,
CreatorId: model.NewId(),
Path: "file3.txt",
})
@@ -737,6 +772,7 @@ func testFileInfoStoreCountAll(t *testing.T, ss store.Store) {
require.NoError(t, err)
f1, err := ss.FileInfo().Save(&model.FileInfo{
PostId: model.NewId(),
ChannelId: model.NewId(),
CreatorId: model.NewId(),
Path: "file1.txt",
})
@@ -744,12 +780,14 @@ func testFileInfoStoreCountAll(t *testing.T, ss store.Store) {
_, err = ss.FileInfo().Save(&model.FileInfo{
PostId: model.NewId(),
ChannelId: model.NewId(),
CreatorId: model.NewId(),
Path: "file2.txt",
})
require.NoError(t, err)
_, err = ss.FileInfo().Save(&model.FileInfo{
PostId: model.NewId(),
ChannelId: model.NewId(),
CreatorId: model.NewId(),
Path: "file3.txt",
})

View File

@@ -14,13 +14,13 @@ type FileInfoStore struct {
mock.Mock
}
// AttachToPost provides a mock function with given fields: fileID, postID, creatorID
func (_m *FileInfoStore) AttachToPost(fileID string, postID string, creatorID string) error {
ret := _m.Called(fileID, postID, creatorID)
// AttachToPost provides a mock function with given fields: fileID, postID, channelID, creatorID
func (_m *FileInfoStore) AttachToPost(fileID string, postID string, channelID string, creatorID string) error {
ret := _m.Called(fileID, postID, channelID, creatorID)
var r0 error
if rf, ok := ret.Get(0).(func(string, string, string) error); ok {
r0 = rf(fileID, postID, creatorID)
if rf, ok := ret.Get(0).(func(string, string, string, string) error); ok {
r0 = rf(fileID, postID, channelID, creatorID)
} else {
r0 = ret.Error(0)
}

View File

@@ -3182,10 +3182,10 @@ func (s *TimerLayerEmojiStore) Search(name string, prefixOnly bool, limit int) (
return result, err
}
func (s *TimerLayerFileInfoStore) AttachToPost(fileID string, postID string, creatorID string) error {
func (s *TimerLayerFileInfoStore) AttachToPost(fileID string, postID string, channelID string, creatorID string) error {
start := time.Now()
err := s.FileInfoStore.AttachToPost(fileID, postID, creatorID)
err := s.FileInfoStore.AttachToPost(fileID, postID, channelID, creatorID)
elapsed := float64(time.Since(start)) / float64(time.Second)
if s.Root.Metrics != nil {

View File

@@ -680,7 +680,7 @@ func (si *SlackImporter) oldImportPost(post *model.Post) string {
firstPostId = post.Id
}
for _, fileId := range post.FileIds {
if err := si.store.FileInfo().AttachToPost(fileId, post.Id, post.UserId); err != nil {
if err := si.store.FileInfo().AttachToPost(fileId, post.Id, post.ChannelId, post.UserId); err != nil {
mlog.Error(
"Error attaching files to post.",
mlog.String("post_id", post.Id),