github.com/haalcala/mattermost-server-change-repo@v0.0.0-20210713015153-16753fbeee5f/store/searchlayer/file_info_layer.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package searchlayer 5 6 import ( 7 "github.com/mattermost/mattermost-server/v5/mlog" 8 "github.com/mattermost/mattermost-server/v5/model" 9 "github.com/mattermost/mattermost-server/v5/services/searchengine" 10 "github.com/mattermost/mattermost-server/v5/store" 11 ) 12 13 type SearchFileInfoStore struct { 14 store.FileInfoStore 15 rootStore *SearchStore 16 } 17 18 func (s SearchFileInfoStore) indexFile(file *model.FileInfo) { 19 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 20 if engine.IsIndexingEnabled() { 21 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 22 if file.PostId == "" { 23 return 24 } 25 post, postErr := s.rootStore.Post().GetSingle(file.PostId) 26 if postErr != nil { 27 mlog.Error("Couldn't get post for file for SearchEngine indexing.", mlog.String("post_id", file.PostId), mlog.String("search_engine", engineCopy.GetName()), mlog.String("file_info_id", file.Id), mlog.Err(postErr)) 28 return 29 } 30 31 if err := engineCopy.IndexFile(file, post.ChannelId); err != nil { 32 mlog.Error("Encountered error indexing file", mlog.String("file_info_id", file.Id), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 33 return 34 } 35 mlog.Debug("Indexed file in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("file_info_id", file.Id)) 36 }) 37 } 38 } 39 } 40 41 func (s SearchFileInfoStore) deleteFileIndex(fileID string) { 42 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 43 if engine.IsIndexingEnabled() { 44 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 45 if err := engineCopy.DeleteFile(fileID); err != nil { 46 mlog.Error("Encountered error deleting file", mlog.String("file_info_id", fileID), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 47 return 48 } 49 mlog.Debug("Removed file from the index in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("file_info_id", fileID)) 50 }) 51 } 52 } 53 } 54 55 func (s SearchFileInfoStore) deleteFileIndexForUser(userID string) { 56 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 57 if engine.IsIndexingEnabled() { 58 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 59 if err := engineCopy.DeleteUserFiles(userID); err != nil { 60 mlog.Error("Encountered error deleting files for user", mlog.String("user_id", userID), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 61 return 62 } 63 mlog.Debug("Removed user's files from the index in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("user_id", userID)) 64 }) 65 } 66 } 67 } 68 69 func (s SearchFileInfoStore) deleteFileIndexForPost(postID string) { 70 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 71 if engine.IsIndexingEnabled() { 72 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 73 if err := engineCopy.DeletePostFiles(postID); err != nil { 74 mlog.Error("Encountered error deleting files for post", mlog.String("post_id", postID), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 75 return 76 } 77 mlog.Debug("Removed post's files from the index in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("post_id", postID)) 78 }) 79 } 80 } 81 } 82 83 func (s SearchFileInfoStore) deleteFileIndexBatch(endTime, limit int64) { 84 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 85 if engine.IsIndexingEnabled() { 86 runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) { 87 if err := engineCopy.DeleteFilesBatch(endTime, limit); err != nil { 88 mlog.Error("Encountered error deleting a batch of files", mlog.Int64("limit", limit), mlog.Int64("end_time", endTime), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err)) 89 return 90 } 91 mlog.Debug("Removed batch of files from the index in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.Int64("end_time", endTime), mlog.Int64("limit", limit)) 92 }) 93 } 94 } 95 } 96 97 func (s SearchFileInfoStore) Save(info *model.FileInfo) (*model.FileInfo, error) { 98 nfile, err := s.FileInfoStore.Save(info) 99 if err == nil { 100 s.indexFile(nfile) 101 } 102 return nfile, err 103 } 104 105 func (s SearchFileInfoStore) SetContent(fileID, content string) error { 106 err := s.FileInfoStore.SetContent(fileID, content) 107 if err == nil { 108 nfile, err2 := s.FileInfoStore.Get(fileID) 109 if err2 == nil { 110 nfile.Content = content 111 s.indexFile(nfile) 112 } 113 } 114 return err 115 } 116 117 func (s SearchFileInfoStore) AttachToPost(fileId, postId, creatorId string) error { 118 err := s.FileInfoStore.AttachToPost(fileId, postId, creatorId) 119 if err == nil { 120 nFileInfo, err2 := s.FileInfoStore.Get(fileId) 121 if err2 == nil { 122 s.indexFile(nFileInfo) 123 } 124 } 125 return err 126 } 127 128 func (s SearchFileInfoStore) DeleteForPost(postId string) (string, error) { 129 result, err := s.FileInfoStore.DeleteForPost(postId) 130 if err == nil { 131 s.deleteFileIndexForPost(postId) 132 } 133 return result, err 134 } 135 136 func (s SearchFileInfoStore) PermanentDelete(fileId string) error { 137 err := s.FileInfoStore.PermanentDelete(fileId) 138 if err == nil { 139 s.deleteFileIndex(fileId) 140 } 141 return err 142 } 143 144 func (s SearchFileInfoStore) PermanentDeleteBatch(endTime int64, limit int64) (int64, error) { 145 result, err := s.FileInfoStore.PermanentDeleteBatch(endTime, limit) 146 if err == nil { 147 s.deleteFileIndexBatch(endTime, limit) 148 } 149 return result, err 150 } 151 152 func (s SearchFileInfoStore) PermanentDeleteByUser(userId string) (int64, error) { 153 result, err := s.FileInfoStore.PermanentDeleteByUser(userId) 154 if err == nil { 155 s.deleteFileIndexForUser(userId) 156 } 157 return result, err 158 } 159 160 func (s SearchFileInfoStore) Search(paramsList []*model.SearchParams, userId, teamId string, page, perPage int) (*model.FileInfoList, error) { 161 for _, engine := range s.rootStore.searchEngine.GetActiveEngines() { 162 if engine.IsSearchEnabled() { 163 userChannels, nErr := s.rootStore.Channel().GetChannels(teamId, userId, paramsList[0].IncludeDeletedChannels, 0) 164 if nErr != nil { 165 return nil, nErr 166 } 167 fileIds, appErr := engine.SearchFiles(userChannels, paramsList, page, perPage) 168 if appErr != nil { 169 mlog.Error("Encountered error on Search.", mlog.String("search_engine", engine.GetName()), mlog.Err(appErr)) 170 continue 171 } 172 mlog.Debug("Using the first available search engine", mlog.String("search_engine", engine.GetName())) 173 174 // Get the files 175 filesList := model.NewFileInfoList() 176 if len(fileIds) > 0 { 177 files, nErr := s.FileInfoStore.GetByIds(fileIds) 178 if nErr != nil { 179 return nil, nErr 180 } 181 for _, f := range files { 182 filesList.AddFileInfo(f) 183 filesList.AddOrder(f.Id) 184 } 185 } 186 return filesList, nil 187 } 188 } 189 190 if *s.rootStore.getConfig().SqlSettings.DisableDatabaseSearch { 191 mlog.Debug("Returning empty results for file Search as the database search is disabled") 192 return model.NewFileInfoList(), nil 193 } 194 195 mlog.Debug("Using database search because no other search engine is available") 196 return s.FileInfoStore.Search(paramsList, userId, teamId, page, perPage) 197 }