Skip to content

Commit 6aadb34

Browse files
authored
chore(pagination): Move cursor based pagination to pkg (#1614)
Signed-off-by: Javier Rodriguez <[email protected]>
1 parent d5f42a0 commit 6aadb34

File tree

7 files changed

+41
-16
lines changed

7 files changed

+41
-16
lines changed

app/controlplane/internal/service/service.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ func handleUseCaseErr(err error, l *log.Helper) error {
142142
switch {
143143
case errors.Is(err, context.Canceled):
144144
return errors.ClientClosed("client closed", err.Error())
145-
case biz.IsErrValidation(err) || biz.IsErrInvalidUUID(err) || biz.IsErrInvalidTimeWindow(err) || pagination.IsOffsetPaginationError(err):
145+
case biz.IsErrValidation(err) || biz.IsErrInvalidUUID(err) || biz.IsErrInvalidTimeWindow(err) ||
146+
pagination.IsOffsetPaginationError(err) || pagination.IsCursorPaginationError(err):
146147
return errors.BadRequest("invalid", err.Error())
147148
case biz.IsNotFound(err):
148149
return errors.NotFound("not found", err.Error())

app/controlplane/internal/service/workflowrun.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ import (
2121

2222
pb "github.com/chainloop-dev/chainloop/app/controlplane/api/controlplane/v1"
2323
craftingpb "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
24-
"github.com/chainloop-dev/chainloop/app/controlplane/internal/pagination"
2524
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz"
25+
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/pagination"
2626
"github.com/chainloop-dev/chainloop/pkg/credentials"
2727
errors "github.com/go-kratos/kratos/v2/errors"
2828
"github.com/google/uuid"

app/controlplane/pkg/biz/mocks/WorkflowRunRepo.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/controlplane/pkg/biz/workflowrun.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import (
2222
"io"
2323
"time"
2424

25-
"github.com/chainloop-dev/chainloop/app/controlplane/internal/pagination"
25+
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/pagination"
2626
"github.com/chainloop-dev/chainloop/pkg/attestation"
2727
"github.com/chainloop-dev/chainloop/pkg/attestation/renderer/chainloop"
2828
"github.com/secure-systems-lab/go-securesystemslib/dsse"

app/controlplane/pkg/biz/workflowrun_integration_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ import (
2222
"testing"
2323

2424
schemav1 "github.com/chainloop-dev/chainloop/app/controlplane/api/workflowcontract/v1"
25-
"github.com/chainloop-dev/chainloop/app/controlplane/internal/pagination"
2625
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz"
2726
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz/testhelpers"
27+
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/pagination"
2828
"github.com/chainloop-dev/chainloop/pkg/credentials"
2929
creds "github.com/chainloop-dev/chainloop/pkg/credentials/mocks"
3030
"github.com/google/uuid"

app/controlplane/pkg/data/workflowrun.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ import (
2121
"fmt"
2222
"time"
2323

24-
"github.com/chainloop-dev/chainloop/app/controlplane/internal/pagination"
2524
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/biz"
2625
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent"
2726
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/organization"
2827
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/projectversion"
2928
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/workflow"
3029
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/data/ent/workflowrun"
30+
"github.com/chainloop-dev/chainloop/app/controlplane/pkg/pagination"
3131
"github.com/go-kratos/kratos/v2/log"
3232
"github.com/google/uuid"
3333
"github.com/secure-systems-lab/go-securesystemslib/dsse"

app/controlplane/internal/pagination/cursor.go renamed to app/controlplane/pkg/pagination/cursor.go

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,28 +25,51 @@ import (
2525
"github.com/google/uuid"
2626
)
2727

28+
// DefaultCursorLimit is the default number of items per page for cursor-based pagination
29+
const DefaultCursorLimit = 10
30+
31+
// Cursor is a struct that holds the timestamp and identifier of a record
32+
type Cursor struct {
33+
Timestamp *time.Time
34+
ID *uuid.UUID
35+
}
36+
37+
// CursorOptions is a struct that holds the cursor and limit for pagination
2838
type CursorOptions struct {
2939
Cursor *Cursor
3040
Limit int
3141
}
3242

33-
type Cursor struct {
34-
Timestamp *time.Time
35-
ID *uuid.UUID
43+
// CursorPaginationError is the error type for cursor-based pagination
44+
type CursorPaginationError struct {
45+
err error
46+
}
47+
48+
// NewCursorPaginationError creates a new CursorPaginationError with the provided error
49+
func NewCursorPaginationError(err error) CursorPaginationError {
50+
return CursorPaginationError{err}
3651
}
3752

38-
const defaultLimit = 10
53+
// Error returns the error message
54+
func (e CursorPaginationError) Error() string {
55+
return e.err.Error()
56+
}
57+
58+
// IsCursorPaginationError checks if the error is an CursorPaginationError
59+
func IsCursorPaginationError(err error) bool {
60+
return errors.As(err, &CursorPaginationError{})
61+
}
3962

4063
func NewCursor(c string, l int) (*CursorOptions, error) {
4164
var cursor *Cursor
42-
var limit = defaultLimit
65+
var limit = DefaultCursorLimit
4366

4467
if c != "" {
45-
time, uuid, err := decodeCursor(c)
68+
timestamp, id, err := decodeCursor(c)
4669
if err != nil {
47-
return nil, fmt.Errorf("decoding cursor: %w", err)
70+
return nil, NewCursorPaginationError(fmt.Errorf("decoding cursor: %w", err))
4871
}
49-
cursor = &Cursor{Timestamp: time, ID: uuid}
72+
cursor = &Cursor{Timestamp: timestamp, ID: id}
5073
}
5174

5275
if l > 0 {
@@ -59,6 +82,7 @@ func NewCursor(c string, l int) (*CursorOptions, error) {
5982
}, nil
6083
}
6184

85+
// decodeCursor decodes a base64 encoded cursor into a timestamp and identifier
6286
func decodeCursor(encodedCursor string) (*time.Time, *uuid.UUID, error) {
6387
byt, err := base64.StdEncoding.DecodeString(encodedCursor)
6488
if err != nil {
@@ -76,12 +100,12 @@ func decodeCursor(encodedCursor string) (*time.Time, *uuid.UUID, error) {
76100
}
77101

78102
rawID := arrStr[1]
79-
uuid, err := uuid.Parse(rawID)
103+
id, err := uuid.Parse(rawID)
80104
if err != nil {
81105
return nil, nil, err
82106
}
83107

84-
return &timestamp, &uuid, nil
108+
return &timestamp, &id, nil
85109
}
86110

87111
// EncodeCursor generates a base64 encoded representation of a timestamp + identifier

0 commit comments

Comments
 (0)