MM-38164: Paginate the GetPostThread API (#19485)

We implement a cursor based pagination model
to page through the posts in a given thread.

The cursor is a combination of the post.CreateAt+
post.Id to differentiate multiple posts in a given
timestamp.

Some additional parameters like direction, fromPost,
fromCreateAt and perPage were introduced to implement
this.

```release-note
NONE
```
Этот коммит содержится в:
Agniva De Sarker
2022-03-24 12:51:41 +05:30
коммит произвёл GitHub
родитель ad5f57b161
Коммит c1f3827801
24 изменённых файлов: 470 добавлений и 112 удалений

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

@@ -674,7 +674,7 @@ type AppIface interface {
GetPostIdAfterTime(channelID string, time int64, collapsedThreads bool) (string, *model.AppError)
GetPostIdBeforeTime(channelID string, time int64, collapsedThreads bool) (string, *model.AppError)
GetPostIfAuthorized(postID string, session *model.Session) (*model.Post, *model.AppError)
GetPostThread(postID string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool, userID string) (*model.PostList, *model.AppError)
GetPostThread(postID string, opts model.GetPostsOptions, userID string) (*model.PostList, *model.AppError)
GetPosts(channelID string, offset int, limit int) (*model.PostList, *model.AppError)
GetPostsAfterPost(options model.GetPostsOptions) (*model.PostList, *model.AppError)
GetPostsAroundPost(before bool, options model.GetPostsOptions) (*model.PostList, *model.AppError)

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

@@ -2084,7 +2084,7 @@ func TestMarkChannelAsUnreadFromPostPanic(t *testing.T) {
mockPostStore := mocks.PostStore{}
mockPostStore.On("GetMaxPostSize").Return(65535, nil)
mockPostStore.On("Get", context.Background(), "postID", false, false, false, "userID").Return(&model.PostList{}, nil)
mockPostStore.On("Get", context.Background(), "postID", model.GetPostsOptions{}, "userID").Return(&model.PostList{}, nil)
mockPostStore.On("GetPostsAfter", mock.AnythingOfType("model.GetPostsOptions")).Return(&model.PostList{}, nil)
mockPostStore.On("GetSingle", "postID", false).Return(&model.Post{
Id: "postID",

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

@@ -367,7 +367,7 @@ func (a *App) MigrateFilenamesToFileInfos(post *model.Post) []*model.FileInfo {
fileMigrationLock.Lock()
defer fileMigrationLock.Unlock()
result, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, false, false, false, "")
result, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, model.GetPostsOptions{}, "")
if nErr != nil {
mlog.Error("Unable to get post when migrating post to use FileInfos", mlog.Err(nErr), mlog.String("post_id", post.Id))
return []*model.FileInfo{}

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

@@ -7639,7 +7639,7 @@ func (a *OpenTracingAppLayer) GetPostIfAuthorized(postID string, session *model.
return resultVar0, resultVar1
}
func (a *OpenTracingAppLayer) GetPostThread(postID string, skipFetchThreads bool, collapsedThreads bool, collapsedThreadsExtended bool, userID string) (*model.PostList, *model.AppError) {
func (a *OpenTracingAppLayer) GetPostThread(postID string, opts model.GetPostsOptions, userID string) (*model.PostList, *model.AppError) {
origCtx := a.ctx
span, newCtx := tracing.StartSpanWithParentByContext(a.ctx, "app.GetPostThread")
@@ -7651,7 +7651,7 @@ func (a *OpenTracingAppLayer) GetPostThread(postID string, skipFetchThreads bool
}()
defer span.Finish()
resultVar0, resultVar1 := a.app.GetPostThread(postID, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID)
resultVar0, resultVar1 := a.app.GetPostThread(postID, opts, userID)
if resultVar1 != nil {
span.LogFields(spanlog.Error(resultVar1))

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

@@ -661,7 +661,7 @@ func (api *PluginAPI) DeletePost(postID string) *model.AppError {
}
func (api *PluginAPI) GetPostThread(postID string) (*model.PostList, *model.AppError) {
return api.app.GetPostThread(postID, false, false, false, "")
return api.app.GetPostThread(postID, model.GetPostsOptions{}, "")
}
func (api *PluginAPI) GetPost(postID string) (*model.Post, *model.AppError) {

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

@@ -168,7 +168,7 @@ func (a *App) CreatePost(c *request.Context, post *model.Post, channel *model.Ch
if post.RootId != "" {
pchan = make(chan store.StoreResult, 1)
go func() {
r, pErr := a.Srv().Store.Post().Get(sqlstore.WithMaster(context.Background()), post.RootId, false, false, false, "")
r, pErr := a.Srv().Store.Post().Get(sqlstore.WithMaster(context.Background()), post.RootId, model.GetPostsOptions{}, "")
pchan <- store.StoreResult{Data: r, NErr: pErr}
close(pchan)
}()
@@ -559,7 +559,7 @@ func (a *App) DeleteEphemeralPost(userID, postID string) {
func (a *App) UpdatePost(c *request.Context, post *model.Post, safeUpdate bool) (*model.Post, *model.AppError) {
post.SanitizeProps()
postLists, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, false, false, false, "")
postLists, nErr := a.Srv().Store.Post().Get(context.Background(), post.Id, model.GetPostsOptions{}, "")
if nErr != nil {
var nfErr *store.ErrNotFound
var invErr *store.ErrInvalidInput
@@ -841,8 +841,8 @@ func (a *App) GetSinglePost(postID string) (*model.Post, *model.AppError) {
return post, nil
}
func (a *App) GetPostThread(postID string, skipFetchThreads, collapsedThreads, collapsedThreadsExtended bool, userID string) (*model.PostList, *model.AppError) {
posts, err := a.Srv().Store.Post().Get(context.Background(), postID, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID)
func (a *App) GetPostThread(postID string, opts model.GetPostsOptions, userID string) (*model.PostList, *model.AppError) {
posts, err := a.Srv().Store.Post().Get(context.Background(), postID, opts, userID)
if err != nil {
var nfErr *store.ErrNotFound
var invErr *store.ErrInvalidInput
@@ -887,7 +887,7 @@ func (a *App) GetFlaggedPostsForChannel(userID, channelID string, offset int, li
}
func (a *App) GetPermalinkPost(c *request.Context, postID string, userID string) (*model.PostList, *model.AppError) {
list, nErr := a.Srv().Store.Post().Get(context.Background(), postID, false, false, false, userID)
list, nErr := a.Srv().Store.Post().Get(context.Background(), postID, model.GetPostsOptions{}, userID)
if nErr != nil {
var nfErr *store.ErrNotFound
var invErr *store.ErrInvalidInput
@@ -1086,7 +1086,12 @@ func (a *App) GetPostsForChannelAroundLastUnread(channelID, userID string, limit
return model.NewPostList(), nil
}
postList, err := a.GetPostThread(lastUnreadPostId, skipFetchThreads, collapsedThreads, collapsedThreadsExtended, userID)
opts := model.GetPostsOptions{
SkipFetchThreads: skipFetchThreads,
CollapsedThreads: collapsedThreads,
CollapsedThreadsExtended: collapsedThreadsExtended,
}
postList, err := a.GetPostThread(lastUnreadPostId, opts, userID)
if err != nil {
return nil, err
}
@@ -1533,7 +1538,7 @@ func (a *App) countMentionsFromPost(user *model.User, post *model.Post) (int, in
// A mapping of thread root IDs to whether or not a post in that thread mentions the user
mentionedByThread := make(map[string]bool)
thread, err := a.GetPostThread(post.Id, false, false, false, user.Id)
thread, err := a.GetPostThread(post.Id, model.GetPostsOptions{}, user.Id)
if err != nil {
return 0, 0, err
}

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

@@ -57,6 +57,7 @@ func (a *App) PreparePostListForClient(originalList *model.PostList) *model.Post
Order: originalList.Order,
NextPostId: originalList.NextPostId,
PrevPostId: originalList.PrevPostId,
HasNext: originalList.HasNext,
}
for id, originalPost := range originalList.Posts {