2023-01-12 12:42:16 +00:00
|
|
|
|
package model
|
2022-11-05 12:59:49 +00:00
|
|
|
|
|
|
|
|
|
import (
|
2022-11-07 08:04:13 +00:00
|
|
|
|
"context"
|
2023-03-19 14:48:23 +00:00
|
|
|
|
"github.com/fthvgb1/wp-go/helper"
|
2023-02-25 15:10:42 +00:00
|
|
|
|
"github.com/fthvgb1/wp-go/helper/number"
|
|
|
|
|
str "github.com/fthvgb1/wp-go/helper/strings"
|
2023-02-04 16:07:10 +00:00
|
|
|
|
"golang.org/x/exp/constraints"
|
2022-11-05 12:59:49 +00:00
|
|
|
|
"math/rand"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
2023-03-05 14:22:54 +00:00
|
|
|
|
type count[T Model] struct {
|
|
|
|
|
t T
|
|
|
|
|
N int `json:"n,omitempty" db:"n" gorm:"n"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c count[T]) PrimaryKey() string {
|
|
|
|
|
return c.t.PrimaryKey()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c count[T]) Table() string {
|
|
|
|
|
return c.t.Table()
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-18 14:27:28 +00:00
|
|
|
|
func pagination[T Model](db dbQuery, ctx context.Context, q *QueryCondition, page, pageSize int) (r []T, total int, err error) {
|
2023-12-08 13:33:09 +00:00
|
|
|
|
if page < 1 {
|
2023-02-26 13:55:03 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
2023-02-27 13:34:48 +00:00
|
|
|
|
q.Limit = pageSize
|
2023-02-25 15:10:42 +00:00
|
|
|
|
qx := QueryCondition{
|
|
|
|
|
Where: q.Where,
|
|
|
|
|
Having: q.Having,
|
|
|
|
|
Join: q.Join,
|
|
|
|
|
In: q.In,
|
|
|
|
|
Group: q.Group,
|
|
|
|
|
From: q.From,
|
2023-03-05 14:22:54 +00:00
|
|
|
|
Fields: "count(*) n",
|
2023-02-25 15:10:42 +00:00
|
|
|
|
}
|
2023-12-03 14:42:44 +00:00
|
|
|
|
if q.Group != "" && q.TotalRow <= 0 {
|
2023-02-25 15:10:42 +00:00
|
|
|
|
qx.Fields = q.Fields
|
2023-05-17 14:22:31 +00:00
|
|
|
|
if qx.From == "" {
|
|
|
|
|
qx.From = Table[T]()
|
|
|
|
|
}
|
2023-05-18 14:27:28 +00:00
|
|
|
|
sq, in, er := BuildQuerySql(&qx)
|
2023-02-25 15:10:42 +00:00
|
|
|
|
qx.In = [][]any{in}
|
|
|
|
|
if er != nil {
|
|
|
|
|
err = er
|
|
|
|
|
return
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
2023-05-21 11:53:37 +00:00
|
|
|
|
qx.From = str.Join("( ", sq, " ) ", "table", number.IntToString(rand.Int()))
|
2023-02-25 15:10:42 +00:00
|
|
|
|
qx = QueryCondition{
|
2023-03-05 14:22:54 +00:00
|
|
|
|
From: qx.From,
|
|
|
|
|
In: qx.In,
|
|
|
|
|
Fields: "count(*) n",
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-12-03 14:42:44 +00:00
|
|
|
|
if q.TotalRow <= 0 {
|
|
|
|
|
n, er := gets[count[T]](db, ctx, &qx)
|
|
|
|
|
total = n.N
|
|
|
|
|
if er != nil || total < 1 {
|
|
|
|
|
err = er
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
total = q.TotalRow
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
2023-12-08 13:33:09 +00:00
|
|
|
|
if q.Limit <= 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
2022-11-05 12:59:49 +00:00
|
|
|
|
offset := 0
|
2023-02-27 13:34:48 +00:00
|
|
|
|
if page > 1 {
|
|
|
|
|
offset = (page - 1) * q.Limit
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
|
|
|
|
if offset >= total {
|
|
|
|
|
return
|
|
|
|
|
}
|
2023-02-25 15:10:42 +00:00
|
|
|
|
q.Offset = offset
|
2023-03-20 05:02:40 +00:00
|
|
|
|
m := helper.GetContextVal[*[]map[string]string](ctx, "handle=>toMap", nil)
|
2023-02-26 14:03:30 +00:00
|
|
|
|
if m == nil {
|
|
|
|
|
r, err = finds[T](db, ctx, q)
|
|
|
|
|
return
|
|
|
|
|
}
|
2023-03-19 14:48:23 +00:00
|
|
|
|
*m, err = findToStringMap[T](db, ctx, q)
|
2023-02-26 13:55:03 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-18 14:27:28 +00:00
|
|
|
|
func paginationToMap[T Model](db dbQuery, ctx context.Context, q *QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
2023-02-27 13:34:48 +00:00
|
|
|
|
ctx = context.WithValue(ctx, "handle=>toMap", &r)
|
|
|
|
|
_, total, err = pagination[T](db, ctx, q, page, pageSize)
|
2023-02-26 13:55:03 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-18 14:27:28 +00:00
|
|
|
|
func PaginationToMap[T Model](ctx context.Context, q *QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
2023-02-27 13:34:48 +00:00
|
|
|
|
return paginationToMap[T](globalBb, ctx, q, page, pageSize)
|
2023-02-26 13:55:03 +00:00
|
|
|
|
}
|
2023-05-18 14:27:28 +00:00
|
|
|
|
func PaginationToMapFromDB[T Model](db dbQuery, ctx context.Context, q *QueryCondition, page, pageSize int) (r []map[string]string, total int, err error) {
|
2023-02-27 13:34:48 +00:00
|
|
|
|
return paginationToMap[T](db, ctx, q, page, pageSize)
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-04 16:07:10 +00:00
|
|
|
|
func FindOneById[T Model, I constraints.Integer](ctx context.Context, id I) (T, error) {
|
2023-05-18 14:27:28 +00:00
|
|
|
|
return gets[T](globalBb, ctx, &QueryCondition{
|
2023-02-25 15:38:12 +00:00
|
|
|
|
Fields: "*",
|
|
|
|
|
Where: SqlBuilder{
|
2023-05-17 14:22:31 +00:00
|
|
|
|
{PrimaryKey[T](), "=", number.IntToString(id), "int"},
|
2023-02-25 15:38:12 +00:00
|
|
|
|
},
|
|
|
|
|
})
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-17 14:22:31 +00:00
|
|
|
|
func FirstOne[T Model](ctx context.Context, where ParseWhere, fields string, order SqlBuilder, in ...[]any) (T, error) {
|
|
|
|
|
return gets[T](globalBb, ctx, Conditions(
|
|
|
|
|
Where(where),
|
|
|
|
|
Fields(fields),
|
|
|
|
|
Order(order),
|
|
|
|
|
In(in...),
|
|
|
|
|
))
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-07 08:04:13 +00:00
|
|
|
|
func LastOne[T Model](ctx context.Context, where ParseWhere, fields string, in ...[]any) (T, error) {
|
2023-02-25 15:38:12 +00:00
|
|
|
|
return gets[T](globalBb, ctx, Conditions(
|
|
|
|
|
Where(where),
|
|
|
|
|
Fields(fields),
|
|
|
|
|
In(in...),
|
|
|
|
|
Order(SqlBuilder{{PrimaryKey[T](), "desc"}}),
|
|
|
|
|
Limit(1),
|
|
|
|
|
))
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-02-21 13:49:59 +00:00
|
|
|
|
func SimpleFind[T Model](ctx context.Context, where ParseWhere, fields string, in ...[]any) (r []T, err error) {
|
2023-05-18 14:27:28 +00:00
|
|
|
|
s, args, err := BuildQuerySql(&QueryCondition{
|
2023-02-25 15:10:42 +00:00
|
|
|
|
Where: where,
|
|
|
|
|
Fields: fields,
|
|
|
|
|
In: in,
|
2023-05-17 14:22:31 +00:00
|
|
|
|
From: Table[T](),
|
2023-02-21 13:49:59 +00:00
|
|
|
|
})
|
2022-11-05 12:59:49 +00:00
|
|
|
|
if err != nil {
|
2023-02-21 13:49:59 +00:00
|
|
|
|
return
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
2023-02-21 13:49:59 +00:00
|
|
|
|
err = globalBb.Select(ctx, &r, s, args...)
|
2022-11-05 12:59:49 +00:00
|
|
|
|
return r, nil
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-25 15:38:12 +00:00
|
|
|
|
// Select 如果查询的为T的表名,可以使用 {table}来代替
|
2022-11-07 08:04:13 +00:00
|
|
|
|
func Select[T Model](ctx context.Context, sql string, params ...any) ([]T, error) {
|
2022-11-05 12:59:49 +00:00
|
|
|
|
var r []T
|
2023-02-25 15:38:12 +00:00
|
|
|
|
sql = strings.Replace(sql, "{table}", Table[T](), -1)
|
2022-11-07 08:04:13 +00:00
|
|
|
|
err := globalBb.Select(ctx, &r, sql, params...)
|
2022-11-05 12:59:49 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return r, err
|
|
|
|
|
}
|
|
|
|
|
return r, nil
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-07 08:04:13 +00:00
|
|
|
|
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) {
|
2023-05-18 14:27:28 +00:00
|
|
|
|
q := &QueryCondition{
|
2023-02-25 15:10:42 +00:00
|
|
|
|
Where: where,
|
|
|
|
|
Fields: fields,
|
|
|
|
|
Group: group,
|
|
|
|
|
Order: order,
|
|
|
|
|
Join: join,
|
|
|
|
|
Having: having,
|
|
|
|
|
Limit: limit,
|
|
|
|
|
In: in,
|
2023-05-17 14:22:31 +00:00
|
|
|
|
From: Table[T](),
|
2023-02-25 15:10:42 +00:00
|
|
|
|
}
|
2023-05-17 14:22:31 +00:00
|
|
|
|
s, args, err := BuildQuerySql(q)
|
2023-02-21 13:49:59 +00:00
|
|
|
|
if err != nil {
|
|
|
|
|
return
|
2022-11-05 12:59:49 +00:00
|
|
|
|
}
|
2023-02-21 13:49:59 +00:00
|
|
|
|
err = globalBb.Select(ctx, &r, s, args...)
|
2022-11-05 12:59:49 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-25 15:38:12 +00:00
|
|
|
|
// Get 可以使用 {table}来替代 T的表名
|
2022-11-07 08:04:13 +00:00
|
|
|
|
func Get[T Model](ctx context.Context, sql string, params ...any) (r T, err error) {
|
2022-11-05 12:59:49 +00:00
|
|
|
|
sql = strings.Replace(sql, "{table}", r.Table(), -1)
|
2022-11-07 08:04:13 +00:00
|
|
|
|
err = globalBb.Get(ctx, &r, sql, params...)
|
2022-11-05 12:59:49 +00:00
|
|
|
|
return
|
|
|
|
|
}
|