Improve pagination
Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
parent
7d53ce79b7
commit
9adb872985
3 changed files with 95 additions and 9 deletions
|
|
@ -254,10 +254,24 @@ func (s *sqlDatabase) SearchFileObjectByTags(ctx context.Context, tags []string,
|
|||
ret[idx] = s.sqlFileObjectToCommonParams(val)
|
||||
}
|
||||
|
||||
// Calculate next and previous page numbers
|
||||
var nextPage, previousPage *uint64
|
||||
if page < totalPages {
|
||||
next := page + 1
|
||||
nextPage = &next
|
||||
}
|
||||
if page > 1 {
|
||||
prev := page - 1
|
||||
previousPage = &prev
|
||||
}
|
||||
|
||||
return params.FileObjectPaginatedResponse{
|
||||
Pages: totalPages,
|
||||
CurrentPage: page,
|
||||
Results: ret,
|
||||
TotalCount: uint64(total),
|
||||
Pages: totalPages,
|
||||
CurrentPage: page,
|
||||
NextPage: nextPage,
|
||||
PreviousPage: previousPage,
|
||||
Results: ret,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -345,10 +359,24 @@ func (s *sqlDatabase) ListFileObjects(ctx context.Context, page, pageSize uint64
|
|||
results[i] = s.sqlFileObjectToCommonParams(obj)
|
||||
}
|
||||
|
||||
// Calculate next and previous page numbers
|
||||
var nextPage, previousPage *uint64
|
||||
if page < totalPages {
|
||||
next := page + 1
|
||||
nextPage = &next
|
||||
}
|
||||
if page > 1 {
|
||||
prev := page - 1
|
||||
previousPage = &prev
|
||||
}
|
||||
|
||||
return params.FileObjectPaginatedResponse{
|
||||
Pages: totalPages,
|
||||
CurrentPage: page,
|
||||
Results: results,
|
||||
TotalCount: uint64(total),
|
||||
Pages: totalPages,
|
||||
CurrentPage: page,
|
||||
NextPage: nextPage,
|
||||
PreviousPage: previousPage,
|
||||
Results: results,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -166,6 +166,16 @@ func (s *FileStoreTestSuite) TestListFileObjects() {
|
|||
s.Require().GreaterOrEqual(len(result.Results), len(s.Fixtures.FileObjects))
|
||||
s.Require().Equal(uint64(1), result.CurrentPage)
|
||||
s.Require().GreaterOrEqual(result.Pages, uint64(1))
|
||||
s.Require().GreaterOrEqual(result.TotalCount, uint64(len(s.Fixtures.FileObjects)))
|
||||
|
||||
// First page should not have previous page
|
||||
s.Require().Nil(result.PreviousPage)
|
||||
|
||||
// If there are more pages, next page should be set
|
||||
if result.Pages > 1 {
|
||||
s.Require().NotNil(result.NextPage)
|
||||
s.Require().Equal(uint64(2), *result.NextPage)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *FileStoreTestSuite) TestListFileObjectsPagination() {
|
||||
|
|
@ -181,6 +191,10 @@ func (s *FileStoreTestSuite) TestListFileObjectsPagination() {
|
|||
s.Require().Nil(err)
|
||||
s.Require().Equal(2, len(page1.Results))
|
||||
s.Require().Equal(uint64(1), page1.CurrentPage)
|
||||
s.Require().GreaterOrEqual(page1.TotalCount, uint64(5))
|
||||
s.Require().Nil(page1.PreviousPage, "First page should not have previous page")
|
||||
s.Require().NotNil(page1.NextPage, "First page should have next page")
|
||||
s.Require().Equal(uint64(2), *page1.NextPage)
|
||||
|
||||
// Test second page
|
||||
page2, err := s.Store.ListFileObjects(s.ctx, 2, 2)
|
||||
|
|
@ -188,6 +202,11 @@ func (s *FileStoreTestSuite) TestListFileObjectsPagination() {
|
|||
s.Require().Equal(2, len(page2.Results))
|
||||
s.Require().Equal(uint64(2), page2.CurrentPage)
|
||||
s.Require().Equal(page1.Pages, page2.Pages)
|
||||
s.Require().Equal(page1.TotalCount, page2.TotalCount)
|
||||
s.Require().NotNil(page2.PreviousPage, "Second page should have previous page")
|
||||
s.Require().Equal(uint64(1), *page2.PreviousPage)
|
||||
s.Require().NotNil(page2.NextPage, "Second page should have next page")
|
||||
s.Require().Equal(uint64(3), *page2.NextPage)
|
||||
|
||||
// Verify different results on different pages
|
||||
if len(page1.Results) > 0 && len(page2.Results) > 0 {
|
||||
|
|
@ -591,6 +610,42 @@ func (s *FileStoreTestSuite) TestSearchFileObjectByTagsOrderByCreatedAt() {
|
|||
s.Require().Less(file2Idx, file1Idx, "Newer file (file2) should appear before older file (file1)")
|
||||
}
|
||||
|
||||
func (s *FileStoreTestSuite) TestPaginationFieldsLastPage() {
|
||||
// Create exactly 5 files
|
||||
for i := 0; i < 5; i++ {
|
||||
content := []byte(fmt.Sprintf("Last page test %d", i))
|
||||
_, err := s.Store.CreateFileObject(s.ctx, fmt.Sprintf("last-page-test-%d.txt", i), int64(len(content)), []string{"last-page"}, bytes.NewReader(content))
|
||||
s.Require().Nil(err)
|
||||
}
|
||||
|
||||
// Get the last page (should have 1 item with pageSize=2)
|
||||
// Total: 5 items, pageSize: 2, so pages: 3 (2, 2, 1)
|
||||
lastPage, err := s.Store.SearchFileObjectByTags(s.ctx, []string{"last-page"}, 3, 2)
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(uint64(3), lastPage.CurrentPage)
|
||||
s.Require().Equal(uint64(3), lastPage.Pages)
|
||||
s.Require().Equal(uint64(5), lastPage.TotalCount)
|
||||
s.Require().Equal(1, len(lastPage.Results), "Last page should have 1 item")
|
||||
s.Require().NotNil(lastPage.PreviousPage, "Last page should have previous page")
|
||||
s.Require().Equal(uint64(2), *lastPage.PreviousPage)
|
||||
s.Require().Nil(lastPage.NextPage, "Last page should not have next page")
|
||||
}
|
||||
|
||||
func (s *FileStoreTestSuite) TestPaginationFieldsSinglePage() {
|
||||
// Test when all results fit in a single page
|
||||
content := []byte("Single page test")
|
||||
_, err := s.Store.CreateFileObject(s.ctx, "single-page-test.txt", int64(len(content)), []string{"single-page-unique-tag"}, bytes.NewReader(content))
|
||||
s.Require().Nil(err)
|
||||
|
||||
result, err := s.Store.SearchFileObjectByTags(s.ctx, []string{"single-page-unique-tag"}, 1, 20)
|
||||
s.Require().Nil(err)
|
||||
s.Require().Equal(uint64(1), result.TotalCount)
|
||||
s.Require().Equal(uint64(1), result.Pages)
|
||||
s.Require().Equal(uint64(1), result.CurrentPage)
|
||||
s.Require().Nil(result.PreviousPage, "Single page should not have previous")
|
||||
s.Require().Nil(result.NextPage, "Single page should not have next")
|
||||
}
|
||||
|
||||
func TestFileStoreTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(FileStoreTestSuite))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1320,9 +1320,12 @@ type FileObject struct {
|
|||
}
|
||||
|
||||
type PaginatedResponse[T any] struct {
|
||||
Pages uint64 `json:"pages"`
|
||||
CurrentPage uint64 `json:"current_page"`
|
||||
Results []T `json:"results"`
|
||||
TotalCount uint64 `json:"total_count"`
|
||||
Pages uint64 `json:"pages"`
|
||||
CurrentPage uint64 `json:"current_page"`
|
||||
NextPage *uint64 `json:"next_page,omitempty"`
|
||||
PreviousPage *uint64 `json:"previous_page,omitempty"`
|
||||
Results []T `json:"results"`
|
||||
}
|
||||
|
||||
// swagger:model FileObjectPaginatedResponse
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue