Add pagination support
This commit is contained in:
parent
4c8c363946
commit
631f908871
3 changed files with 54 additions and 3 deletions
1
main.go
1
main.go
|
@ -22,6 +22,7 @@ func setupRouter(env *Env, spotifyID string, spotifySecret string) *gin.Engine {
|
|||
// See: https://pkg.go.dev/github.com/gin-gonic/gin#Engine.SetTrustedProxies
|
||||
r.SetTrustedProxies(nil)
|
||||
r.Use(spotifyAuth(spotifyID, spotifySecret))
|
||||
r.Use(paginator())
|
||||
r.GET("/alive", env.alive)
|
||||
r.GET("/artists/:artistID", env.getArtistByID)
|
||||
r.GET("/artists", env.getArtistByName)
|
||||
|
|
54
routes.go
54
routes.go
|
@ -6,8 +6,53 @@ import (
|
|||
"gorm.io/gorm/clause"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// Pagination helper middleware
|
||||
// This just checks and inserts some default pagination values
|
||||
func paginator() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
queryPage := c.DefaultQuery("page", "1")
|
||||
queryPageSize := c.DefaultQuery("page_size", "10")
|
||||
|
||||
// add some defaults here if user gives us empty values
|
||||
if queryPage == ""{
|
||||
queryPage = "1"
|
||||
}
|
||||
if queryPageSize == "" {
|
||||
queryPageSize = "10"
|
||||
}
|
||||
|
||||
page, err := strconv.Atoi(queryPage)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"Error": "Failed to convert page parameter to number"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
pageSize, err := strconv.Atoi(queryPageSize)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"Error": "Failed to convert page_size parameter to number"})
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
if page < 1 || pageSize < 1 {
|
||||
page, pageSize = 1, 10
|
||||
}
|
||||
|
||||
// Calculate the correct SQL offset for this page
|
||||
offset := (page - 1) * pageSize
|
||||
c.Set("page", page)
|
||||
c.Set("page_size", pageSize)
|
||||
c.Set("page_offset", offset)
|
||||
|
||||
// Process request
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
func (env *Env) alive(c *gin.Context) {
|
||||
c.String(http.StatusOK, "yes!")
|
||||
}
|
||||
|
@ -70,13 +115,15 @@ func (env *Env) getArtistByName(c *gin.Context) {
|
|||
c.JSON(http.StatusBadRequest, gin.H{"Error": "name parameter was not supplied"})
|
||||
return
|
||||
}
|
||||
pageSize := c.GetInt("page_size")
|
||||
pageOffset := c.GetInt("page_offset")
|
||||
|
||||
// Lookup this name in the DB and return any ArtistProfile objects
|
||||
// NOTE: This is case insensitive for ascii on sqlite
|
||||
// NOTE: However unicode is treated case sensitive due to very difficult conversions for some languages/characters
|
||||
// NOTE: In future better DBs with unicode support such as postgres should be used
|
||||
var artistProfiles []ArtistProfile
|
||||
dbResult := env.db.Where("name LIKE ?", fmt.Sprintf("%%%s%%", artistName)).Preload("Genres").Find(&artistProfiles)
|
||||
dbResult := env.db.Where("name LIKE ?", fmt.Sprintf("%%%s%%", artistName)).Preload("Genres").Offset(pageOffset).Limit(pageSize).Find(&artistProfiles)
|
||||
if dbResult.Error != nil {
|
||||
slog.Error("[GOMUSIC] Failed to query local database for artist name", "Name", artistName)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to lookup name"})
|
||||
|
@ -88,7 +135,10 @@ func (env *Env) getArtistByName(c *gin.Context) {
|
|||
|
||||
func (env *Env) getGenres(c *gin.Context) {
|
||||
var genres []Genre
|
||||
dbResult := env.db.Find(&genres)
|
||||
pageSize := c.GetInt("page_size")
|
||||
pageOffset := c.GetInt("page_offset")
|
||||
|
||||
dbResult := env.db.Offset(pageOffset).Limit(pageSize).Find(&genres)
|
||||
if dbResult.Error != nil {
|
||||
slog.Error("[GOMUSIC] Failed to query local database for genre data")
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"Error": "Failed to query database for genre data"})
|
||||
|
|
|
@ -97,7 +97,7 @@ func TestGetArtistByName(t *testing.T) {
|
|||
assert.Fail(t, fmt.Sprintf("Could not validate and parse JSON response: %s", err.Error()))
|
||||
}
|
||||
|
||||
// only response should be kanye
|
||||
// only response should be aesop
|
||||
assert.Equal(t, "Aesop Rock", resp[0].Name)
|
||||
assert.Equal(t, "2fSaE6BXtQy0x7R7v9IOmZ", resp[0].SpotifyID)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue