分页器调整

This commit is contained in:
xing 2023-02-27 21:34:48 +08:00
parent 1b1e3bf8f3
commit eab6db83eb
6 changed files with 56 additions and 56 deletions

View File

@ -92,8 +92,10 @@ func GetPostsByIds(a ...any) (m map[uint64]models.Posts, err error) {
func SearchPostIds(args ...any) (ids PostIds, err error) { func SearchPostIds(args ...any) (ids PostIds, err error) {
ctx := args[0].(context.Context) ctx := args[0].(context.Context)
q := args[1].(model.QueryCondition) q := args[1].(model.QueryCondition)
page := args[2].(int)
pageSize := args[3].(int)
q.Fields = "ID" q.Fields = "ID"
res, total, err := model.Pagination[models.Posts](ctx, q) res, total, err := model.Pagination[models.Posts](ctx, q, page, pageSize)
for _, posts := range res { for _, posts := range res {
ids.Ids = append(ids.Ids, posts.Id) ids.Ids = append(ids.Ids, posts.Id)
} }

View File

@ -8,7 +8,6 @@ type QueryCondition struct {
Order SqlBuilder Order SqlBuilder
Join SqlBuilder Join SqlBuilder
Having SqlBuilder Having SqlBuilder
Page int
Limit int Limit int
Offset int Offset int
In [][]any In [][]any
@ -68,12 +67,6 @@ func Having(having SqlBuilder) Condition {
} }
} }
func Page(page int) Condition {
return func(c *QueryCondition) {
c.Page = page
}
}
func Limit(limit int) Condition { func Limit(limit int) Condition {
return func(c *QueryCondition) { return func(c *QueryCondition) {
c.Limit = limit c.Limit = limit

View File

@ -9,10 +9,11 @@ import (
"strings" "strings"
) )
func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []T, total int, err error) { func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) (r []T, total int, err error) {
if q.Page < 1 { if page < 1 || pageSize < 1 {
return return
} }
q.Limit = pageSize
qx := QueryCondition{ qx := QueryCondition{
Where: q.Where, Where: q.Where,
Having: q.Having, Having: q.Having,
@ -42,45 +43,41 @@ func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r [
return return
} }
offset := 0 offset := 0
if q.Page > 1 { if page > 1 {
offset = (q.Page - 1) * q.Limit offset = (page - 1) * q.Limit
} }
if offset >= total { if offset >= total {
return return
} }
q.Offset = offset q.Offset = offset
m := ctx.Value("handle=>") m := ctx.Value("handle=>toMap")
if m == nil { if m == nil {
r, err = finds[T](db, ctx, q) r, err = finds[T](db, ctx, q)
return return
} }
mm, ok := m.(string) mm, ok := m.(*[]map[string]string)
if ok && mm == "toMap" { if ok {
v := ctx.Value("map")
mx, er := findToStringMap[T](db, ctx, q) mx, er := findToStringMap[T](db, ctx, q)
if er != nil { if er != nil {
err = er err = er
return return
} }
vv := v.(*[]map[string]string) *mm = mx
*vv = mx
return
} }
return return
} }
func paginationToMap[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []map[string]string, total int, err error) { func paginationToMap[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
ctx = context.WithValue(ctx, "handle=>", "toMap") ctx = context.WithValue(ctx, "handle=>toMap", &r)
ctx = context.WithValue(ctx, "map", &r) _, total, err = pagination[T](db, ctx, q, page, pageSize)
_, total, err = pagination[T](db, ctx, q)
return return
} }
func PaginationToMap[T Model](ctx context.Context, q QueryCondition) (r []map[string]string, total int, err error) { func PaginationToMap[T Model](ctx context.Context, q QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
return paginationToMap[T](globalBb, ctx, q) return paginationToMap[T](globalBb, ctx, q, page, pageSize)
} }
func PaginationToMapFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []map[string]string, total int, err error) { func PaginationToMapFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
return paginationToMap[T](db, ctx, q) return paginationToMap[T](db, ctx, q, page, pageSize)
} }
func FindOneById[T Model, I constraints.Integer](ctx context.Context, id I) (T, error) { func FindOneById[T Model, I constraints.Integer](ctx context.Context, id I) (T, error) {

View File

@ -468,6 +468,8 @@ func Test_pagination(t *testing.T) {
db dbQuery db dbQuery
ctx context.Context ctx context.Context
q QueryCondition q QueryCondition
page int
pageSize int
} }
type testCase[T Model] struct { type testCase[T Model] struct {
name string name string
@ -487,10 +489,12 @@ func Test_pagination(t *testing.T) {
Group: "post_type", Group: "post_type",
Having: SqlBuilder{{"ID", ">", "1", "int"}}, Having: SqlBuilder{{"ID", ">", "1", "int"}},
}, },
page: 1,
pageSize: 2,
}, },
wantR: func() (r []post) { wantR: func() (r []post) {
err := glob.Selects(ctx, &r, "select post_type,count(*) ID from wp_posts group by post_type having `ID`> 1") err := glob.Selects(ctx, &r, "select post_type,count(*) ID from wp_posts group by post_type having `ID`> 1 limit 2")
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -502,7 +506,7 @@ func Test_pagination(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
gotR, gotTotal, err := pagination[post](tt.args.db, tt.args.ctx, tt.args.q) gotR, gotTotal, err := pagination[post](tt.args.db, tt.args.ctx, tt.args.q, tt.args.page, tt.args.pageSize)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("pagination() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("pagination() error = %v, wantErr %v", err, tt.wantErr)
return return
@ -522,6 +526,8 @@ func Test_paginationToMap(t *testing.T) {
db dbQuery db dbQuery
ctx context.Context ctx context.Context
q QueryCondition q QueryCondition
page int
pageSize int
} }
tests := []struct { tests := []struct {
name string name string
@ -537,10 +543,10 @@ func Test_paginationToMap(t *testing.T) {
ctx: ctx, ctx: ctx,
q: QueryCondition{ q: QueryCondition{
Fields: "ID", Fields: "ID",
Limit: 2,
Page: 1,
Where: SqlBuilder{{"ID < 200"}}, Where: SqlBuilder{{"ID < 200"}},
}, },
page: 1,
pageSize: 2,
}, },
wantR: []map[string]string{{"ID": "63"}, {"ID": "64"}}, wantR: []map[string]string{{"ID": "63"}, {"ID": "64"}},
wantTotal: 4, wantTotal: 4,
@ -552,10 +558,10 @@ func Test_paginationToMap(t *testing.T) {
ctx: ctx, ctx: ctx,
q: QueryCondition{ q: QueryCondition{
Fields: "ID", Fields: "ID",
Limit: 2,
Page: 2,
Where: SqlBuilder{{"ID < 200"}}, Where: SqlBuilder{{"ID < 200"}},
}, },
page: 2,
pageSize: 2,
}, },
wantR: []map[string]string{{"ID": "190"}, {"ID": "193"}}, wantR: []map[string]string{{"ID": "190"}, {"ID": "193"}},
wantTotal: 4, wantTotal: 4,
@ -563,11 +569,11 @@ func Test_paginationToMap(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
gotR, gotTotal, err := PaginationToMap[post](tt.args.ctx, tt.args.q) gotR, gotTotal, err := PaginationToMap[post](tt.args.ctx, tt.args.q, tt.args.page, tt.args.pageSize)
fmt.Println(gotR, gotTotal, err) fmt.Println(gotR, gotTotal, err)
gotR, gotTotal, err = PaginationToMapFromDB[post](tt.args.db, tt.args.ctx, tt.args.q) gotR, gotTotal, err = PaginationToMapFromDB[post](tt.args.db, tt.args.ctx, tt.args.q, tt.args.page, tt.args.pageSize)
fmt.Println(gotR, gotTotal, err) fmt.Println(gotR, gotTotal, err)
gotR, gotTotal, err = paginationToMap[post](tt.args.db, tt.args.ctx, tt.args.q) gotR, gotTotal, err = paginationToMap[post](tt.args.db, tt.args.ctx, tt.args.q, tt.args.page, tt.args.pageSize)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("paginationToMap() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("paginationToMap() error = %v, wantErr %v", err, tt.wantErr)

View File

@ -41,7 +41,7 @@ func chunkFind[T Model](db dbQuery, ctx context.Context, perLimit int, q QueryCo
var offset int var offset int
for { for {
if 1 == i { if 1 == i {
rr, total, err = pagination[T](db, ctx, q) rr, total, err = pagination[T](db, ctx, q, 1, perLimit)
} else { } else {
q.Offset = offset q.Offset = offset
q.Limit = perLimit q.Limit = perLimit
@ -100,7 +100,7 @@ func chunk[T Model, R any](db dbQuery, ctx context.Context, perLimit int, fn fun
var offset int var offset int
for { for {
if 1 == i { if 1 == i {
rr, total, err = pagination[T](db, ctx, q) rr, total, err = pagination[T](db, ctx, q, 1, perLimit)
} else { } else {
q.Offset = offset q.Offset = offset
q.Limit = perLimit q.Limit = perLimit
@ -127,16 +127,16 @@ func chunk[T Model, R any](db dbQuery, ctx context.Context, perLimit int, fn fun
// Pagination 同 // Pagination 同
// //
// Condition 中可使用 Where Fields From Group Having Join Order Page Limit In 函数 // Condition 中可使用 Where Fields From Group Having Join Order Limit In 函数
func Pagination[T Model](ctx context.Context, q QueryCondition) ([]T, int, error) { func Pagination[T Model](ctx context.Context, q QueryCondition, page, pageSize int) ([]T, int, error) {
return pagination[T](globalBb, ctx, q) return pagination[T](globalBb, ctx, q, page, pageSize)
} }
// PaginationFromDB 同 Pagination 方便多个db使用 // PaginationFromDB 同 Pagination 方便多个db使用
// //
// Condition 中可使用 Where Fields Group Having Join Order Page Limit In 函数 // Condition 中可使用 Where Fields Group Having Join Order Limit In 函数
func PaginationFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition) ([]T, int, error) { func PaginationFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition, page, pageSize int) ([]T, int, error) {
return pagination[T](db, ctx, q) return pagination[T](db, ctx, q, page, pageSize)
} }
func Column[V Model, T any](ctx context.Context, fn func(V) (T, bool), q QueryCondition) ([]T, error) { func Column[V Model, T any](ctx context.Context, fn func(V) (T, bool), q QueryCondition) ([]T, error) {

View File

@ -180,6 +180,8 @@ func TestPagination(t *testing.T) {
type args struct { type args struct {
ctx context.Context ctx context.Context
q QueryCondition q QueryCondition
page int
pageSize int
} }
type testCase[T Model] struct { type testCase[T Model] struct {
name string name string
@ -197,10 +199,10 @@ func TestPagination(t *testing.T) {
Where(SqlBuilder{ Where(SqlBuilder{
{"ID", "in", ""}, {"ID", "in", ""},
}), }),
Page(1),
Limit(5),
In([][]any{slice.ToAnySlice(number.Range(431, 440, 1))}...), In([][]any{slice.ToAnySlice(number.Range(431, 440, 1))}...),
), ),
page: 1,
pageSize: 5,
}, },
want: func() (r []post) { want: func() (r []post) {
r, err := Select[post](ctx, "select * from "+post{}.Table()+" where ID in (?,?,?,?,?)", slice.ToAnySlice(number.Range(431, 435, 1))...) r, err := Select[post](ctx, "select * from "+post{}.Table()+" where ID in (?,?,?,?,?)", slice.ToAnySlice(number.Range(431, 435, 1))...)
@ -217,7 +219,7 @@ func TestPagination(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, got1, err := Pagination[post](tt.args.ctx, tt.args.q) got, got1, err := Pagination[post](tt.args.ctx, tt.args.q, tt.args.page, tt.args.pageSize)
if (err != nil) != tt.wantErr { if (err != nil) != tt.wantErr {
t.Errorf("Pagination() error = %v, wantErr %v", err, tt.wantErr) t.Errorf("Pagination() error = %v, wantErr %v", err, tt.wantErr)
return return
@ -333,7 +335,7 @@ func Test_getField(t *testing.T) {
db := glob db := glob
field := "count(*)" field := "count(*)"
q := Conditions() q := Conditions()
wantR := "385" wantR := "406"
wantErr := false wantErr := false
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
gotR, err := getField[options](db, ctx, field, q) gotR, err := getField[options](db, ctx, field, q)