github.com/haalcala/mattermost-server-change-repo/v5@v5.33.2/store/searchlayer/post_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/pkg/errors"
     8  
     9  	"github.com/mattermost/mattermost-server/v5/mlog"
    10  	"github.com/mattermost/mattermost-server/v5/model"
    11  	"github.com/mattermost/mattermost-server/v5/services/searchengine"
    12  	"github.com/mattermost/mattermost-server/v5/store"
    13  )
    14  
    15  type SearchPostStore struct {
    16  	store.PostStore
    17  	rootStore *SearchStore
    18  }
    19  
    20  func (s SearchPostStore) indexPost(post *model.Post) {
    21  	for _, engine := range s.rootStore.searchEngine.GetActiveEngines() {
    22  		if engine.IsIndexingEnabled() {
    23  			runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) {
    24  				channel, chanErr := s.rootStore.Channel().Get(post.ChannelId, true)
    25  				if chanErr != nil {
    26  					mlog.Error("Couldn't get channel for post for SearchEngine indexing.", mlog.String("channel_id", post.ChannelId), mlog.String("search_engine", engineCopy.GetName()), mlog.String("post_id", post.Id), mlog.Err(chanErr))
    27  					return
    28  				}
    29  				if err := engineCopy.IndexPost(post, channel.TeamId); err != nil {
    30  					mlog.Warn("Encountered error indexing post", mlog.String("post_id", post.Id), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err))
    31  					return
    32  				}
    33  				mlog.Debug("Indexed post in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("post_id", post.Id))
    34  			})
    35  		}
    36  	}
    37  }
    38  
    39  func (s SearchPostStore) deletePostIndex(post *model.Post) {
    40  	for _, engine := range s.rootStore.searchEngine.GetActiveEngines() {
    41  		if engine.IsIndexingEnabled() {
    42  			runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) {
    43  				if err := engineCopy.DeletePost(post); err != nil {
    44  					mlog.Warn("Encountered error deleting post", mlog.String("post_id", post.Id), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err))
    45  					return
    46  				}
    47  				mlog.Debug("Removed post from the index in search engine", mlog.String("search_engine", engineCopy.GetName()), mlog.String("post_id", post.Id))
    48  			})
    49  		}
    50  	}
    51  }
    52  
    53  func (s SearchPostStore) deleteChannelPostsIndex(channelID string) {
    54  	for _, engine := range s.rootStore.searchEngine.GetActiveEngines() {
    55  		if engine.IsIndexingEnabled() {
    56  			runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) {
    57  				if err := engineCopy.DeleteChannelPosts(channelID); err != nil {
    58  					mlog.Warn("Encountered error deleting channel posts", mlog.String("channel_id", channelID), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err))
    59  					return
    60  				}
    61  				mlog.Debug("Removed all channel posts from the index in search engine", mlog.String("channel_id", channelID), mlog.String("search_engine", engineCopy.GetName()))
    62  			})
    63  		}
    64  	}
    65  }
    66  
    67  func (s SearchPostStore) deleteUserPostsIndex(userID string) {
    68  	for _, engine := range s.rootStore.searchEngine.GetActiveEngines() {
    69  		if engine.IsIndexingEnabled() {
    70  			runIndexFn(engine, func(engineCopy searchengine.SearchEngineInterface) {
    71  				if err := engineCopy.DeleteUserPosts(userID); err != nil {
    72  					mlog.Warn("Encountered error deleting user posts", mlog.String("user_id", userID), mlog.String("search_engine", engineCopy.GetName()), mlog.Err(err))
    73  					return
    74  				}
    75  				mlog.Debug("Removed all user posts from the index in search engine", mlog.String("user_id", userID), mlog.String("search_engine", engineCopy.GetName()))
    76  			})
    77  		}
    78  	}
    79  }
    80  
    81  func (s SearchPostStore) Update(newPost, oldPost *model.Post) (*model.Post, error) {
    82  	post, err := s.PostStore.Update(newPost, oldPost)
    83  
    84  	if err == nil {
    85  		s.indexPost(post)
    86  	}
    87  	return post, err
    88  }
    89  
    90  func (s *SearchPostStore) Overwrite(post *model.Post) (*model.Post, error) {
    91  	post, err := s.PostStore.Overwrite(post)
    92  	if err == nil {
    93  		s.indexPost(post)
    94  	}
    95  	return post, err
    96  }
    97  
    98  func (s SearchPostStore) Save(post *model.Post) (*model.Post, error) {
    99  	npost, err := s.PostStore.Save(post)
   100  
   101  	if err == nil {
   102  		s.indexPost(npost)
   103  	}
   104  	return npost, err
   105  }
   106  
   107  func (s SearchPostStore) Delete(postId string, date int64, deletedByID string) error {
   108  	err := s.PostStore.Delete(postId, date, deletedByID)
   109  
   110  	if err == nil {
   111  		postList, err2 := s.PostStore.Get(postId, true, false, false)
   112  		if postList != nil && len(postList.Order) > 0 {
   113  			if err2 != nil {
   114  				s.deletePostIndex(postList.Posts[postList.Order[0]])
   115  			}
   116  		}
   117  	}
   118  	return err
   119  }
   120  
   121  func (s SearchPostStore) PermanentDeleteByUser(userID string) error {
   122  	err := s.PostStore.PermanentDeleteByUser(userID)
   123  	if err == nil {
   124  		s.deleteUserPostsIndex(userID)
   125  	}
   126  	return err
   127  }
   128  
   129  func (s SearchPostStore) PermanentDeleteByChannel(channelID string) error {
   130  	err := s.PostStore.PermanentDeleteByChannel(channelID)
   131  	if err == nil {
   132  		s.deleteChannelPostsIndex(channelID)
   133  	}
   134  	return err
   135  }
   136  
   137  func (s SearchPostStore) searchPostsInTeamForUserByEngine(engine searchengine.SearchEngineInterface, paramsList []*model.SearchParams, userId, teamId string, page, perPage int) (*model.PostSearchResults, error) {
   138  	if err := model.IsSearchParamsListValid(paramsList); err != nil {
   139  		return nil, err
   140  	}
   141  
   142  	// We only allow the user to search in channels they are a member of.
   143  	userChannels, err2 := s.rootStore.Channel().GetChannels(teamId, userId, paramsList[0].IncludeDeletedChannels, 0)
   144  	if err2 != nil {
   145  		return nil, errors.Wrap(err2, "error getting channel for user")
   146  	}
   147  
   148  	postIds, matches, err := engine.SearchPosts(userChannels, paramsList, page, perPage)
   149  	if err != nil {
   150  		return nil, err
   151  	}
   152  
   153  	// Get the posts
   154  	postList := model.NewPostList()
   155  	if len(postIds) > 0 {
   156  		posts, err := s.PostStore.GetPostsByIds(postIds)
   157  		if err != nil {
   158  			return nil, err
   159  		}
   160  		for _, p := range posts {
   161  			if p.DeleteAt == 0 {
   162  				postList.AddPost(p)
   163  				postList.AddOrder(p.Id)
   164  			}
   165  		}
   166  	}
   167  
   168  	return model.MakePostSearchResults(postList, matches), nil
   169  }
   170  
   171  func (s SearchPostStore) SearchPostsInTeamForUser(paramsList []*model.SearchParams, userId, teamId string, page, perPage int) (*model.PostSearchResults, error) {
   172  	for _, engine := range s.rootStore.searchEngine.GetActiveEngines() {
   173  		if engine.IsSearchEnabled() {
   174  			results, err := s.searchPostsInTeamForUserByEngine(engine, paramsList, userId, teamId, page, perPage)
   175  			if err != nil {
   176  				mlog.Warn("Encountered error on SearchPostsInTeamForUser.", mlog.String("search_engine", engine.GetName()), mlog.Err(err))
   177  				continue
   178  			}
   179  			mlog.Debug("Using the first available search engine", mlog.String("search_engine", engine.GetName()))
   180  			return results, err
   181  		}
   182  	}
   183  
   184  	if *s.rootStore.getConfig().SqlSettings.DisableDatabaseSearch {
   185  		mlog.Debug("Returning empty results for post SearchPostsInTeam as the database search is disabled")
   186  		return &model.PostSearchResults{PostList: model.NewPostList(), Matches: model.PostSearchMatches{}}, nil
   187  	}
   188  
   189  	mlog.Debug("Using database search because no other search engine is available")
   190  	return s.PostStore.SearchPostsInTeamForUser(paramsList, userId, teamId, page, perPage)
   191  }