Skip to content

Commit 681fa0d

Browse files
committed
feat(collections): add pagination to collections
1 parent 2974b47 commit 681fa0d

File tree

5 files changed

+123
-27
lines changed

5 files changed

+123
-27
lines changed

db/queries/collections.sql

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
-- name: CreateCollection :one
22
INSERT INTO collections (name) VALUES (?) RETURNING *;
33

4-
-- name: GetAllCollections :many
5-
SELECT * FROM collections;
4+
-- name: GetCollectionsPaginated :many
5+
SELECT * FROM collections
6+
ORDER BY created_at DESC
7+
LIMIT ? OFFSET ?;
8+
9+
-- name: CountCollections :one
10+
SELECT COUNT(*) FROM collections;
611

712
-- name: UpdateCollectionName :one
813
UPDATE collections

internal/collections/manager.go

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,29 @@ func (c *CollectionsManager) Delete(ctx context.Context, id int64) error {
9696
}
9797

9898
func (c *CollectionsManager) List(ctx context.Context) ([]CollectionEntity, error) {
99-
log.Debug("listing all collections")
100-
collections, err := c.DB.GetAllCollections(ctx)
99+
log.Debug("listing all collections with default pagination")
100+
paginated, err := c.ListPaginated(ctx, 50, 0)
101101
if err != nil {
102-
log.Error("failed to list collections", "error", err)
102+
return nil, err
103+
}
104+
return paginated.Collections, nil
105+
}
106+
107+
func (c *CollectionsManager) ListPaginated(ctx context.Context, limit, offset int64) (*PaginatedCollections, error) {
108+
log.Debug("listing paginated collections", "limit", limit, "offset", offset)
109+
110+
total, err := c.DB.CountCollections(ctx)
111+
if err != nil {
112+
log.Error("failed to count collections", "error", err)
113+
return nil, err
114+
}
115+
116+
collections, err := c.DB.GetCollectionsPaginated(ctx, database.GetCollectionsPaginatedParams{
117+
Limit: limit,
118+
Offset: offset,
119+
})
120+
if err != nil {
121+
log.Error("failed to get paginated collections", "limit", limit, "offset", offset, "error", err)
103122
return nil, err
104123
}
105124

@@ -108,6 +127,17 @@ func (c *CollectionsManager) List(ctx context.Context) ([]CollectionEntity, erro
108127
entities[i] = CollectionEntity{Collection: collection}
109128
}
110129

111-
log.Debug("listed collections", "count", len(entities))
112-
return entities, nil
130+
hasNext := offset+int64(len(collections)) < total
131+
hasPrev := offset > 0
132+
133+
log.Debug("retrieved paginated collections", "total", total, "returned", len(entities), "has_next", hasNext, "has_prev", hasPrev)
134+
135+
return &PaginatedCollections{
136+
Collections: entities,
137+
Total: total,
138+
Offset: offset,
139+
Limit: limit,
140+
HasNext: hasNext,
141+
HasPrev: hasPrev,
142+
}, nil
113143
}

internal/collections/manager_test.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package collections
33
import (
44
"context"
55
"database/sql"
6+
"fmt"
67
"testing"
78

89
"github.com/maniac-en/req/internal/crud"
@@ -94,6 +95,39 @@ func TestCollectionsManagerCRUD(t *testing.T) {
9495
t.Errorf("Expected at least 2 collections, got %d", len(collections))
9596
}
9697
})
98+
99+
t.Run("ListPaginated", func(t *testing.T) {
100+
for i := 1; i <= 5; i++ {
101+
manager.Create(ctx, fmt.Sprintf("Pagination Test %d", i))
102+
}
103+
104+
paginated, err := manager.ListPaginated(ctx, 2, 0)
105+
if err != nil {
106+
t.Fatalf("ListPaginated failed: %v", err)
107+
}
108+
109+
if len(paginated.Collections) != 2 {
110+
t.Errorf("Expected 2 collections, got %d", len(paginated.Collections))
111+
}
112+
if paginated.Total < 5 {
113+
t.Errorf("Expected total >= 5, got %d", paginated.Total)
114+
}
115+
if !paginated.HasNext {
116+
t.Error("Expected HasNext to be true")
117+
}
118+
if paginated.HasPrev {
119+
t.Error("Expected HasPrev to be false for offset 0")
120+
}
121+
122+
// Test second page
123+
paginated2, err := manager.ListPaginated(ctx, 2, 2)
124+
if err != nil {
125+
t.Fatalf("ListPaginated page 2 failed: %v", err)
126+
}
127+
if !paginated2.HasPrev {
128+
t.Error("Expected HasPrev to be true for offset > 0")
129+
}
130+
})
97131
}
98132

99133
func TestCollectionsManagerValidation(t *testing.T) {

internal/collections/models.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,13 @@ func (c CollectionEntity) GetUpdatedAt() time.Time {
3939

4040
type CollectionsManager struct {
4141
DB *database.Queries
42+
}
43+
44+
type PaginatedCollections struct {
45+
Collections []CollectionEntity `json:"collections"`
46+
Total int64 `json:"total"`
47+
Offset int64 `json:"offset"`
48+
Limit int64 `json:"limit"`
49+
HasNext bool `json:"has_next"`
50+
HasPrev bool `json:"has_prev"`
4251
}

internal/database/collections.sql.go

Lines changed: 38 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)