Migrate FileInfo store to Sync by default (#10837)

Этот коммит содержится в:
Jesús Espino
2019-05-15 22:07:03 +02:00
коммит произвёл GitHub
родитель 99ea780f20
Коммит beb7592c93
17 изменённых файлов: 462 добавлений и 459 удалений

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

@@ -20,9 +20,9 @@ import (
"github.com/mattermost/mattermost-server/app" "github.com/mattermost/mattermost-server/app"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/utils/fileutils" "github.com/mattermost/mattermost-server/utils/fileutils"
"github.com/mattermost/mattermost-server/utils/testutils" "github.com/mattermost/mattermost-server/utils/testutils"
"github.com/stretchr/testify/require"
) )
var testDir = "" var testDir = ""
@@ -680,13 +680,8 @@ func TestUploadFiles(t *testing.T) {
fmt.Sprintf("Wrong clientId returned, expected %v, got %v", tc.clientIds[i], fileResp.ClientIds[i])) fmt.Sprintf("Wrong clientId returned, expected %v, got %v", tc.clientIds[i], fileResp.ClientIds[i]))
} }
var dbInfo *model.FileInfo dbInfo, err := th.App.Srv.Store.FileInfo().Get(ri.Id)
result := <-th.App.Srv.Store.FileInfo().Get(ri.Id) require.Nil(t, err)
if result.Err != nil {
t.Error(result.Err)
} else {
dbInfo = result.Data.(*model.FileInfo)
}
checkEq(t, dbInfo.Id, ri.Id, "File id from response should match one stored in database") checkEq(t, dbInfo.Id, ri.Id, "File id from response should match one stored in database")
checkEq(t, dbInfo.CreatorId, tc.expectedCreatorId, "F ile should be assigned to user") checkEq(t, dbInfo.CreatorId, tc.expectedCreatorId, "F ile should be assigned to user")
checkEq(t, dbInfo.PostId, "", "File shouldn't have a post") checkEq(t, dbInfo.PostId, "", "File shouldn't have a post")
@@ -957,7 +952,8 @@ func TestGetFileLink(t *testing.T) {
CheckBadRequestStatus(t, resp) CheckBadRequestStatus(t, resp)
// Hacky way to assign file to a post (usually would be done by CreatePost call) // Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(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.BasicUser.Id)
require.Nil(t, err)
th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false }) th.App.UpdateConfig(func(cfg *model.Config) { *cfg.FileSettings.EnablePublicLink = false })
_, resp = Client.GetFileLink(fileId) _, resp = Client.GetFileLink(fileId)
@@ -993,11 +989,9 @@ func TestGetFileLink(t *testing.T) {
_, resp = th.SystemAdminClient.GetFileLink(fileId) _, resp = th.SystemAdminClient.GetFileLink(fileId)
CheckNoError(t, resp) CheckNoError(t, resp)
if result := <-th.App.Srv.Store.FileInfo().Get(fileId); result.Err != nil { fileInfo, err := th.App.Srv.Store.FileInfo().Get(fileId)
t.Fatal(result.Err) require.Nil(t, err)
} else { th.cleanupTestFile(fileInfo)
th.cleanupTestFile(result.Data.(*model.FileInfo))
}
} }
func TestGetFilePreview(t *testing.T) { func TestGetFilePreview(t *testing.T) {
@@ -1139,10 +1133,11 @@ func TestGetPublicFile(t *testing.T) {
} }
// Hacky way to assign file to a post (usually would be done by CreatePost call) // Hacky way to assign file to a post (usually would be done by CreatePost call)
store.Must(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.BasicUser.Id)
require.Nil(t, err)
result := <-th.App.Srv.Store.FileInfo().Get(fileId) info, err := th.App.Srv.Store.FileInfo().Get(fileId)
info := result.Data.(*model.FileInfo) require.Nil(t, err)
link := th.App.GeneratePublicLink(Client.Url, info) link := th.App.GeneratePublicLink(Client.Url, info)
// Wait a bit for files to ready // Wait a bit for files to ready
@@ -1174,9 +1169,8 @@ func TestGetPublicFile(t *testing.T) {
t.Fatal("should've failed to get image with public link after salt changed") t.Fatal("should've failed to get image with public link after salt changed")
} }
if err := th.cleanupTestFile(store.Must(th.App.Srv.Store.FileInfo().Get(fileId)).(*model.FileInfo)); err != nil { fileInfo, err := th.App.Srv.Store.FileInfo().Get(fileId)
t.Fatal(err) require.Nil(t, err)
} require.Nil(t, th.cleanupTestFile(fileInfo))
th.cleanupTestFile(info) th.cleanupTestFile(info)
} }

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

@@ -30,7 +30,6 @@ import (
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/plugin" "github.com/mattermost/mattermost-server/plugin"
"github.com/mattermost/mattermost-server/services/filesstore" "github.com/mattermost/mattermost-server/services/filesstore"
"github.com/mattermost/mattermost-server/store"
"github.com/mattermost/mattermost-server/utils" "github.com/mattermost/mattermost-server/utils"
) )
@@ -276,14 +275,14 @@ func (a *App) MigrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
if newPost := result.Data.(*model.PostList).Posts[post.Id]; len(newPost.Filenames) != len(post.Filenames) { if newPost := result.Data.(*model.PostList).Posts[post.Id]; len(newPost.Filenames) != len(post.Filenames) {
// Another thread has already created FileInfos for this post, so just return those // Another thread has already created FileInfos for this post, so just return those
result := <-a.Srv.Store.FileInfo().GetForPost(post.Id, true, false) fileInfos, err := a.Srv.Store.FileInfo().GetForPost(post.Id, true, false)
if result.Err != nil { if err != nil {
mlog.Error(fmt.Sprintf("Unable to get FileInfos for migrated post, err=%v", result.Err), mlog.String("post_id", post.Id)) mlog.Error(fmt.Sprintf("Unable to get FileInfos for migrated post, err=%v", result.Err), mlog.String("post_id", post.Id))
return []*model.FileInfo{} return []*model.FileInfo{}
} }
mlog.Debug("Post already migrated to use FileInfos", mlog.String("post_id", post.Id)) mlog.Debug("Post already migrated to use FileInfos", mlog.String("post_id", post.Id))
return result.Data.([]*model.FileInfo) return fileInfos
} }
mlog.Debug("Migrating post to use FileInfos", mlog.String("post_id", post.Id)) mlog.Debug("Migrating post to use FileInfos", mlog.String("post_id", post.Id))
@@ -291,9 +290,9 @@ func (a *App) MigrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
savedInfos := make([]*model.FileInfo, 0, len(infos)) savedInfos := make([]*model.FileInfo, 0, len(infos))
fileIds := make([]string, 0, len(filenames)) fileIds := make([]string, 0, len(filenames))
for _, info := range infos { for _, info := range infos {
if result := <-a.Srv.Store.FileInfo().Save(info); result.Err != nil { if _, err := a.Srv.Store.FileInfo().Save(info); err != nil {
mlog.Error( mlog.Error(
fmt.Sprintf("Unable to save file info when migrating post to use FileInfos, err=%v", result.Err), fmt.Sprintf("Unable to save file info when migrating post to use FileInfos, err=%v", err),
mlog.String("post_id", post.Id), mlog.String("post_id", post.Id),
mlog.String("file_info_id", info.Id), mlog.String("file_info_id", info.Id),
mlog.String("file_info_path", info.Path), mlog.String("file_info_path", info.Path),
@@ -506,7 +505,7 @@ type uploadFileTask struct {
// Testing: overrideable dependency functions // Testing: overrideable dependency functions
pluginsEnvironment *plugin.Environment pluginsEnvironment *plugin.Environment
writeFile func(io.Reader, string) (int64, *model.AppError) writeFile func(io.Reader, string) (int64, *model.AppError)
saveToDatabase func(*model.FileInfo) store.StoreChannel saveToDatabase func(*model.FileInfo) (*model.FileInfo, *model.AppError)
} }
func (t *uploadFileTask) init(a *App) { func (t *uploadFileTask) init(a *App) {
@@ -605,8 +604,8 @@ func (a *App) UploadFileX(channelId, name string, input io.Reader,
return nil, aerr return nil, aerr
} }
if result := <-t.saveToDatabase(t.fileinfo); result.Err != nil { if _, err := t.saveToDatabase(t.fileinfo); err != nil {
return nil, result.Err return nil, err
} }
wg.Wait() wg.Wait()
@@ -915,8 +914,8 @@ func (a *App) DoUploadFileExpectModification(now time.Time, rawTeamId string, ra
return nil, data, err return nil, data, err
} }
if result := <-a.Srv.Store.FileInfo().Save(info); result.Err != nil { if _, err := a.Srv.Store.FileInfo().Save(info); err != nil {
return nil, data, result.Err return nil, data, err
} }
return info, data, nil return info, data, nil
@@ -1059,11 +1058,7 @@ func (a *App) generatePreviewImage(img image.Image, previewPath string, width in
} }
func (a *App) GetFileInfo(fileId string) (*model.FileInfo, *model.AppError) { func (a *App) GetFileInfo(fileId string) (*model.FileInfo, *model.AppError) {
result := <-a.Srv.Store.FileInfo().Get(fileId) return a.Srv.Store.FileInfo().Get(fileId)
if result.Err != nil {
return nil, result.Err
}
return result.Data.(*model.FileInfo), nil
} }
func (a *App) GetFile(fileId string) ([]byte, *model.AppError) { func (a *App) GetFile(fileId string) ([]byte, *model.AppError) {
@@ -1086,21 +1081,19 @@ func (a *App) CopyFileInfos(userId string, fileIds []string) ([]string, *model.A
now := model.GetMillis() now := model.GetMillis()
for _, fileId := range fileIds { for _, fileId := range fileIds {
result := <-a.Srv.Store.FileInfo().Get(fileId) fileInfo, err := a.Srv.Store.FileInfo().Get(fileId)
if err != nil {
if result.Err != nil { return nil, err
return nil, result.Err
} }
fileInfo := result.Data.(*model.FileInfo)
fileInfo.Id = model.NewId() fileInfo.Id = model.NewId()
fileInfo.CreatorId = userId fileInfo.CreatorId = userId
fileInfo.CreateAt = now fileInfo.CreateAt = now
fileInfo.UpdateAt = now fileInfo.UpdateAt = now
fileInfo.PostId = "" fileInfo.PostId = ""
if result := <-a.Srv.Store.FileInfo().Save(fileInfo); result.Err != nil { if _, err := a.Srv.Store.FileInfo().Save(fileInfo); err != nil {
return newFileIds, result.Err return newFileIds, err
} }
newFileIds = append(newFileIds, fileInfo.Id) newFileIds = append(newFileIds, fileInfo.Id)

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

@@ -91,7 +91,7 @@ func BenchmarkUploadFile(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
<-th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id)
th.App.RemoveFile(info1.Path) th.App.RemoveFile(info1.Path)
}, },
@@ -110,7 +110,7 @@ func BenchmarkUploadFile(b *testing.B) {
if aerr != nil { if aerr != nil {
b.Fatal(aerr) b.Fatal(aerr)
} }
<-th.App.Srv.Store.FileInfo().PermanentDelete(info.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info.Id)
th.App.RemoveFile(info.Path) th.App.RemoveFile(info.Path)
}, },
}, },
@@ -128,7 +128,7 @@ func BenchmarkUploadFile(b *testing.B) {
if aerr != nil { if aerr != nil {
b.Fatal(aerr) b.Fatal(aerr)
} }
<-th.App.Srv.Store.FileInfo().PermanentDelete(info.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info.Id)
th.App.RemoveFile(info.Path) th.App.RemoveFile(info.Path)
}, },
}, },
@@ -143,7 +143,7 @@ func BenchmarkUploadFile(b *testing.B) {
if err != nil { if err != nil {
b.Fatal(err) b.Fatal(err)
} }
<-th.App.Srv.Store.FileInfo().PermanentDelete(resp.FileInfos[0].Id) th.App.Srv.Store.FileInfo().PermanentDelete(resp.FileInfos[0].Id)
th.App.RemoveFile(resp.FileInfos[0].Path) th.App.RemoveFile(resp.FileInfos[0].Path)
}, },
}, },
@@ -160,7 +160,7 @@ func BenchmarkUploadFile(b *testing.B) {
if aerr != nil { if aerr != nil {
b.Fatal(aerr) b.Fatal(aerr)
} }
<-th.App.Srv.Store.FileInfo().PermanentDelete(info.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info.Id)
th.App.RemoveFile(info.Path) th.App.RemoveFile(info.Path)
}, },
}, },
@@ -177,7 +177,7 @@ func BenchmarkUploadFile(b *testing.B) {
if aerr != nil { if aerr != nil {
b.Fatal(aerr) b.Fatal(aerr)
} }
<-th.App.Srv.Store.FileInfo().PermanentDelete(info.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info.Id)
th.App.RemoveFile(info.Path) th.App.RemoveFile(info.Path)
}, },
}, },

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

@@ -55,7 +55,7 @@ func TestDoUploadFile(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} else { } else {
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id)
th.App.RemoveFile(info1.Path) th.App.RemoveFile(info1.Path)
}() }()
} }
@@ -69,7 +69,7 @@ func TestDoUploadFile(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} else { } else {
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info2.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info2.Id)
th.App.RemoveFile(info2.Path) th.App.RemoveFile(info2.Path)
}() }()
} }
@@ -83,7 +83,7 @@ func TestDoUploadFile(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} else { } else {
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info3.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info3.Id)
th.App.RemoveFile(info3.Path) th.App.RemoveFile(info3.Path)
}() }()
} }
@@ -97,7 +97,7 @@ func TestDoUploadFile(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} else { } else {
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info4.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info4.Id)
th.App.RemoveFile(info4.Path) th.App.RemoveFile(info4.Path)
}() }()
} }
@@ -120,7 +120,7 @@ func TestUploadFile(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} else { } else {
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id)
th.App.RemoveFile(info1.Path) th.App.RemoveFile(info1.Path)
}() }()
} }
@@ -199,7 +199,7 @@ func TestCopyFileInfos(t *testing.T) {
info1, err := th.App.DoUploadFile(time.Date(2007, 2, 4, 1, 2, 3, 4, time.Local), teamId, channelId, userId, filename, data) info1, err := th.App.DoUploadFile(time.Date(2007, 2, 4, 1, 2, 3, 4, time.Local), teamId, channelId, userId, filename, data)
require.Nil(t, err) require.Nil(t, err)
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id)
th.App.RemoveFile(info1.Path) th.App.RemoveFile(info1.Path)
}() }()
@@ -209,7 +209,7 @@ func TestCopyFileInfos(t *testing.T) {
info2, err := th.App.GetFileInfo(infoIds[0]) info2, err := th.App.GetFileInfo(infoIds[0])
require.Nil(t, err) require.Nil(t, err)
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info2.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info2.Id)
th.App.RemoveFile(info2.Path) th.App.RemoveFile(info2.Path)
}() }()

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

@@ -1064,8 +1064,8 @@ func (a *App) uploadAttachments(attachments *[]AttachmentImportData, post *model
func (a *App) UpdateFileInfoWithPostId(post *model.Post) { func (a *App) UpdateFileInfoWithPostId(post *model.Post) {
for _, fileId := range post.FileIds { for _, fileId := range post.FileIds {
if result := <-a.Srv.Store.FileInfo().AttachToPost(fileId, post.Id, post.UserId); result.Err != nil { if err := a.Srv.Store.FileInfo().AttachToPost(fileId, post.Id, post.UserId); err != nil {
mlog.Error(fmt.Sprintf("Error attaching files to post. postId=%v, fileIds=%v, message=%v", post.Id, post.FileIds, result.Err), mlog.String("post_id", post.Id)) mlog.Error(fmt.Sprintf("Error attaching files to post. postId=%v, fileIds=%v, message=%v", post.Id, post.FileIds, err), mlog.String("post_id", post.Id))
} }
} }
} }

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

@@ -11,6 +11,7 @@ import (
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/mattermost/mattermost-server/model" "github.com/mattermost/mattermost-server/model"
"github.com/mattermost/mattermost-server/utils/fileutils" "github.com/mattermost/mattermost-server/utils/fileutils"
@@ -250,12 +251,9 @@ func TestImportProcessImportDataFileVersionLine(t *testing.T) {
} }
func GetAttachments(userId string, th *TestHelper, t *testing.T) []*model.FileInfo { func GetAttachments(userId string, th *TestHelper, t *testing.T) []*model.FileInfo {
if result := <-th.App.Srv.Store.FileInfo().GetForUser(userId); result.Err != nil { fileInfos, err := th.App.Srv.Store.FileInfo().GetForUser(userId)
t.Fatal(result.Err.Error()) require.Nil(t, err)
} else { return fileInfos
return result.Data.([]*model.FileInfo)
}
return nil
} }
func AssertFileIdsInPost(files []*model.FileInfo, th *TestHelper, t *testing.T) { func AssertFileIdsInPost(files []*model.FileInfo, th *TestHelper, t *testing.T) {

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

@@ -30,10 +30,14 @@ func (a *App) SendNotifications(post *model.Post, team *model.Team, channel *mod
pchan := a.Srv.Store.User().GetAllProfilesInChannel(channel.Id, true) pchan := a.Srv.Store.User().GetAllProfilesInChannel(channel.Id, true)
cmnchan := a.Srv.Store.Channel().GetAllChannelMembersNotifyPropsForChannel(channel.Id, true) cmnchan := a.Srv.Store.Channel().GetAllChannelMembersNotifyPropsForChannel(channel.Id, true)
var fchan store.StoreChannel var fchan chan store.StoreResult
if len(post.FileIds) != 0 { if len(post.FileIds) != 0 {
fchan = a.Srv.Store.FileInfo().GetForPost(post.Id, true, true) fchan = make(chan store.StoreResult, 1)
go func() {
fileInfos, err := a.Srv.Store.FileInfo().GetForPost(post.Id, true, true)
fchan <- store.StoreResult{Data: fileInfos, Err: err}
close(fchan)
}()
} }
result := <-pchan result := <-pchan

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

@@ -290,11 +290,10 @@ func (a *App) GetMessageForNotification(post *model.Post, translateFunc i18n.Tra
} }
// extract the filenames from their paths and determine what type of files are attached // extract the filenames from their paths and determine what type of files are attached
result := <-a.Srv.Store.FileInfo().GetForPost(post.Id, true, true) infos, err := a.Srv.Store.FileInfo().GetForPost(post.Id, true, true)
if result.Err != nil { if err != nil {
mlog.Warn(fmt.Sprintf("Encountered error when getting files for notification message, post_id=%v, err=%v", post.Id, result.Err), mlog.String("post_id", post.Id)) mlog.Warn(fmt.Sprintf("Encountered error when getting files for notification message, post_id=%v, err=%v", post.Id, err), mlog.String("post_id", post.Id))
} }
infos := result.Data.([]*model.FileInfo)
filenames := make([]string, len(infos)) filenames := make([]string, len(infos))
onlyImages := true onlyImages := true

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

@@ -291,7 +291,7 @@ func TestPluginAPIGetFile(t *testing.T) {
info, err := th.App.DoUploadFile(uploadTime, th.BasicTeam.Id, th.BasicChannel.Id, th.BasicUser.Id, filename, fileData) info, err := th.App.DoUploadFile(uploadTime, th.BasicTeam.Id, th.BasicChannel.Id, th.BasicUser.Id, filename, fileData)
require.Nil(t, err) require.Nil(t, err)
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info.Id)
th.App.RemoveFile(info.Path) th.App.RemoveFile(info.Path)
}() }()

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

@@ -302,9 +302,9 @@ func (a *App) CreatePost(post *model.Post, channel *model.Channel, triggerWebhoo
func (a *App) attachFilesToPost(post *model.Post) *model.AppError { func (a *App) attachFilesToPost(post *model.Post) *model.AppError {
var attachedIds []string var attachedIds []string
for _, fileId := range post.FileIds { for _, fileId := range post.FileIds {
result := <-a.Srv.Store.FileInfo().AttachToPost(fileId, post.Id, post.UserId) err := a.Srv.Store.FileInfo().AttachToPost(fileId, post.Id, post.UserId)
if result.Err != nil { if err != nil {
mlog.Warn("Failed to attach file to post", mlog.String("file_id", fileId), mlog.String("post_id", post.Id), mlog.Err(result.Err)) mlog.Warn("Failed to attach file to post", mlog.String("file_id", fileId), mlog.String("post_id", post.Id), mlog.Err(err))
continue continue
} }
@@ -776,8 +776,8 @@ func (a *App) DeletePostFiles(post *model.Post) {
return return
} }
if result := <-a.Srv.Store.FileInfo().DeleteForPost(post.Id); result.Err != nil { if _, err := a.Srv.Store.FileInfo().DeleteForPost(post.Id); err != nil {
mlog.Warn(fmt.Sprintf("Encountered error when deleting files for post, post_id=%v, err=%v", post.Id, result.Err), mlog.String("post_id", post.Id)) mlog.Warn(fmt.Sprintf("Encountered error when deleting files for post, post_id=%v, err=%v", post.Id, err), mlog.String("post_id", post.Id))
} }
} }
@@ -980,12 +980,7 @@ func (a *App) GetFileInfosForPostWithMigration(postId string) ([]*model.FileInfo
} }
func (a *App) GetFileInfosForPost(postId string) ([]*model.FileInfo, *model.AppError) { func (a *App) GetFileInfosForPost(postId string) ([]*model.FileInfo, *model.AppError) {
result := <-a.Srv.Store.FileInfo().GetForPost(postId, false, true) return a.Srv.Store.FileInfo().GetForPost(postId, false, true)
if result.Err != nil {
return nil, result.Err
}
return result.Data.([]*model.FileInfo), nil
} }
func (a *App) PostWithProxyAddedToImageURLs(post *model.Post) *model.Post { func (a *App) PostWithProxyAddedToImageURLs(post *model.Post) *model.Post {

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

@@ -191,19 +191,22 @@ func TestAttachFilesToPost(t *testing.T) {
th := Setup(t).InitBasic() th := Setup(t).InitBasic()
defer th.TearDown() defer th.TearDown()
info1 := store.Must(th.App.Srv.Store.FileInfo().Save(&model.FileInfo{ info1, err := th.App.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
Path: "path.txt", Path: "path.txt",
})).(*model.FileInfo) })
info2 := store.Must(th.App.Srv.Store.FileInfo().Save(&model.FileInfo{ require.Nil(t, err)
info2, err := th.App.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
Path: "path.txt", Path: "path.txt",
})).(*model.FileInfo) })
require.Nil(t, err)
post := th.BasicPost post := th.BasicPost
post.FileIds = []string{info1.Id, info2.Id} post.FileIds = []string{info1.Id, info2.Id}
err := th.App.attachFilesToPost(post) err = th.App.attachFilesToPost(post)
assert.Nil(t, err) assert.Nil(t, err)
infos, err := th.App.GetFileInfosForPost(post.Id) infos, err := th.App.GetFileInfosForPost(post.Id)
@@ -215,20 +218,23 @@ func TestAttachFilesToPost(t *testing.T) {
th := Setup(t).InitBasic() th := Setup(t).InitBasic()
defer th.TearDown() defer th.TearDown()
info1 := store.Must(th.App.Srv.Store.FileInfo().Save(&model.FileInfo{ info1, err := th.App.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
Path: "path.txt", Path: "path.txt",
PostId: model.NewId(), PostId: model.NewId(),
})).(*model.FileInfo) })
info2 := store.Must(th.App.Srv.Store.FileInfo().Save(&model.FileInfo{ require.Nil(t, err)
info2, err := th.App.Srv.Store.FileInfo().Save(&model.FileInfo{
CreatorId: th.BasicUser.Id, CreatorId: th.BasicUser.Id,
Path: "path.txt", Path: "path.txt",
})).(*model.FileInfo) })
require.Nil(t, err)
post := th.BasicPost post := th.BasicPost
post.FileIds = []string{info1.Id, info2.Id} post.FileIds = []string{info1.Id, info2.Id}
err := th.App.attachFilesToPost(post) err = th.App.attachFilesToPost(post)
assert.Nil(t, err) assert.Nil(t, err)
infos, err := th.App.GetFileInfosForPost(post.Id) infos, err := th.App.GetFileInfosForPost(post.Id)
@@ -623,7 +629,7 @@ func TestDeletePostWithFileAttachments(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} else { } else {
defer func() { defer func() {
<-th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id) th.App.Srv.Store.FileInfo().PermanentDelete(info1.Id)
th.App.RemoveFile(info1.Path) th.App.RemoveFile(info1.Path)
}() }()
} }

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

@@ -747,8 +747,8 @@ func (a *App) OldImportPost(post *model.Post) string {
firstPostId = post.Id firstPostId = post.Id
} }
for _, fileId := range post.FileIds { for _, fileId := range post.FileIds {
if result := <-a.Srv.Store.FileInfo().AttachToPost(fileId, post.Id, post.UserId); result.Err != nil { if err := a.Srv.Store.FileInfo().AttachToPost(fileId, post.Id, post.UserId); err != nil {
mlog.Error(fmt.Sprintf("Error attaching files to post. postId=%v, fileIds=%v, message=%v", post.Id, post.FileIds, result.Err), mlog.String("post_id", post.Id)) mlog.Error(fmt.Sprintf("Error attaching files to post. postId=%v, fileIds=%v, message=%v", post.Id, post.FileIds, err), mlog.String("post_id", post.Id))
} }
} }
post.FileIds = nil post.FileIds = nil

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

@@ -1447,12 +1447,11 @@ func (a *App) PermanentDeleteUser(user *model.User) *model.AppError {
return result.Err return result.Err
} }
result := <-a.Srv.Store.FileInfo().GetForUser(user.Id) infos, err := a.Srv.Store.FileInfo().GetForUser(user.Id)
if result.Err != nil { if err != nil {
mlog.Warn("Error getting file list for user from FileInfoStore") mlog.Warn("Error getting file list for user from FileInfoStore")
} }
infos := result.Data.([]*model.FileInfo)
for _, info := range infos { for _, info := range infos {
res, err := a.FileExists(info.Path) res, err := a.FileExists(info.Path)
if err != nil { if err != nil {
@@ -1480,8 +1479,8 @@ func (a *App) PermanentDeleteUser(user *model.User) *model.AppError {
} }
} }
if result := <-a.Srv.Store.FileInfo().PermanentDeleteByUser(user.Id); result.Err != nil { if _, err := a.Srv.Store.FileInfo().PermanentDeleteByUser(user.Id); err != nil {
return result.Err return err
} }
if result := <-a.Srv.Store.User().PermanentDelete(user.Id); result.Err != nil { if result := <-a.Srv.Store.User().PermanentDelete(user.Id); result.Err != nil {

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

@@ -61,50 +61,42 @@ func (fs SqlFileInfoStore) CreateIndexesIfNotExists() {
fs.CreateIndexIfNotExists("idx_fileinfo_postid_at", "FileInfo", "PostId") fs.CreateIndexIfNotExists("idx_fileinfo_postid_at", "FileInfo", "PostId")
} }
func (fs SqlFileInfoStore) Save(info *model.FileInfo) store.StoreChannel { func (fs SqlFileInfoStore) Save(info *model.FileInfo) (*model.FileInfo, *model.AppError) {
return store.Do(func(result *store.StoreResult) { info.PreSave()
info.PreSave() if err := info.IsValid(); err != nil {
if result.Err = info.IsValid(); result.Err != nil { return nil, err
return }
}
if err := fs.GetMaster().Insert(info); err != nil { if err := fs.GetMaster().Insert(info); err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.Save", "store.sql_file_info.save.app_error", nil, err.Error(), http.StatusInternalServerError) return nil, model.NewAppError("SqlFileInfoStore.Save", "store.sql_file_info.save.app_error", nil, err.Error(), http.StatusInternalServerError)
} else { }
result.Data = info return info, nil
}
})
} }
func (fs SqlFileInfoStore) Get(id string) store.StoreChannel { func (fs SqlFileInfoStore) Get(id string) (*model.FileInfo, *model.AppError) {
return store.Do(func(result *store.StoreResult) { info := &model.FileInfo{}
info := &model.FileInfo{}
if err := fs.GetReplica().SelectOne(info, if err := fs.GetReplica().SelectOne(info,
`SELECT `SELECT
* *
FROM FROM
FileInfo FileInfo
WHERE WHERE
Id = :Id Id = :Id
AND DeleteAt = 0`, map[string]interface{}{"Id": id}); err != nil { AND DeleteAt = 0`, map[string]interface{}{"Id": id}); err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
result.Err = model.NewAppError("SqlFileInfoStore.Get", "store.sql_file_info.get.app_error", nil, "id="+id+", "+err.Error(), http.StatusNotFound) return nil, model.NewAppError("SqlFileInfoStore.Get", "store.sql_file_info.get.app_error", nil, "id="+id+", "+err.Error(), http.StatusNotFound)
} else {
result.Err = model.NewAppError("SqlFileInfoStore.Get", "store.sql_file_info.get.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError)
}
} else {
result.Data = info
} }
}) return nil, model.NewAppError("SqlFileInfoStore.Get", "store.sql_file_info.get.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError)
}
return info, nil
} }
func (fs SqlFileInfoStore) GetByPath(path string) store.StoreChannel { func (fs SqlFileInfoStore) GetByPath(path string) (*model.FileInfo, *model.AppError) {
return store.Do(func(result *store.StoreResult) { info := &model.FileInfo{}
info := &model.FileInfo{}
if err := fs.GetReplica().SelectOne(info, if err := fs.GetReplica().SelectOne(info,
`SELECT `SELECT
* *
FROM FROM
FileInfo FileInfo
@@ -112,11 +104,9 @@ func (fs SqlFileInfoStore) GetByPath(path string) store.StoreChannel {
Path = :Path Path = :Path
AND DeleteAt = 0 AND DeleteAt = 0
LIMIT 1`, map[string]interface{}{"Path": path}); err != nil { LIMIT 1`, map[string]interface{}{"Path": path}); err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.GetByPath", "store.sql_file_info.get_by_path.app_error", nil, "path="+path+", "+err.Error(), http.StatusInternalServerError) return nil, model.NewAppError("SqlFileInfoStore.GetByPath", "store.sql_file_info.get_by_path.app_error", nil, "path="+path+", "+err.Error(), http.StatusInternalServerError)
} else { }
result.Data = info return info, nil
}
})
} }
func (fs SqlFileInfoStore) InvalidateFileInfosForPostCache(postId string) { func (fs SqlFileInfoStore) InvalidateFileInfosForPostCache(postId string) {
@@ -126,37 +116,34 @@ func (fs SqlFileInfoStore) InvalidateFileInfosForPostCache(postId string) {
} }
} }
func (fs SqlFileInfoStore) GetForPost(postId string, readFromMaster bool, allowFromCache bool) store.StoreChannel { func (fs SqlFileInfoStore) GetForPost(postId string, readFromMaster bool, allowFromCache bool) ([]*model.FileInfo, *model.AppError) {
return store.Do(func(result *store.StoreResult) { if allowFromCache {
if allowFromCache { if cacheItem, ok := fileInfoCache.Get(postId); ok {
if cacheItem, ok := fileInfoCache.Get(postId); ok {
if fs.metrics != nil {
fs.metrics.IncrementMemCacheHitCounter("File Info Cache")
}
result.Data = cacheItem.([]*model.FileInfo)
return
} else {
if fs.metrics != nil {
fs.metrics.IncrementMemCacheMissCounter("File Info Cache")
}
}
} else {
if fs.metrics != nil { if fs.metrics != nil {
fs.metrics.IncrementMemCacheMissCounter("File Info Cache") fs.metrics.IncrementMemCacheHitCounter("File Info Cache")
} }
return cacheItem.([]*model.FileInfo), nil
} }
if fs.metrics != nil {
var infos []*model.FileInfo fs.metrics.IncrementMemCacheMissCounter("File Info Cache")
dbmap := fs.GetReplica()
if readFromMaster {
dbmap = fs.GetMaster()
} }
} else {
if fs.metrics != nil {
fs.metrics.IncrementMemCacheMissCounter("File Info Cache")
}
}
if _, err := dbmap.Select(&infos, var infos []*model.FileInfo
`SELECT
dbmap := fs.GetReplica()
if readFromMaster {
dbmap = fs.GetMaster()
}
if _, err := dbmap.Select(&infos,
`SELECT
* *
FROM FROM
FileInfo FileInfo
@@ -165,26 +152,23 @@ func (fs SqlFileInfoStore) GetForPost(postId string, readFromMaster bool, allowF
AND DeleteAt = 0 AND DeleteAt = 0
ORDER BY ORDER BY
CreateAt`, map[string]interface{}{"PostId": postId}); err != nil { CreateAt`, map[string]interface{}{"PostId": postId}); err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.GetForPost", return nil, model.NewAppError("SqlFileInfoStore.GetForPost",
"store.sql_file_info.get_for_post.app_error", nil, "post_id="+postId+", "+err.Error(), http.StatusInternalServerError) "store.sql_file_info.get_for_post.app_error", nil, "post_id="+postId+", "+err.Error(), http.StatusInternalServerError)
} else { }
if len(infos) > 0 { if len(infos) > 0 {
fileInfoCache.AddWithExpiresInSecs(postId, infos, FILE_INFO_CACHE_SEC) fileInfoCache.AddWithExpiresInSecs(postId, infos, FILE_INFO_CACHE_SEC)
} }
result.Data = infos return infos, nil
}
})
} }
func (fs SqlFileInfoStore) GetForUser(userId string) store.StoreChannel { func (fs SqlFileInfoStore) GetForUser(userId string) ([]*model.FileInfo, *model.AppError) {
return store.Do(func(result *store.StoreResult) { var infos []*model.FileInfo
var infos []*model.FileInfo
dbmap := fs.GetReplica() dbmap := fs.GetReplica()
if _, err := dbmap.Select(&infos, if _, err := dbmap.Select(&infos,
`SELECT `SELECT
* *
FROM FROM
FileInfo FileInfo
@@ -193,18 +177,15 @@ func (fs SqlFileInfoStore) GetForUser(userId string) store.StoreChannel {
AND DeleteAt = 0 AND DeleteAt = 0
ORDER BY ORDER BY
CreateAt`, map[string]interface{}{"CreatorId": userId}); err != nil { CreateAt`, map[string]interface{}{"CreatorId": userId}); err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.GetForPost", return nil, model.NewAppError("SqlFileInfoStore.GetForPost",
"store.sql_file_info.get_for_user_id.app_error", nil, "creator_id="+userId+", "+err.Error(), http.StatusInternalServerError) "store.sql_file_info.get_for_user_id.app_error", nil, "creator_id="+userId+", "+err.Error(), http.StatusInternalServerError)
} else { }
result.Data = infos return infos, nil
}
})
} }
func (fs SqlFileInfoStore) AttachToPost(fileId, postId, creatorId string) store.StoreChannel { func (fs SqlFileInfoStore) AttachToPost(fileId, postId, creatorId string) *model.AppError {
return store.Do(func(result *store.StoreResult) { sqlResult, err := fs.GetMaster().Exec(
sqlResult, err := fs.GetMaster().Exec( `UPDATE
`UPDATE
FileInfo FileInfo
SET SET
PostId = :PostId PostId = :PostId
@@ -212,94 +193,80 @@ func (fs SqlFileInfoStore) AttachToPost(fileId, postId, creatorId string) store.
Id = :Id Id = :Id
AND PostId = '' AND PostId = ''
AND CreatorId = :CreatorId`, map[string]interface{}{"PostId": postId, "Id": fileId, "CreatorId": creatorId}) AND CreatorId = :CreatorId`, map[string]interface{}{"PostId": postId, "Id": fileId, "CreatorId": creatorId})
if err != nil { if err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.AttachToPost", return model.NewAppError("SqlFileInfoStore.AttachToPost",
"store.sql_file_info.attach_to_post.app_error", nil, "post_id="+postId+", file_id="+fileId+", err="+err.Error(), http.StatusInternalServerError) "store.sql_file_info.attach_to_post.app_error", nil, "post_id="+postId+", file_id="+fileId+", err="+err.Error(), http.StatusInternalServerError)
return }
}
count, err := sqlResult.RowsAffected() count, err := sqlResult.RowsAffected()
if err != nil { if err != nil {
// RowsAffected should never fail with the MySQL or Postgres drivers // RowsAffected should never fail with the MySQL or Postgres drivers
result.Err = model.NewAppError("SqlFileInfoStore.AttachToPost", return model.NewAppError("SqlFileInfoStore.AttachToPost",
"store.sql_file_info.attach_to_post.app_error", nil, "post_id="+postId+", file_id="+fileId+", err="+err.Error(), http.StatusInternalServerError) "store.sql_file_info.attach_to_post.app_error", nil, "post_id="+postId+", file_id="+fileId+", err="+err.Error(), http.StatusInternalServerError)
} else if count == 0 { } else if count == 0 {
// Could not attach the file to the post // Could not attach the file to the post
result.Err = model.NewAppError("SqlFileInfoStore.AttachToPost", return model.NewAppError("SqlFileInfoStore.AttachToPost",
"store.sql_file_info.attach_to_post.app_error", nil, "post_id="+postId+", file_id="+fileId, http.StatusBadRequest) "store.sql_file_info.attach_to_post.app_error", nil, "post_id="+postId+", file_id="+fileId, http.StatusBadRequest)
} }
}) return nil
} }
func (fs SqlFileInfoStore) DeleteForPost(postId string) store.StoreChannel { func (fs SqlFileInfoStore) DeleteForPost(postId string) (string, *model.AppError) {
return store.Do(func(result *store.StoreResult) { if _, err := fs.GetMaster().Exec(
if _, err := fs.GetMaster().Exec( `UPDATE
`UPDATE
FileInfo FileInfo
SET SET
DeleteAt = :DeleteAt DeleteAt = :DeleteAt
WHERE WHERE
PostId = :PostId`, map[string]interface{}{"DeleteAt": model.GetMillis(), "PostId": postId}); err != nil { PostId = :PostId`, map[string]interface{}{"DeleteAt": model.GetMillis(), "PostId": postId}); err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.DeleteForPost", return "", model.NewAppError("SqlFileInfoStore.DeleteForPost",
"store.sql_file_info.delete_for_post.app_error", nil, "post_id="+postId+", err="+err.Error(), http.StatusInternalServerError) "store.sql_file_info.delete_for_post.app_error", nil, "post_id="+postId+", err="+err.Error(), http.StatusInternalServerError)
} else { }
result.Data = postId return postId, nil
}
})
} }
func (fs SqlFileInfoStore) PermanentDelete(fileId string) store.StoreChannel { func (fs SqlFileInfoStore) PermanentDelete(fileId string) *model.AppError {
return store.Do(func(result *store.StoreResult) { if _, err := fs.GetMaster().Exec(
if _, err := fs.GetMaster().Exec( `DELETE FROM
`DELETE FROM
FileInfo FileInfo
WHERE WHERE
Id = :FileId`, map[string]interface{}{"FileId": fileId}); err != nil { Id = :FileId`, map[string]interface{}{"FileId": fileId}); err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.PermanentDelete", return model.NewAppError("SqlFileInfoStore.PermanentDelete",
"store.sql_file_info.permanent_delete.app_error", nil, "file_id="+fileId+", err="+err.Error(), http.StatusInternalServerError) "store.sql_file_info.permanent_delete.app_error", nil, "file_id="+fileId+", err="+err.Error(), http.StatusInternalServerError)
} }
}) return nil
} }
func (s SqlFileInfoStore) PermanentDeleteBatch(endTime int64, limit int64) store.StoreChannel { func (s SqlFileInfoStore) PermanentDeleteBatch(endTime int64, limit int64) (int64, *model.AppError) {
return store.Do(func(result *store.StoreResult) { var query string
var query string if s.DriverName() == "postgres" {
if s.DriverName() == "postgres" { query = "DELETE from FileInfo WHERE Id = any (array (SELECT Id FROM FileInfo WHERE CreateAt < :EndTime LIMIT :Limit))"
query = "DELETE from FileInfo WHERE Id = any (array (SELECT Id FROM FileInfo WHERE CreateAt < :EndTime LIMIT :Limit))" } else {
} else { query = "DELETE from FileInfo WHERE CreateAt < :EndTime LIMIT :Limit"
query = "DELETE from FileInfo WHERE CreateAt < :EndTime LIMIT :Limit" }
}
sqlResult, err := s.GetMaster().Exec(query, map[string]interface{}{"EndTime": endTime, "Limit": limit}) sqlResult, err := s.GetMaster().Exec(query, map[string]interface{}{"EndTime": endTime, "Limit": limit})
if err != nil { if err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.PermanentDeleteBatch", "store.sql_file_info.permanent_delete_batch.app_error", nil, ""+err.Error(), http.StatusInternalServerError) return 0, model.NewAppError("SqlFileInfoStore.PermanentDeleteBatch", "store.sql_file_info.permanent_delete_batch.app_error", nil, ""+err.Error(), http.StatusInternalServerError)
} else { }
rowsAffected, err1 := sqlResult.RowsAffected() rowsAffected, err1 := sqlResult.RowsAffected()
if err1 != nil { if err1 != nil {
result.Err = model.NewAppError("SqlFileInfoStore.PermanentDeleteBatch", "store.sql_file_info.permanent_delete_batch.app_error", nil, ""+err.Error(), http.StatusInternalServerError) return 0, model.NewAppError("SqlFileInfoStore.PermanentDeleteBatch", "store.sql_file_info.permanent_delete_batch.app_error", nil, ""+err.Error(), http.StatusInternalServerError)
result.Data = int64(0) }
} else { return rowsAffected, nil
result.Data = rowsAffected
}
}
})
} }
func (s SqlFileInfoStore) PermanentDeleteByUser(userId string) store.StoreChannel { func (s SqlFileInfoStore) PermanentDeleteByUser(userId string) (int64, *model.AppError) {
return store.Do(func(result *store.StoreResult) { query := "DELETE from FileInfo WHERE CreatorId = :CreatorId"
query := "DELETE from FileInfo WHERE CreatorId = :CreatorId"
sqlResult, err := s.GetMaster().Exec(query, map[string]interface{}{"CreatorId": userId}) sqlResult, err := s.GetMaster().Exec(query, map[string]interface{}{"CreatorId": userId})
if err != nil { if err != nil {
result.Err = model.NewAppError("SqlFileInfoStore.PermanentDeleteByUser", "store.sql_file_info.PermanentDeleteByUser.app_error", nil, ""+err.Error(), http.StatusInternalServerError) return 0, model.NewAppError("SqlFileInfoStore.PermanentDeleteByUser", "store.sql_file_info.PermanentDeleteByUser.app_error", nil, ""+err.Error(), http.StatusInternalServerError)
} else { }
rowsAffected, err1 := sqlResult.RowsAffected()
if err1 != nil { rowsAffected, err1 := sqlResult.RowsAffected()
result.Err = model.NewAppError("SqlFileInfoStore.PermanentDeleteByUser", "store.sql_file_info.PermanentDeleteByUser.app_error", nil, ""+err.Error(), http.StatusInternalServerError) if err1 != nil {
result.Data = int64(0) return 0, model.NewAppError("SqlFileInfoStore.PermanentDeleteByUser", "store.sql_file_info.PermanentDeleteByUser.app_error", nil, ""+err.Error(), http.StatusInternalServerError)
} else { }
result.Data = rowsAffected return rowsAffected, nil
}
}
})
} }

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

@@ -476,17 +476,17 @@ type StatusStore interface {
} }
type FileInfoStore interface { type FileInfoStore interface {
Save(info *model.FileInfo) StoreChannel Save(info *model.FileInfo) (*model.FileInfo, *model.AppError)
Get(id string) StoreChannel Get(id string) (*model.FileInfo, *model.AppError)
GetByPath(path string) StoreChannel GetByPath(path string) (*model.FileInfo, *model.AppError)
GetForPost(postId string, readFromMaster bool, allowFromCache bool) StoreChannel GetForPost(postId string, readFromMaster bool, allowFromCache bool) ([]*model.FileInfo, *model.AppError)
GetForUser(userId string) StoreChannel GetForUser(userId string) ([]*model.FileInfo, *model.AppError)
InvalidateFileInfosForPostCache(postId string) InvalidateFileInfosForPostCache(postId string)
AttachToPost(fileId string, postId string, creatorId string) StoreChannel AttachToPost(fileId string, postId string, creatorId string) *model.AppError
DeleteForPost(postId string) StoreChannel DeleteForPost(postId string) (string, *model.AppError)
PermanentDelete(fileId string) StoreChannel PermanentDelete(fileId string) *model.AppError
PermanentDeleteBatch(endTime int64, limit int64) StoreChannel PermanentDeleteBatch(endTime int64, limit int64) (int64, *model.AppError)
PermanentDeleteByUser(userId string) StoreChannel PermanentDeleteByUser(userId string) (int64, *model.AppError)
ClearCaches() ClearCaches()
} }

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

@@ -32,36 +32,30 @@ func testFileInfoSaveGet(t *testing.T, ss store.Store) {
Path: "file.txt", Path: "file.txt",
} }
if result := <-ss.FileInfo().Save(info); result.Err != nil { info, err := ss.FileInfo().Save(info)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.(*model.FileInfo); len(returned.Id) == 0 { require.NotEqual(t, len(info.Id), 0)
t.Fatal("should've assigned an id to FileInfo")
} else {
info = returned
}
defer func() { defer func() {
<-ss.FileInfo().PermanentDelete(info.Id) ss.FileInfo().PermanentDelete(info.Id)
}() }()
if result := <-ss.FileInfo().Get(info.Id); result.Err != nil { rinfo, err := ss.FileInfo().Get(info.Id)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.(*model.FileInfo); returned.Id != info.Id { require.Equal(t, info.Id, rinfo.Id)
t.Log(info)
t.Log(returned)
t.Fatal("should've returned correct FileInfo")
}
info2 := store.Must(ss.FileInfo().Save(&model.FileInfo{ info2, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(), CreatorId: model.NewId(),
Path: "file.txt", Path: "file.txt",
DeleteAt: 123, DeleteAt: 123,
})).(*model.FileInfo) })
require.Nil(t, err)
_, err = ss.FileInfo().Get(info2.Id)
assert.NotNil(t, err)
if result := <-ss.FileInfo().Get(info2.Id); result.Err == nil {
t.Fatal("shouldn't have gotten deleted file")
}
defer func() { defer func() {
<-ss.FileInfo().PermanentDelete(info2.Id) ss.FileInfo().PermanentDelete(info2.Id)
}() }()
} }
@@ -71,36 +65,29 @@ func testFileInfoSaveGetByPath(t *testing.T, ss store.Store) {
Path: fmt.Sprintf("%v/file.txt", model.NewId()), Path: fmt.Sprintf("%v/file.txt", model.NewId()),
} }
if result := <-ss.FileInfo().Save(info); result.Err != nil { info, err := ss.FileInfo().Save(info)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.(*model.FileInfo); len(returned.Id) == 0 { assert.NotEqual(t, len(info.Id), 0)
t.Fatal("should've assigned an id to FileInfo")
} else {
info = returned
}
defer func() { defer func() {
<-ss.FileInfo().PermanentDelete(info.Id) ss.FileInfo().PermanentDelete(info.Id)
}() }()
if result := <-ss.FileInfo().GetByPath(info.Path); result.Err != nil { rinfo, err := ss.FileInfo().GetByPath(info.Path)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.(*model.FileInfo); returned.Id != info.Id { assert.Equal(t, info.Id, rinfo.Id)
t.Log(info)
t.Log(returned)
t.Fatal("should've returned correct FileInfo")
}
info2 := store.Must(ss.FileInfo().Save(&model.FileInfo{ info2, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(), CreatorId: model.NewId(),
Path: "file.txt", Path: "file.txt",
DeleteAt: 123, DeleteAt: 123,
})).(*model.FileInfo) })
require.Nil(t, err)
_, err = ss.FileInfo().GetByPath(info2.Id)
assert.NotNil(t, err)
if result := <-ss.FileInfo().GetByPath(info2.Id); result.Err == nil {
t.Fatal("shouldn't have gotten deleted file")
}
defer func() { defer func() {
<-ss.FileInfo().PermanentDelete(info2.Id) ss.FileInfo().PermanentDelete(info2.Id)
}() }()
} }
@@ -133,29 +120,25 @@ func testFileInfoGetForPost(t *testing.T, ss store.Store) {
} }
for i, info := range infos { for i, info := range infos {
infos[i] = store.Must(ss.FileInfo().Save(info)).(*model.FileInfo) newInfo, err := ss.FileInfo().Save(info)
require.Nil(t, err)
infos[i] = newInfo
defer func(id string) { defer func(id string) {
<-ss.FileInfo().PermanentDelete(id) ss.FileInfo().PermanentDelete(id)
}(infos[i].Id) }(newInfo.Id)
} }
if result := <-ss.FileInfo().GetForPost(postId, true, false); result.Err != nil { postInfos, err := ss.FileInfo().GetForPost(postId, true, false)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.([]*model.FileInfo); len(returned) != 2 { assert.Len(t, postInfos, 2)
t.Fatal("should've returned exactly 2 file infos")
}
if result := <-ss.FileInfo().GetForPost(postId, false, false); result.Err != nil { postInfos, err = ss.FileInfo().GetForPost(postId, false, false)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.([]*model.FileInfo); len(returned) != 2 { assert.Len(t, postInfos, 2)
t.Fatal("should've returned exactly 2 file infos")
}
if result := <-ss.FileInfo().GetForPost(postId, true, true); result.Err != nil { postInfos, err = ss.FileInfo().GetForPost(postId, true, true)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.([]*model.FileInfo); len(returned) != 2 { assert.Len(t, postInfos, 2)
t.Fatal("should've returned exactly 2 file infos")
}
} }
func testFileInfoGetForUser(t *testing.T, ss store.Store) { func testFileInfoGetForUser(t *testing.T, ss store.Store) {
@@ -187,23 +170,21 @@ func testFileInfoGetForUser(t *testing.T, ss store.Store) {
} }
for i, info := range infos { for i, info := range infos {
infos[i] = store.Must(ss.FileInfo().Save(info)).(*model.FileInfo) newInfo, err := ss.FileInfo().Save(info)
require.Nil(t, err)
infos[i] = newInfo
defer func(id string) { defer func(id string) {
<-ss.FileInfo().PermanentDelete(id) ss.FileInfo().PermanentDelete(id)
}(infos[i].Id) }(newInfo.Id)
} }
if result := <-ss.FileInfo().GetForUser(userId); result.Err != nil { userPosts, err := ss.FileInfo().GetForUser(userId)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.([]*model.FileInfo); len(returned) != 3 { assert.Len(t, userPosts, 3)
t.Fatal("should've returned exactly 3 file infos")
}
if result := <-ss.FileInfo().GetForUser(userId2); result.Err != nil { userPosts, err = ss.FileInfo().GetForUser(userId2)
t.Fatal(result.Err) require.Nil(t, err)
} else if returned := result.Data.([]*model.FileInfo); len(returned) != 1 { assert.Len(t, userPosts, 1)
t.Fatal("should've returned exactly 1 file infos")
}
} }
func testFileInfoAttachToPost(t *testing.T, ss store.Store) { func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
@@ -211,28 +192,28 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
userId := model.NewId() userId := model.NewId()
postId := model.NewId() postId := model.NewId()
info1 := store.Must(ss.FileInfo().Save(&model.FileInfo{ info1, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: userId, CreatorId: userId,
Path: "file.txt", Path: "file.txt",
})).(*model.FileInfo) })
info2 := store.Must(ss.FileInfo().Save(&model.FileInfo{ require.Nil(t, err)
info2, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: userId, CreatorId: userId,
Path: "file2.txt", Path: "file2.txt",
})).(*model.FileInfo) })
require.Nil(t, err)
require.Equal(t, "", info1.PostId) require.Equal(t, "", info1.PostId)
require.Equal(t, "", info2.PostId) require.Equal(t, "", info2.PostId)
result := <-ss.FileInfo().AttachToPost(info1.Id, postId, userId) err = ss.FileInfo().AttachToPost(info1.Id, postId, userId)
assert.Nil(t, result.Err) assert.Nil(t, err)
result = <-ss.FileInfo().AttachToPost(info2.Id, postId, userId) err = ss.FileInfo().AttachToPost(info2.Id, postId, userId)
assert.Nil(t, result.Err) assert.Nil(t, err)
result = <-ss.FileInfo().GetForPost(postId, true, false) data, err := ss.FileInfo().GetForPost(postId, true, false)
assert.Nil(t, result.Err) assert.Nil(t, err)
data := result.Data.([]*model.FileInfo)
assert.Len(t, data, 2) assert.Len(t, data, 2)
assert.True(t, data[0].Id == info1.Id || data[0].Id == info2.Id) assert.True(t, data[0].Id == info1.Id || data[0].Id == info2.Id)
@@ -243,34 +224,35 @@ func testFileInfoAttachToPost(t *testing.T, ss store.Store) {
userId := model.NewId() userId := model.NewId()
postId := model.NewId() postId := model.NewId()
info := store.Must(ss.FileInfo().Save(&model.FileInfo{ info, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: userId, CreatorId: userId,
Path: "file.txt", Path: "file.txt",
})).(*model.FileInfo) })
require.Nil(t, err)
require.Equal(t, "", info.PostId) require.Equal(t, "", info.PostId)
result := <-ss.FileInfo().AttachToPost(info.Id, model.NewId(), userId) err = ss.FileInfo().AttachToPost(info.Id, model.NewId(), userId)
assert.Nil(t, result.Err) assert.Nil(t, err)
result = <-ss.FileInfo().AttachToPost(info.Id, postId, userId) err = ss.FileInfo().AttachToPost(info.Id, postId, userId)
assert.NotNil(t, result.Err) assert.NotNil(t, err)
}) })
t.Run("should not attach files owned from a different user", func(t *testing.T) { t.Run("should not attach files owned from a different user", func(t *testing.T) {
userId := model.NewId() userId := model.NewId()
postId := model.NewId() postId := model.NewId()
info := store.Must(ss.FileInfo().Save(&model.FileInfo{ info, err := ss.FileInfo().Save(&model.FileInfo{
CreatorId: model.NewId(), CreatorId: model.NewId(),
Path: "file.txt", Path: "file.txt",
})).(*model.FileInfo) })
require.Nil(t, err)
require.Equal(t, "", info.PostId) require.Equal(t, "", info.PostId)
result := <-ss.FileInfo().AttachToPost(info.Id, postId, userId) err = ss.FileInfo().AttachToPost(info.Id, postId, userId)
assert.NotNil(t, err)
assert.NotNil(t, result.Err)
}) })
} }
@@ -303,83 +285,84 @@ func testFileInfoDeleteForPost(t *testing.T, ss store.Store) {
} }
for i, info := range infos { for i, info := range infos {
infos[i] = store.Must(ss.FileInfo().Save(info)).(*model.FileInfo) newInfo, err := ss.FileInfo().Save(info)
require.Nil(t, err)
infos[i] = newInfo
defer func(id string) { defer func(id string) {
<-ss.FileInfo().PermanentDelete(id) ss.FileInfo().PermanentDelete(id)
}(infos[i].Id) }(newInfo.Id)
} }
if result := <-ss.FileInfo().DeleteForPost(postId); result.Err != nil { _, err := ss.FileInfo().DeleteForPost(postId)
t.Fatal(result.Err) require.Nil(t, err)
}
if infos := store.Must(ss.FileInfo().GetForPost(postId, true, false)).([]*model.FileInfo); len(infos) != 0 { infos, err = ss.FileInfo().GetForPost(postId, true, false)
t.Fatal("shouldn't have returned any file infos") require.Nil(t, err)
} assert.Len(t, infos, 0)
} }
func testFileInfoPermanentDelete(t *testing.T, ss store.Store) { func testFileInfoPermanentDelete(t *testing.T, ss store.Store) {
info := store.Must(ss.FileInfo().Save(&model.FileInfo{ info, err := ss.FileInfo().Save(&model.FileInfo{
PostId: model.NewId(), PostId: model.NewId(),
CreatorId: model.NewId(), CreatorId: model.NewId(),
Path: "file.txt", Path: "file.txt",
})).(*model.FileInfo) })
require.Nil(t, err)
if result := <-ss.FileInfo().PermanentDelete(info.Id); result.Err != nil { err = ss.FileInfo().PermanentDelete(info.Id)
t.Fatal(result.Err) require.Nil(t, err)
}
} }
func testFileInfoPermanentDeleteBatch(t *testing.T, ss store.Store) { func testFileInfoPermanentDeleteBatch(t *testing.T, ss store.Store) {
postId := model.NewId() postId := model.NewId()
store.Must(ss.FileInfo().Save(&model.FileInfo{ _, err := ss.FileInfo().Save(&model.FileInfo{
PostId: postId, PostId: postId,
CreatorId: model.NewId(), CreatorId: model.NewId(),
Path: "file.txt", Path: "file.txt",
CreateAt: 1000, CreateAt: 1000,
})) })
require.Nil(t, err)
store.Must(ss.FileInfo().Save(&model.FileInfo{ _, err = ss.FileInfo().Save(&model.FileInfo{
PostId: postId, PostId: postId,
CreatorId: model.NewId(), CreatorId: model.NewId(),
Path: "file.txt", Path: "file.txt",
CreateAt: 1200, CreateAt: 1200,
})) })
require.Nil(t, err)
store.Must(ss.FileInfo().Save(&model.FileInfo{ _, err = ss.FileInfo().Save(&model.FileInfo{
PostId: postId, PostId: postId,
CreatorId: model.NewId(), CreatorId: model.NewId(),
Path: "file.txt", Path: "file.txt",
CreateAt: 2000, CreateAt: 2000,
})) })
require.Nil(t, err)
if result := <-ss.FileInfo().GetForPost(postId, true, false); result.Err != nil { postFiles, err := ss.FileInfo().GetForPost(postId, true, false)
t.Fatal(result.Err) require.Nil(t, err)
} else if len(result.Data.([]*model.FileInfo)) != 3 { assert.Len(t, postFiles, 3)
t.Fatal("Expected 3 fileInfos")
}
store.Must(ss.FileInfo().PermanentDeleteBatch(1500, 1000)) _, err = ss.FileInfo().PermanentDeleteBatch(1500, 1000)
require.Nil(t, err)
if result := <-ss.FileInfo().GetForPost(postId, true, false); result.Err != nil { postFiles, err = ss.FileInfo().GetForPost(postId, true, false)
t.Fatal(result.Err) require.Nil(t, err)
} else if len(result.Data.([]*model.FileInfo)) != 1 { assert.Len(t, postFiles, 1)
t.Fatal("Expected 3 fileInfos")
}
} }
func testFileInfoPermanentDeleteByUser(t *testing.T, ss store.Store) { func testFileInfoPermanentDeleteByUser(t *testing.T, ss store.Store) {
userId := model.NewId() userId := model.NewId()
postId := model.NewId() postId := model.NewId()
store.Must(ss.FileInfo().Save(&model.FileInfo{ _, err := ss.FileInfo().Save(&model.FileInfo{
PostId: postId, PostId: postId,
CreatorId: userId, CreatorId: userId,
Path: "file.txt", Path: "file.txt",
})) })
require.Nil(t, err)
if result := <-ss.FileInfo().PermanentDeleteByUser(userId); result.Err != nil { _, err = ss.FileInfo().PermanentDeleteByUser(userId)
t.Fatal(result.Err) require.Nil(t, err)
}
} }

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

@@ -6,7 +6,6 @@ package mocks
import mock "github.com/stretchr/testify/mock" import mock "github.com/stretchr/testify/mock"
import model "github.com/mattermost/mattermost-server/model" import model "github.com/mattermost/mattermost-server/model"
import store "github.com/mattermost/mattermost-server/store"
// FileInfoStore is an autogenerated mock type for the FileInfoStore type // FileInfoStore is an autogenerated mock type for the FileInfoStore type
type FileInfoStore struct { type FileInfoStore struct {
@@ -14,15 +13,15 @@ type FileInfoStore struct {
} }
// AttachToPost provides a mock function with given fields: fileId, postId, creatorId // AttachToPost provides a mock function with given fields: fileId, postId, creatorId
func (_m *FileInfoStore) AttachToPost(fileId string, postId string, creatorId string) store.StoreChannel { func (_m *FileInfoStore) AttachToPost(fileId string, postId string, creatorId string) *model.AppError {
ret := _m.Called(fileId, postId, creatorId) ret := _m.Called(fileId, postId, creatorId)
var r0 store.StoreChannel var r0 *model.AppError
if rf, ok := ret.Get(0).(func(string, string, string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string, string, string) *model.AppError); ok {
r0 = rf(fileId, postId, creatorId) r0 = rf(fileId, postId, creatorId)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(*model.AppError)
} }
} }
@@ -35,83 +34,126 @@ func (_m *FileInfoStore) ClearCaches() {
} }
// DeleteForPost provides a mock function with given fields: postId // DeleteForPost provides a mock function with given fields: postId
func (_m *FileInfoStore) DeleteForPost(postId string) store.StoreChannel { func (_m *FileInfoStore) DeleteForPost(postId string) (string, *model.AppError) {
ret := _m.Called(postId) ret := _m.Called(postId)
var r0 store.StoreChannel var r0 string
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string) string); ok {
r0 = rf(postId) r0 = rf(postId)
} else { } else {
if ret.Get(0) != nil { r0 = ret.Get(0).(string)
r0 = ret.Get(0).(store.StoreChannel) }
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(postId)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
} }
} }
return r0 return r0, r1
} }
// Get provides a mock function with given fields: id // Get provides a mock function with given fields: id
func (_m *FileInfoStore) Get(id string) store.StoreChannel { func (_m *FileInfoStore) Get(id string) (*model.FileInfo, *model.AppError) {
ret := _m.Called(id) ret := _m.Called(id)
var r0 store.StoreChannel var r0 *model.FileInfo
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string) *model.FileInfo); ok {
r0 = rf(id) r0 = rf(id)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(*model.FileInfo)
} }
} }
return r0 var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(id)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
} }
// GetByPath provides a mock function with given fields: path // GetByPath provides a mock function with given fields: path
func (_m *FileInfoStore) GetByPath(path string) store.StoreChannel { func (_m *FileInfoStore) GetByPath(path string) (*model.FileInfo, *model.AppError) {
ret := _m.Called(path) ret := _m.Called(path)
var r0 store.StoreChannel var r0 *model.FileInfo
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string) *model.FileInfo); ok {
r0 = rf(path) r0 = rf(path)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(*model.FileInfo)
} }
} }
return r0 var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(path)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
} }
// GetForPost provides a mock function with given fields: postId, readFromMaster, allowFromCache // GetForPost provides a mock function with given fields: postId, readFromMaster, allowFromCache
func (_m *FileInfoStore) GetForPost(postId string, readFromMaster bool, allowFromCache bool) store.StoreChannel { func (_m *FileInfoStore) GetForPost(postId string, readFromMaster bool, allowFromCache bool) ([]*model.FileInfo, *model.AppError) {
ret := _m.Called(postId, readFromMaster, allowFromCache) ret := _m.Called(postId, readFromMaster, allowFromCache)
var r0 store.StoreChannel var r0 []*model.FileInfo
if rf, ok := ret.Get(0).(func(string, bool, bool) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string, bool, bool) []*model.FileInfo); ok {
r0 = rf(postId, readFromMaster, allowFromCache) r0 = rf(postId, readFromMaster, allowFromCache)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).([]*model.FileInfo)
} }
} }
return r0 var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string, bool, bool) *model.AppError); ok {
r1 = rf(postId, readFromMaster, allowFromCache)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
} }
// GetForUser provides a mock function with given fields: userId // GetForUser provides a mock function with given fields: userId
func (_m *FileInfoStore) GetForUser(userId string) store.StoreChannel { func (_m *FileInfoStore) GetForUser(userId string) ([]*model.FileInfo, *model.AppError) {
ret := _m.Called(userId) ret := _m.Called(userId)
var r0 store.StoreChannel var r0 []*model.FileInfo
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string) []*model.FileInfo); ok {
r0 = rf(userId) r0 = rf(userId)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).([]*model.FileInfo)
} }
} }
return r0 var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(userId)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
} }
// InvalidateFileInfosForPostCache provides a mock function with given fields: postId // InvalidateFileInfosForPostCache provides a mock function with given fields: postId
@@ -120,15 +162,15 @@ func (_m *FileInfoStore) InvalidateFileInfosForPostCache(postId string) {
} }
// PermanentDelete provides a mock function with given fields: fileId // PermanentDelete provides a mock function with given fields: fileId
func (_m *FileInfoStore) PermanentDelete(fileId string) store.StoreChannel { func (_m *FileInfoStore) PermanentDelete(fileId string) *model.AppError {
ret := _m.Called(fileId) ret := _m.Called(fileId)
var r0 store.StoreChannel var r0 *model.AppError
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string) *model.AppError); ok {
r0 = rf(fileId) r0 = rf(fileId)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(*model.AppError)
} }
} }
@@ -136,49 +178,72 @@ func (_m *FileInfoStore) PermanentDelete(fileId string) store.StoreChannel {
} }
// PermanentDeleteBatch provides a mock function with given fields: endTime, limit // PermanentDeleteBatch provides a mock function with given fields: endTime, limit
func (_m *FileInfoStore) PermanentDeleteBatch(endTime int64, limit int64) store.StoreChannel { func (_m *FileInfoStore) PermanentDeleteBatch(endTime int64, limit int64) (int64, *model.AppError) {
ret := _m.Called(endTime, limit) ret := _m.Called(endTime, limit)
var r0 store.StoreChannel var r0 int64
if rf, ok := ret.Get(0).(func(int64, int64) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(int64, int64) int64); ok {
r0 = rf(endTime, limit) r0 = rf(endTime, limit)
} else { } else {
if ret.Get(0) != nil { r0 = ret.Get(0).(int64)
r0 = ret.Get(0).(store.StoreChannel) }
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(int64, int64) *model.AppError); ok {
r1 = rf(endTime, limit)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
} }
} }
return r0 return r0, r1
} }
// PermanentDeleteByUser provides a mock function with given fields: userId // PermanentDeleteByUser provides a mock function with given fields: userId
func (_m *FileInfoStore) PermanentDeleteByUser(userId string) store.StoreChannel { func (_m *FileInfoStore) PermanentDeleteByUser(userId string) (int64, *model.AppError) {
ret := _m.Called(userId) ret := _m.Called(userId)
var r0 store.StoreChannel var r0 int64
if rf, ok := ret.Get(0).(func(string) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(string) int64); ok {
r0 = rf(userId) r0 = rf(userId)
} else { } else {
if ret.Get(0) != nil { r0 = ret.Get(0).(int64)
r0 = ret.Get(0).(store.StoreChannel) }
var r1 *model.AppError
if rf, ok := ret.Get(1).(func(string) *model.AppError); ok {
r1 = rf(userId)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
} }
} }
return r0 return r0, r1
} }
// Save provides a mock function with given fields: info // Save provides a mock function with given fields: info
func (_m *FileInfoStore) Save(info *model.FileInfo) store.StoreChannel { func (_m *FileInfoStore) Save(info *model.FileInfo) (*model.FileInfo, *model.AppError) {
ret := _m.Called(info) ret := _m.Called(info)
var r0 store.StoreChannel var r0 *model.FileInfo
if rf, ok := ret.Get(0).(func(*model.FileInfo) store.StoreChannel); ok { if rf, ok := ret.Get(0).(func(*model.FileInfo) *model.FileInfo); ok {
r0 = rf(info) r0 = rf(info)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(store.StoreChannel) r0 = ret.Get(0).(*model.FileInfo)
} }
} }
return r0 var r1 *model.AppError
if rf, ok := ret.Get(1).(func(*model.FileInfo) *model.AppError); ok {
r1 = rf(info)
} else {
if ret.Get(1) != nil {
r1 = ret.Get(1).(*model.AppError)
}
}
return r0, r1
} }