Skip to content

Commit 424e1f4

Browse files
authored
feat(backend): crud managers with pagination #19
2 parents bc83291 + 472d38a commit 424e1f4

File tree

17 files changed

+894
-156
lines changed

17 files changed

+894
-156
lines changed

db/queries/endpoints.sql

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,15 @@ RETURNING *;
1616
SELECT * FROM endpoints
1717
WHERE id = ? LIMIT 1;
1818

19-
-- name: ListEndpoints :many
19+
-- name: ListEndpointsPaginated :many
2020
SELECT * FROM endpoints
2121
WHERE collection_id = ?
22-
ORDER BY name;
22+
ORDER BY name
23+
LIMIT ? OFFSET ?;
24+
25+
-- name: CountEndpointsByCollection :one
26+
SELECT COUNT(*) FROM endpoints
27+
WHERE collection_id = ?;
2328

2429
-- name: UpdateEndpoint :one
2530
UPDATE endpoints

internal/collections/manager.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (c *CollectionsManager) List(ctx context.Context) ([]CollectionEntity, erro
104104
return paginated.Collections, nil
105105
}
106106

107-
func (c *CollectionsManager) ListPaginated(ctx context.Context, limit, offset int64) (*PaginatedCollections, error) {
107+
func (c *CollectionsManager) ListPaginated(ctx context.Context, limit, offset int) (*PaginatedCollections, error) {
108108
log.Debug("listing paginated collections", "limit", limit, "offset", offset)
109109

110110
total, err := c.DB.CountCollections(ctx)
@@ -114,8 +114,8 @@ func (c *CollectionsManager) ListPaginated(ctx context.Context, limit, offset in
114114
}
115115

116116
collections, err := c.DB.GetCollectionsPaginated(ctx, database.GetCollectionsPaginatedParams{
117-
Limit: limit,
118-
Offset: offset,
117+
Limit: int64(limit),
118+
Offset: int64(offset),
119119
})
120120
if err != nil {
121121
log.Error("failed to get paginated collections", "limit", limit, "offset", offset, "error", err)
@@ -127,17 +127,12 @@ func (c *CollectionsManager) ListPaginated(ctx context.Context, limit, offset in
127127
entities[i] = CollectionEntity{Collection: collection}
128128
}
129129

130-
hasNext := offset+int64(len(collections)) < total
131-
hasPrev := offset > 0
130+
pagination := crud.CalculatePagination(total, limit, offset)
132131

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
132+
result := &PaginatedCollections{
133+
Collections: entities,
134+
PaginationMetadata: pagination,
135+
}
136+
log.Info("retrieved collections", "count", len(entities), "total", pagination.Total, "page", pagination.CurrentPage, "total_pages", pagination.TotalPages)
137+
return result, nil
143138
}

internal/collections/manager_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ func TestCollectionsManagerCRUD(t *testing.T) {
100100
for i := 1; i <= 5; i++ {
101101
manager.Create(ctx, fmt.Sprintf("Pagination Test %d", i))
102102
}
103-
103+
104104
paginated, err := manager.ListPaginated(ctx, 2, 0)
105105
if err != nil {
106106
t.Fatalf("ListPaginated failed: %v", err)
107107
}
108-
108+
109109
if len(paginated.Collections) != 2 {
110110
t.Errorf("Expected 2 collections, got %d", len(paginated.Collections))
111111
}
@@ -118,7 +118,7 @@ func TestCollectionsManagerCRUD(t *testing.T) {
118118
if paginated.HasPrev {
119119
t.Error("Expected HasPrev to be false for offset 0")
120120
}
121-
121+
122122
// Test second page
123123
paginated2, err := manager.ListPaginated(ctx, 2, 2)
124124
if err != nil {
@@ -155,4 +155,4 @@ func TestCollectionsManagerValidation(t *testing.T) {
155155
t.Errorf("Expected ErrNotFound, got %v", err)
156156
}
157157
})
158-
}
158+
}

internal/collections/models.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package collections
33
import (
44
"time"
55

6+
"github.com/maniac-en/req/internal/crud"
67
"github.com/maniac-en/req/internal/database"
78
"github.com/maniac-en/req/internal/log"
89
)
@@ -43,9 +44,5 @@ type CollectionsManager struct {
4344

4445
type PaginatedCollections struct {
4546
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"`
51-
}
47+
crud.PaginationMetadata
48+
}

internal/crud/interfaces.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,31 @@ type Manager[T Entity] interface {
2525
Update(ctx context.Context, id int64, name string) (T, error)
2626
Delete(ctx context.Context, id int64) error
2727
List(ctx context.Context) ([]T, error)
28-
}
28+
}
29+
30+
type PaginationMetadata struct {
31+
Total int64 `json:"total"`
32+
HasNext bool `json:"has_next"`
33+
HasPrev bool `json:"has_prev"`
34+
Limit int `json:"limit"`
35+
Offset int `json:"offset"`
36+
TotalPages int `json:"total_pages"`
37+
CurrentPage int `json:"current_page"`
38+
}
39+
40+
func CalculatePagination(total int64, limit, offset int) PaginationMetadata {
41+
totalPages := int((total + int64(limit) - 1) / int64(limit)) // Ceiling division
42+
currentPage := (offset / limit) + 1
43+
hasNext := (offset + limit) < int(total)
44+
hasPrev := offset > 0
45+
46+
return PaginationMetadata{
47+
Total: total,
48+
HasNext: hasNext,
49+
HasPrev: hasPrev,
50+
Limit: limit,
51+
Offset: offset,
52+
TotalPages: totalPages,
53+
CurrentPage: currentPage,
54+
}
55+
}

0 commit comments

Comments
 (0)