wp-go/model/query.go
2023-02-26 21:55:03 +08:00

174 lines
4.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package model
import (
"context"
"github.com/fthvgb1/wp-go/helper/number"
str "github.com/fthvgb1/wp-go/helper/strings"
"golang.org/x/exp/constraints"
"math/rand"
"strings"
)
func pagination[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []T, total int, err error) {
if q.Page < 1 {
return
}
qx := QueryCondition{
Where: q.Where,
Having: q.Having,
Join: q.Join,
In: q.In,
Group: q.Group,
From: q.From,
}
if q.Group != "" {
qx.Fields = q.Fields
sq, in, er := BuildQuerySql[T](qx)
qx.In = [][]any{in}
if er != nil {
err = er
return
}
qx.From = str.Join("( ", sq, " ) ", "table", number.ToString(rand.Int()))
qx = QueryCondition{
From: qx.From,
In: qx.In,
}
}
n, err := GetField[T](ctx, "count(*)", qx)
total = str.ToInt[int](n)
if err != nil || total < 1 {
return
}
offset := 0
if q.Page > 1 {
offset = (q.Page - 1) * q.Limit
}
if offset >= total {
return
}
q.Offset = offset
m := ctx.Value("handle=>")
if m != nil {
mm, ok := m.(string)
if ok && mm == "toMap" {
v := ctx.Value("map")
mx, er := findToStringMap[T](db, ctx, q)
if er != nil {
err = er
return
}
vv := v.(*[]map[string]string)
*vv = mx
return
}
}
r, err = finds[T](db, ctx, q)
return
}
func paginationToMap[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []map[string]string, total int, err error) {
ctx = context.WithValue(ctx, "handle=>", "toMap")
ctx = context.WithValue(ctx, "map", &r)
_, total, err = pagination[T](db, ctx, q)
return
}
func PaginationToMap[T Model](ctx context.Context, q QueryCondition) (r []map[string]string, total int, err error) {
ctx = context.WithValue(ctx, "handle=>", "toMap")
ctx = context.WithValue(ctx, "map", &r)
_, total, err = pagination[T](globalBb, ctx, q)
return
}
func PaginationToMapFromDB[T Model](db dbQuery, ctx context.Context, q QueryCondition) (r []map[string]string, total int, err error) {
ctx = context.WithValue(ctx, "handle=>", "toMap")
ctx = context.WithValue(ctx, "map", &r)
_, total, err = pagination[T](db, ctx, q)
return
}
func FindOneById[T Model, I constraints.Integer](ctx context.Context, id I) (T, error) {
return gets[T](globalBb, ctx, QueryCondition{
Fields: "*",
Where: SqlBuilder{
{PrimaryKey[T](), "=", number.ToString(id), "int"},
},
})
}
func FirstOne[T Model](ctx context.Context, where ParseWhere, fields string, order SqlBuilder, in ...[]any) (r T, err error) {
s, args, err := BuildQuerySql[T](QueryCondition{
Where: where,
Fields: fields,
Order: order,
In: in,
Limit: 1,
})
if err != nil {
return
}
err = globalBb.Get(ctx, &r, s, args...)
return
}
func LastOne[T Model](ctx context.Context, where ParseWhere, fields string, in ...[]any) (T, error) {
return gets[T](globalBb, ctx, Conditions(
Where(where),
Fields(fields),
In(in...),
Order(SqlBuilder{{PrimaryKey[T](), "desc"}}),
Limit(1),
))
}
func SimpleFind[T Model](ctx context.Context, where ParseWhere, fields string, in ...[]any) (r []T, err error) {
s, args, err := BuildQuerySql[T](QueryCondition{
Where: where,
Fields: fields,
In: in,
})
if err != nil {
return
}
err = globalBb.Select(ctx, &r, s, args...)
return r, nil
}
// Select 如果查询的为T的表名可以使用 {table}来代替
func Select[T Model](ctx context.Context, sql string, params ...any) ([]T, error) {
var r []T
sql = strings.Replace(sql, "{table}", Table[T](), -1)
err := globalBb.Select(ctx, &r, sql, params...)
if err != nil {
return r, err
}
return r, nil
}
func Find[T Model](ctx context.Context, where ParseWhere, fields, group string, order SqlBuilder, join SqlBuilder, having SqlBuilder, limit int, in ...[]any) (r []T, err error) {
q := QueryCondition{
Where: where,
Fields: fields,
Group: group,
Order: order,
Join: join,
Having: having,
Limit: limit,
In: in,
}
s, args, err := BuildQuerySql[T](q)
if err != nil {
return
}
err = globalBb.Select(ctx, &r, s, args...)
return
}
// Get 可以使用 {table}来替代 T的表名
func Get[T Model](ctx context.Context, sql string, params ...any) (r T, err error) {
sql = strings.Replace(sql, "{table}", r.Table(), -1)
err = globalBb.Get(ctx, &r, sql, params...)
return
}