v3.3.0
Changelog
Pagination
The new pagination API lets you split the results of a query into chunks containing a fixed number of items.
Simple pagination for db.Result
res = sess.Collection("posts").Paginate(20) // 20 results per page
err = res.All(&posts) // First 20 results of the query
err = res.Page(2).All(&posts) // Results from page 2 (limit 20, offset 40)
Simple pagination for SQL builder
q = sess.SelectFrom("posts").Paginate(20)
err = res.All(&posts) // First 20 results of the query
err = res.Page(2).All(&posts) // Results from page 2 (limit 20, offset 40)
Cursor based pagination (both for db.Result and SQL Builder)
res = sess.Collection("posts").
Paginate(20). // 20 results per page
Cursor("id") // using id as cursor
err = res.All(&posts) // First 20 results of the query
// Get the next 20 results starting from the last item of the previous query.
res = res.NextPage(posts[len(posts)-1].ID)
err = res.All(&posts) // Results from page 1, limit 20, offset 20
Other commonly used pagination tools
res = res.Paginate(23)
totalNumberOfEntries, err = res.TotalEntries()
totalNumberOfPages, err = res.TotalPages()
Support for binary and text mode (PostgreSQL)
pgbouncer requires binary mode (binary_parameters="yes"
) to be enabled, but all of the auto-fields that were working with text mode started failing with binary mode.
Starting with v3.3.0 upper-db supports binary mode. This is how you can enable binary mode in your PostgreSQL session:
settings = postgresql.ConnectionURL {
...
Options: map[string]string{
"binary_parameters": "yes",
},
}
Unfortunately, for this to work we had to push a breaking change: any fields that used stringarray
, int64array
and jsonb
options need to be changed into an special type.
// Before v3.3.0
type Demo struct {
MyIntegers []int64 `db:"my_integers,int64array"`
MyStrings []string `db:"my_strings,stringarray"`
MyWhatevs map[string]interface{}`db:"field,jsonb"`
}
// v3.3.0+
type Demo struct {
MyIntegers postgresql.Int64Array `db:"my_integers"`
MyStrings postgresql.StringArray `db:"my_strings"`
MyWhatevs postgresql.JSONBMap`db:"field"`
}
To make sure the user is aware of this, the mapping methods will now throw an error when stringarray
, int64array
or jsonb
field tags are detected.
You can use any other custom struct as long as it satisfies driver.Valuer
and sql.Scanner
. The postgresql
package providers some handy functions for when you want to encode something into JSONB format:
import (
...
"database/sql/driver"
"database/sql"
"upper.io/db.v3/postgresql"
)
type Demo struct {
MyWhatevs customJSONB `db:"field"`
}
type customJSONB struct {
N string `json:"name"`
V float64 `json:"value"`
}
func (c customJSONB) Value() (driver.Value, error) {
return postgresql.EncodeJSONB(c)
}
func (c *customJSONB) Scan(src interface{}) error {
return postgresql.DecodeJSONB(c, src)
}
var (
_ driver.Valuer = &customJSONB{}
_ sql.Scanner = &customJSONB{}
)
Here are some other types provided by the postgresql
package:
postgresql.Float64Array // []float64
postgresql.GenericArray // []interface{}
postgresql.BoolArray // []bool
postgresql.JSONB // interface{}
postgresql.JSONBMap // map[string]interface{}
postgresql.JSONBArray // []interface{}
Feel free to open a ticket if you find any bug or need help!