Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .custom-gcl.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
version: v2.12.2
version: v2.13.1
plugins:
- module: "github.com/manuelarte/testcomments"
import: "github.com/manuelarte/testcomments/plugin"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pr-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,4 @@ jobs:
- name: golangci-lint
uses: golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee # v9.2.1
with:
version: v2.12
version: v2.13
14 changes: 10 additions & 4 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ formatters:
- pattern: "interface{}"
replacement: "any"
gofumpt:
extra-rules: true
extra:
group-params: true
gci:
sections:
- standard
Expand All @@ -32,6 +33,7 @@ linters:
- err113
- errchkjson
- exhaustruct
- exhaustruct_v5
- forcetypeassert
- ginkgolinter # Related to Ginkgo.
- goheader
Expand All @@ -42,18 +44,16 @@ linters:
- intrange
- ireturn
- maintidx
- noinlineerr # I prefer inlined errors.
- nlreturn
- noinlineerr # I prefer inlined errors.
- prealloc
- promlinter # Related to prometheus.
- protogetter # Related to protocol buffer.
- spancheck # Related to OpenTelemetry
- sqlclosecheck # Related to SQL.
- tagliatelle
- testpackage
- thelper
- varnamelen
- wrapcheck
- wsl # Deprecated, use wsl_v5 instead.
- zerologlint
# keep-sorted end
Expand Down Expand Up @@ -121,6 +121,11 @@ linters:
paramsOnly: false
underef:
skipRecvDeref: false
godoclint:
default: all
options:
max-len:
length: 120
godox:
keywords:
- FIXME
Expand Down Expand Up @@ -177,6 +182,7 @@ linters:
- funlen
- gocognit
- goconst
- godoclint
- gosec
path: _test\.go

Expand Down
15 changes: 10 additions & 5 deletions cursorpagination/errors.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package cursorpagination

Check failure on line 1 in cursorpagination/errors.go

View workflow job for this annotation

GitHub Actions / build (stable, ubuntu-latest)

File test coverage below threshold

File test coverage below threshold: coverage: 40.0% (2/5); threshold: 50%

Check failure on line 1 in cursorpagination/errors.go

View workflow job for this annotation

GitHub Actions / build (stable, ubuntu-latest)

File test coverage below threshold

File test coverage below threshold: coverage: 40.0% (2/5); threshold: 50%

import (
"errors"
Expand All @@ -7,17 +7,22 @@
)

var (
ErrSizeCantBeNegative = errors.New("size can't be negative")
ErrCursorsRequired = errors.New("order is required")
ErrOrderNotValid = errors.New("order is not valid")
_ error = new(CursorValuesNotValidError)
// ErrSizeCantBeNegative is returned when the size is negative.
ErrSizeCantBeNegative = errors.New("size can't be negative")
// ErrCursorsRequired is returned when the order is required.
ErrCursorsRequired = errors.New("order is required")
// ErrOrderNotValid is returned when the order is not valid.
ErrOrderNotValid = errors.New("order is not valid")
_ error = new(CursorValuesNotValidError)
)

// CursorValuesNotValidError is an error type that represents an invalid cursor values.
type CursorValuesNotValidError struct {
CursorsHaveValues []string
CursorsNilValue []string
}

// Error returns the error message.
func (c CursorValuesNotValidError) Error() string {
return fmt.Sprintf(
"some cursor have values and some others don't, with:[%v], without[%v]",
Expand All @@ -26,7 +31,7 @@
)
}

// Is allows errors.Is to compare CursorValuesNotValidError values even though
// Is allows [errors.Is] to compare CursorValuesNotValidError values even though
// the struct contains slice fields (which are not directly comparable).
// It returns true when the target error is a CursorValuesNotValidError (or
// pointer to) and both slices have the same contents in the same order.
Expand Down
4 changes: 4 additions & 0 deletions cursorpagination/pagination.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
)

type (
// Cursor represents a cursor.
//go:structinit
Cursor struct {
order pagegeneric.Order
Expand Down Expand Up @@ -107,6 +108,7 @@ func (p *Pagination) Cursors() []Cursor {
return slices.Clone(p.cursors)
}

// TotalElements returns the total elements.
func (p *Pagination) TotalElements() (int64, bool) {
p.mu.RLock()
defer p.mu.RUnlock()
Expand Down Expand Up @@ -138,6 +140,7 @@ func (p *Pagination) IsUnPaged() bool {
return p.size == 0 && len(p.cursors) == 0
}

// IsTotalElementsSet Check whether the total elements are set.
func (p *Pagination) IsTotalElementsSet() bool {
p.mu.RLock()
defer p.mu.RUnlock()
Expand Down Expand Up @@ -198,6 +201,7 @@ func newCursor(order pagegeneric.Order, value any) Cursor {
return Cursor{order: order, value: value}
}

// Column returns the cursor column.
func (c Cursor) Column() string {
return c.order.Column()
}
Expand Down
4 changes: 4 additions & 0 deletions docs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Package pagorminator providers pagination utilities for GORM.
// It provides two types of pagination: cursor-based and page-based.
// It also provides a generic interface for pagination that can be used to implement custom pagination strategies.
package pagorminator
1 change: 1 addition & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var (
)

type (
// PaginationRequest is the interface that contains the information about the pagination.
PaginationRequest interface {
// Size returns the pagination size, a.k.a. limit
Size() int
Expand Down
1 change: 1 addition & 0 deletions pagegeneric/errors.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package pagegeneric

Check failure on line 1 in pagegeneric/errors.go

View workflow job for this annotation

GitHub Actions / build (stable, ubuntu-latest)

File test coverage below threshold

File test coverage below threshold: coverage: 0.0% (0/1); threshold: 50%

Check failure on line 1 in pagegeneric/errors.go

View workflow job for this annotation

GitHub Actions / build (stable, ubuntu-latest)

File test coverage below threshold

File test coverage below threshold: coverage: 0.0% (0/1); threshold: 50%

import (
"fmt"
Expand All @@ -13,6 +13,7 @@
}
)

// Error returns the error message.
func (e TotalElementsNotValidError) Error() string {
return fmt.Sprintf("total elements is not valid: %d", e.TotalElements)
}
6 changes: 6 additions & 0 deletions pagegeneric/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type (
order()
}

// Sort represents a collection of Order.
Sort []Order

// Asc is ascending order.
Expand All @@ -27,20 +28,24 @@ type (
Desc string
)

// Column returns the column name of the order.
func (a Asc) Column() string {
return string(a)
}

// GormString returns the string representation of the order for gorm.
func (a Asc) GormString() string {
return fmt.Sprintf("%s ASC", a)
}

func (a Asc) order() {}

// Column returns the column name of the order.
func (d Desc) Column() string {
return string(d)
}

// GormString returns the string representation of the order for gorm.
func (d Desc) GormString() string {
return fmt.Sprintf("%s DESC", d)
}
Expand All @@ -57,6 +62,7 @@ func Unsorted() Sort {
return Sort{}
}

// String returns the string representation of the sort.
func (s Sort) String() string {
orderStrings := make([]string, len(s))
for i, order := range s {
Expand Down
5 changes: 4 additions & 1 deletion pagepagination/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package pagepagination
import "errors"

var (
// ErrPageCantBeNegative is an error type that represents an invalid page value.
ErrPageCantBeNegative = errors.New("page number can't be negative")
// ErrSizeCantBeNegative is an error type that represents an invalid size value.
ErrSizeCantBeNegative = errors.New("size can't be negative")
ErrSizeNotAllowed = errors.New("size is not allowed")
// ErrSizeNotAllowed is an error type that represents an invalid size value.
ErrSizeNotAllowed = errors.New("size is not allowed")
)
1 change: 1 addition & 0 deletions pagepagination/pagination.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ func (p *Pagination) IsSort() bool {
return len(p.sort) > 0
}

// IsTotalElementsSet Check whether the total elements are set.
func (p *Pagination) IsTotalElementsSet() bool {
p.mu.RLock()
defer p.mu.RUnlock()
Expand Down
1 change: 1 addition & 0 deletions pagorminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type PaGorminator struct {
Debug bool
}

// Name returns the name of the plugin.
func (p PaGorminator) Name() string {
return "pagorminator"
}
Expand Down
4 changes: 4 additions & 0 deletions pagorminator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1463,6 +1463,8 @@ func TestCursorPaginationTotalElementsIgnoreCursorWhere(t *testing.T) {
}

func setupDB(t *testing.T) *gorm.DB {
t.Helper()

db, err := gorm.Open(sqlite.Open(fmt.Sprintf("file:%s?mode=memory&cache=shared", t.Name())), &gorm.Config{})
if err != nil {
t.Fatal("failed to connect database")
Expand Down Expand Up @@ -1587,6 +1589,8 @@ func compareTestStructs(t *testing.T, got, want []*TestStruct) {
}

func comparePaginations(t *testing.T, got Pagination, want any) {
t.Helper()

switch actual := got.(type) {
case *pagepagination.Pagination:
if diff := cmp.Diff(
Expand Down
Loading