added seasons list

This commit is contained in:
2026-02-01 13:25:11 +11:00
parent b25906b115
commit d7179a57da
17 changed files with 660 additions and 679 deletions

96
internal/db/paginate.go Normal file
View File

@@ -0,0 +1,96 @@
package db
import "github.com/uptrace/bun"
type PageOpts struct {
Page int
PerPage int
Order bun.Order
OrderBy string
}
type OrderOpts struct {
Order bun.Order
OrderBy string
Label string
}
// TotalPages calculates the total number of pages
func (p *PageOpts) TotalPages(total int) int {
if p.PerPage == 0 {
return 0
}
pages := total / p.PerPage
if total%p.PerPage > 0 {
pages++
}
return pages
}
// HasPrevPage checks if there is a previous page
func (p *PageOpts) HasPrevPage() bool {
return p.Page > 1
}
// HasNextPage checks if there is a next page
func (p *PageOpts) HasNextPage(total int) bool {
return p.Page < p.TotalPages(total)
}
// GetPageRange returns an array of page numbers to display
// maxButtons controls how many page buttons to show
func (p *PageOpts) GetPageRange(total int, maxButtons int) []int {
totalPages := p.TotalPages(total)
if totalPages == 0 {
return []int{}
}
// If total pages is less than max buttons, show all pages
if totalPages <= maxButtons {
pages := make([]int, totalPages)
for i := 0; i < totalPages; i++ {
pages[i] = i + 1
}
return pages
}
// Calculate range around current page
halfButtons := maxButtons / 2
start := p.Page - halfButtons
end := p.Page + halfButtons
// Adjust if at beginning
if start < 1 {
start = 1
end = maxButtons
}
// Adjust if at end
if end > totalPages {
end = totalPages
start = totalPages - maxButtons + 1
}
pages := make([]int, 0, maxButtons)
for i := start; i <= end; i++ {
pages = append(pages, i)
}
return pages
}
// StartItem returns the number of the first item on the current page
func (p *PageOpts) StartItem() int {
if p.Page < 1 {
return 0
}
return (p.Page-1)*p.PerPage + 1
}
// EndItem returns the number of the last item on the current page
func (p *PageOpts) EndItem(total int) int {
end := p.Page * p.PerPage
if end > total {
return total
}
return end
}

83
internal/db/season.go Normal file
View File

@@ -0,0 +1,83 @@
package db
import (
"context"
"database/sql"
"github.com/pkg/errors"
"github.com/uptrace/bun"
)
type Season struct {
bun.BaseModel `bun:"table:seasons,alias:s"`
ID int `bun:"id,pk,autoincrement"`
Name string `bun:"name,unique"`
ShortName string `bun:"short_name,unique"`
}
type SeasonList struct {
Seasons []Season
Total int
PageOpts PageOpts
}
func NewSeason(ctx context.Context, tx bun.Tx, name, shortname string) (*Season, error) {
if name == "" {
return nil, errors.New("name cannot be empty")
}
if shortname == "" {
return nil, errors.New("shortname cannot be empty")
}
season := &Season{
Name: name,
ShortName: shortname,
}
_, err := tx.NewInsert().
Model(season).
Exec(ctx)
if err != nil {
return nil, errors.Wrap(err, "tx.NewInsert")
}
return season, nil
}
func ListSeasons(ctx context.Context, tx bun.Tx, pageOpts *PageOpts) (*SeasonList, error) {
if pageOpts == nil {
pageOpts = &PageOpts{}
}
if pageOpts.Page == 0 {
pageOpts.Page = 1
}
if pageOpts.PerPage == 0 {
pageOpts.PerPage = 10
}
if pageOpts.Order == "" {
pageOpts.Order = bun.OrderDesc
}
if pageOpts.OrderBy == "" {
pageOpts.OrderBy = "name"
}
seasons := []Season{}
err := tx.NewSelect().
Model(&seasons).
OrderBy(pageOpts.OrderBy, pageOpts.Order).
Offset(pageOpts.PerPage * (pageOpts.Page - 1)).
Limit(pageOpts.PerPage).
Scan(ctx)
if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrap(err, "tx.NewSelect")
}
total, err := tx.NewSelect().
Model(&seasons).
Count(ctx)
if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrap(err, "tx.NewSelect")
}
sl := &SeasonList{
Seasons: seasons,
Total: total,
PageOpts: *pageOpts,
}
return sl, nil
}

View File

@@ -34,7 +34,7 @@ func (user *User) ChangeUsername(ctx context.Context, tx bun.Tx, newUsername str
Where("id = ?", user.ID).
Exec(ctx)
if err != nil {
return errors.Wrap(err, "tx.Update")
return errors.Wrap(err, "tx.NewUpdate")
}
user.Username = newUsername
return nil
@@ -55,7 +55,7 @@ func CreateUser(ctx context.Context, tx bun.Tx, username string, discorduser *di
Model(user).
Exec(ctx)
if err != nil {
return nil, errors.Wrap(err, "tx.Insert")
return nil, errors.Wrap(err, "tx.NewInsert")
}
return user, nil
@@ -75,7 +75,7 @@ func GetUserByID(ctx context.Context, tx bun.Tx, id int) (*User, error) {
if err.Error() == "sql: no rows in result set" {
return nil, nil
}
return nil, errors.Wrap(err, "tx.Select")
return nil, errors.Wrap(err, "tx.NewSelect")
}
return user, nil
}
@@ -111,7 +111,7 @@ func GetUserByDiscordID(ctx context.Context, tx bun.Tx, discordID string) (*User
if err.Error() == "sql: no rows in result set" {
return nil, nil
}
return nil, errors.Wrap(err, "tx.Select")
return nil, errors.Wrap(err, "tx.NewSelect")
}
return user, nil
}
@@ -124,7 +124,7 @@ func IsUsernameUnique(ctx context.Context, tx bun.Tx, username string) (bool, er
Where("username = ?", username).
Count(ctx)
if err != nil {
return false, errors.Wrap(err, "tx.Count")
return false, errors.Wrap(err, "tx.NewSelect")
}
return count == 0, nil
}