Skip to content

Commit

Permalink
Fixing bug with Preloads
Browse files Browse the repository at this point in the history
  • Loading branch information
Manuel Doncel Martos committed Dec 24, 2024
1 parent 3bb2a58 commit 09f9f0b
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 14 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v0.0.1-rc4] 2024-12-24

## BugFix

- Fixing bug of using Pagination with preload

## [v0.0.1-rc3] 2024-12-17

## BugFix
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Using where to filter

Unpaged query

- [Many Pages With Preload](./examples/many-pages-preload/main.go)

Example using Preload

## 🔗 Contact

- 📧 [email protected]
66 changes: 66 additions & 0 deletions examples/many-pages-preload/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"fmt"
"github.com/manuelarte/pagorminator"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"strconv"
)

type Product struct {
gorm.Model
Code string
Price Price
}

type Price struct {
gorm.Model
Unit uint
Currency string
ProductID uint
}

func (p Product) String() string {
return fmt.Sprintf("Product{Code: %s, Price: %d}", p.Code, p.Price)
}

func main() {
db, err := gorm.Open(sqlite.Open("file:mem?mode=memory&cache=shared"), &gorm.Config{})
if err != nil {
panic("failed to connect database")
}

_ = db.Use(pagorminator.PaGormMinator{})
_ = db.AutoMigrate(&Product{}, &Price{})
length := 10
for i := 0; i < length; i++ {
errCreatingProduct := db.Create(&Product{Code: strconv.Itoa(i), Price: Price{Unit: uint(i), Currency: "EUR"}})
if errCreatingProduct.Error != nil {
panic(errCreatingProduct.Error)
}
}

fmt.Printf("%d product created\n", length)

var products []*Product
pageRequest, _ := pagorminator.PageRequest(0, 5)
txErr := db.Debug().Clauses(pageRequest).Preload("Price").Find(&products).Error
if txErr != nil {
panic(txErr)
}

fmt.Printf("PageRequest result:(Page: %d, Size: %d, TotalElements: %d, TotalPages: %d)\n",
pageRequest.GetPage(), pageRequest.GetSize(), pageRequest.GetTotalElements(), pageRequest.GetTotalPages())
for _, product := range products {
fmt.Printf("\t Product: %s\n", product)
}

pageRequest, _ = pagorminator.PageRequest(1, 5)
db.Clauses(pageRequest).Find(&products)
fmt.Printf("PageRequest result:(Page: %d, Size: %d, TotalElements: %d, TotalPages: %d)\n",
pageRequest.GetPage(), pageRequest.GetSize(), pageRequest.GetTotalElements(), pageRequest.GetTotalPages())
for _, product := range products {
fmt.Printf("\t Product: %s\n", product)
}
}
28 changes: 15 additions & 13 deletions pagorminator.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,21 @@ func (p PaGormMinator) count(db *gorm.DB) {
if db.Statement.Schema != nil {
if pageable, ok := p.getPageRequest(db); ok {
if value, ok := db.Get(countKey); !ok || !value.(bool) {
newDb := db.Session(&gorm.Session{NewDB: true})
newDb.Statement = db.Statement.Statement

var totalElements int64
tx := newDb.Set(countKey, true).Model(newDb.Statement.Model)
if whereClause, existWhere := db.Statement.Clauses["WHERE"]; existWhere {
tx.Where(whereClause.Expression)
}
tx.Count(&totalElements)
if tx.Error != nil {
_ = db.AddError(tx.Error)
} else {
pageable.totalElements = totalElements
if pageable.totalElements == 0 {
newDb := db.Session(&gorm.Session{NewDB: true})
newDb.Statement = db.Statement.Statement

var totalElements int64
tx := newDb.Set(countKey, true).Model(newDb.Statement.Model)
if whereClause, existWhere := db.Statement.Clauses["WHERE"]; existWhere {
tx.Where(whereClause.Expression)
}
tx.Count(&totalElements)
if tx.Error != nil {
_ = db.AddError(tx.Error)
} else {
pageable.totalElements = totalElements
}
}
}
}
Expand Down
62 changes: 61 additions & 1 deletion pagorminator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,18 @@ type TestStruct struct {
Price uint
}

type TestProduct struct {
gorm.Model
Code string
Price TestPrice
}
type TestPrice struct {
gorm.Model
Amount uint
Currency string
TestProductID uint
}

func TestPaginationScopeMetadata_NoWhere(t *testing.T) {
t.Parallel()
tests := map[string]struct {
Expand Down Expand Up @@ -146,14 +158,62 @@ func TestPaginationScopeMetadata_Where(t *testing.T) {
}
}

func TestPaginationWithPreload(t *testing.T) {
t.Parallel()
tests := map[string]struct {
toMigrate []*TestProduct
pageRequest *Pagination
expectedPage *Pagination
}{
"UnPaged one item, not filtered": {
toMigrate: []*TestProduct{
{Code: "1", Price: TestPrice{Amount: 1, Currency: "EUR"}},
},
pageRequest: UnPaged(),
expectedPage: &Pagination{
page: 0,
size: 0,
totalElements: 1,
},
},
"Paged 1/2 items": {
toMigrate: []*TestProduct{
{Code: "1", Price: TestPrice{Amount: 1, Currency: "EUR"}},
{Code: "2", Price: TestPrice{Amount: 2, Currency: "EUR"}},
},
pageRequest: &Pagination{page: 0, size: 1},
expectedPage: &Pagination{
page: 0,
size: 1,
totalElements: 2,
},
},
}

for name, test := range tests {
t.Run(name, func(t *testing.T) {
db := setupDb(t, name)
db.CreateInBatches(&test.toMigrate, len(test.toMigrate))

// Read
var products []*TestProduct

db.Clauses(test.pageRequest).Preload("Price").Find(&products)
if !equalPageRequests(test.pageRequest, test.expectedPage) {
t.Fatalf("expected page to be %d, got %d", test.expectedPage, test.pageRequest)
}
})
}
}

func setupDb(t *testing.T, name string) *gorm.DB {
db, err := gorm.Open(sqlite.Open(fmt.Sprintf("file:%s?mode=memory&cache=shared", name)), &gorm.Config{})
if err != nil {
t.Fatal("failed to connect database")
}

// Migrate the schema
err = db.AutoMigrate(&TestStruct{})
err = db.AutoMigrate(&TestStruct{}, &TestProduct{}, &TestPrice{})
if err != nil {
t.Fatal(err)
}
Expand Down

0 comments on commit 09f9f0b

Please sign in to comment.