A simple way to implement pagination in Golang.
package main
import (
"fmt"
"github.com/vcraescu/go-paginator/v2"
"github.com/vcraescu/go-paginator/v2/adapter"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"time"
)
type Post struct {
ID uint `gorm:"primary_key"`
Title string
Body string
PublishedAt time.Time
}
func main() {
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
if err != nil {
panic(fmt.Errorf("db connection error: %s", err))
}
if err := db.AutoMigrate(&Post{}); err != nil {
panic(err)
}
var posts []Post
q := db.Model(Post{}).Where("published_at > ?", time.Now())
p := paginator.New(adapter.NewGORMAdapter(q), 10)
p.SetPage(2)
if err = p.Results(&posts); err != nil {
panic(err)
}
for _, post := range posts {
fmt.Println(post.Title)
}
}
Some of other methods available:
p.HasNext()
p.HasPrev()
p.HasPages()
p.PageNums()
An adapter must implement the Adapter
interface which has 2 methods:
- Nums - must return the number of results;
- Slice - must retrieve a slice for an offset and length.
This way you can create your own adapter for any kind of data source you want to paginate.
type Adapter interface {
Nums() (int64, error)
Slice(offset, length int, data interface{}) error
}
To paginate a GORM query builder.
q := db.Model(Post{}).Where("published_at > ?", time.Now())
p := paginator.New(adapter.NewGORMAdapter(q), 10)
To paginate a slice.
var pages []int
p := paginator.New(adapter.NewSliceAdapter(pages), 10)
View models contains all necessary logic to render the paginator inside a template.
Use it if you want to render a paginator similar to the one from Google search.
< Prev 2 3 4 5 6 7 8 9 10 11 Next >
func main() {
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
if err != nil {
panic(fmt.Errorf("db connection error: %s", err))
}
db.AutoMigrate(&Post{})
var posts []Post
q := db.Model(Post{}).Where("published_at > ?", time.Now())
p := paginator.New(adapter.NewGORMAdapter(q), 10)
p.SetPage(7)
view := view.New(&p)
pages, _ := view.Pages()
fmt.Println(pages) // [2 3 4 5 6 7 8 9 10 11]
next, _ := view.Next()
fmt.Println(next) // 8
prev, _ := view.Prev()
fmt.Println(prev) // 6
current, _ := view.Current()
fmt.Println(current) // 7
}
- More adapters
Paginator is licensed under the MIT License.