feat: conditional.go query, production friendly
This commit is contained in:
parent
aeb298635b
commit
4eb10914ab
319
conditional/conditional.go
Normal file
319
conditional/conditional.go
Normal file
@ -0,0 +1,319 @@
|
||||
package conditional
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gorm.io/gorm"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const GeneralSumKey = "#sum"
|
||||
|
||||
var isInjectionReg = regexp.MustCompile("[^a-zA-Z_]+")
|
||||
|
||||
type BaseCondition struct {
|
||||
Page *int `json:"page" form:"page"` // zh: 页码
|
||||
Pagesize *int `json:"pagesize" form:"pagesize"` // zh: 每页大小
|
||||
OrderKey *string `json:"orderKey" form:"orderKey"` // zh: 排序字段名
|
||||
Desc *bool `json:"desc" form:"desc"` // zh: 是否降序
|
||||
}
|
||||
|
||||
type GeneralResult struct {
|
||||
Total int64 `json:"total"`
|
||||
List []map[string]interface{} `json:"list"`
|
||||
Sum map[string]interface{} `json:"sum"`
|
||||
}
|
||||
|
||||
type wrapDB struct {
|
||||
Db *gorm.DB
|
||||
maxPagesize int
|
||||
includeEmptyString int
|
||||
Page *int `json:"page" form:"page"` // zh: 页码
|
||||
Pagesize *int `json:"pagesize" form:"pagesize"` // zh: 每页大小
|
||||
OrderKey *string `json:"orderKey" form:"orderKey"` // zh: 排序字段名
|
||||
Desc *bool `json:"desc" form:"desc"` // zh: 是否降序
|
||||
}
|
||||
|
||||
func camelCaseToUnderscore(s string) string {
|
||||
var output []rune
|
||||
output = append(output, unicode.ToLower(rune(s[0])))
|
||||
for i := 1; i < len(s); i++ {
|
||||
if unicode.IsUpper(rune(s[i])) {
|
||||
output = append(output, '_')
|
||||
}
|
||||
output = append(output, unicode.ToLower(rune(s[i])))
|
||||
}
|
||||
return string(output)
|
||||
}
|
||||
|
||||
func underscoreToUpperCamelCase(s string) string {
|
||||
var output []rune
|
||||
for i, f := 0, false; i < len(s); i++ {
|
||||
if s[i] == '_' {
|
||||
f = true
|
||||
continue
|
||||
}
|
||||
if f {
|
||||
f = false
|
||||
output = append(output, unicode.ToUpper(rune(s[i])))
|
||||
} else {
|
||||
output = append(output, rune(s[i]))
|
||||
}
|
||||
}
|
||||
return string(output)
|
||||
}
|
||||
|
||||
func (w *wrapDB) doOrder() *wrapDB {
|
||||
if w.OrderKey != nil {
|
||||
if orderKey := *w.OrderKey; orderKey != "" && !isInjectionReg.MatchString(orderKey) {
|
||||
if w.Desc != nil && *w.Desc {
|
||||
orderKey += " desc"
|
||||
}
|
||||
w.Db.Order(orderKey)
|
||||
}
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *wrapDB) doPage() *wrapDB {
|
||||
if w.Pagesize == nil || *w.Pagesize > w.maxPagesize {
|
||||
w.Pagesize = &w.maxPagesize
|
||||
}
|
||||
if *w.Pagesize > 0 {
|
||||
w.Db.Limit(*w.Pagesize)
|
||||
}
|
||||
if w.Page != nil {
|
||||
w.Db.Offset(*w.Pagesize * (*w.Page - 1))
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *wrapDB) doWhere(key string, val interface{}) *wrapDB {
|
||||
if len(key) == 0 || strings.HasPrefix(key, "#") {
|
||||
return w
|
||||
}
|
||||
if w.includeEmptyString < 1 {
|
||||
if ref := reflect.ValueOf(val); ref.Kind() == reflect.String && ref.String() == "" {
|
||||
return w
|
||||
}
|
||||
}
|
||||
db := w.Db
|
||||
if key = camelCaseToUnderscore(key); len(key) > 3 {
|
||||
pre := key[:3]
|
||||
switch pre {
|
||||
case "neq":
|
||||
if key[3] == '_' {
|
||||
db.Where(fmt.Sprintf("`%s` <> ?", key[4:]), val)
|
||||
}
|
||||
case "gt_":
|
||||
db.Where(fmt.Sprintf("`%s` >= ?", key[3:]), val)
|
||||
case "lt_":
|
||||
db.Where(fmt.Sprintf("`%s` <= ?", key[3:]), val)
|
||||
case "in_":
|
||||
db.Where(fmt.Sprintf("`%s` in ?", key[3:]), val)
|
||||
case "nin":
|
||||
if key[3] == '_' {
|
||||
db.Where(fmt.Sprintf("`%s` not in ?", key[4:]), val)
|
||||
}
|
||||
case "lik":
|
||||
if strings.HasPrefix(key, "like_") {
|
||||
db.Where(fmt.Sprintf("`%s` like ?", key[5:]), val)
|
||||
}
|
||||
case "nli":
|
||||
if strings.HasPrefix(key, "nlike_") {
|
||||
db.Where(fmt.Sprintf("`%s` not like ?", key[6:]), val)
|
||||
}
|
||||
case "pag":
|
||||
if key == "page" {
|
||||
var page int
|
||||
ref := reflect.ValueOf(val)
|
||||
if ref.CanFloat() {
|
||||
page = int(ref.Float())
|
||||
} else if ref.CanInt() {
|
||||
page = int(ref.Int())
|
||||
} else {
|
||||
page = int(ref.Uint())
|
||||
}
|
||||
w.Page = &page
|
||||
} else if key == "pagesize" || key == "page_size" {
|
||||
var pagesize int
|
||||
ref := reflect.ValueOf(val)
|
||||
if ref.CanFloat() {
|
||||
pagesize = int(ref.Float())
|
||||
} else if ref.CanInt() {
|
||||
pagesize = int(ref.Int())
|
||||
} else {
|
||||
pagesize = int(ref.Uint())
|
||||
}
|
||||
w.Pagesize = &pagesize
|
||||
}
|
||||
case "ord":
|
||||
if key == "order_key" {
|
||||
v := camelCaseToUnderscore(val.(string))
|
||||
if strings.HasPrefix(v, "desc_") {
|
||||
n, b := v[5:], true
|
||||
w.OrderKey, w.Desc = &n, &b
|
||||
} else {
|
||||
var n string
|
||||
if strings.HasPrefix(v, "asc_") {
|
||||
n = v[4:]
|
||||
} else {
|
||||
n = v
|
||||
}
|
||||
w.OrderKey = &n
|
||||
}
|
||||
}
|
||||
case "eq_":
|
||||
db.Where(fmt.Sprintf("`%s` = ?", key[3:]), val)
|
||||
default:
|
||||
db.Where(fmt.Sprintf("`%s` = ?", key), val)
|
||||
}
|
||||
} else {
|
||||
db.Where(fmt.Sprintf("`%s` = ?", key), val)
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func (w *wrapDB) doDeepWhere(k string, v reflect.Value) *wrapDB {
|
||||
kind := v.Kind()
|
||||
switch kind {
|
||||
case reflect.Pointer, reflect.UnsafePointer:
|
||||
if !v.IsNil() {
|
||||
w.doDeepWhere(k, v.Elem())
|
||||
}
|
||||
case reflect.Struct:
|
||||
t, n := v.Type(), v.NumField()
|
||||
for i := 0; i < n; i++ {
|
||||
ki, vi := t.Field(i).Name, v.Field(i)
|
||||
kind = vi.Kind()
|
||||
switch kind {
|
||||
case reflect.Pointer, reflect.UnsafePointer:
|
||||
w.doDeepWhere(ki, vi.Elem())
|
||||
case reflect.Struct, reflect.Map:
|
||||
w.doDeepWhere("", vi)
|
||||
default:
|
||||
w.doWhere(ki, vi.Interface())
|
||||
}
|
||||
}
|
||||
case reflect.Map:
|
||||
if keys := v.MapKeys(); len(keys) > 0 && keys[0].Kind() == reflect.String {
|
||||
for _, key := range keys {
|
||||
w.doWhere(key.String(), v.MapIndex(key).Interface())
|
||||
}
|
||||
}
|
||||
default:
|
||||
w.doWhere(k, v.Interface())
|
||||
}
|
||||
return w
|
||||
}
|
||||
|
||||
func QueryGeneralConditional(db *gorm.DB, search map[string]interface{}, maxPagesize, includeEmptyString int) (gr GeneralResult, err error) {
|
||||
gr = GeneralResult{List: make([]map[string]interface{}, 0), Sum: make(map[string]interface{}), Total: 0}
|
||||
wdb := &wrapDB{Db: db, maxPagesize: maxPagesize, includeEmptyString: includeEmptyString}
|
||||
for key, val := range search {
|
||||
wdb.doWhere(key, val)
|
||||
}
|
||||
if err = wdb.Db.Count(&gr.Total).Error; err != nil {
|
||||
return
|
||||
}
|
||||
if gr.Total > 0 {
|
||||
wdb.doOrder().doPage()
|
||||
if err = wdb.Db.Scan(&gr.List).Error; err != nil {
|
||||
return
|
||||
}
|
||||
// [Optional] Underscore field name to UpperCamelCase
|
||||
if len(gr.List) > 0 {
|
||||
list := make([]map[string]interface{}, 0)
|
||||
for _, m := range gr.List {
|
||||
nm := make(map[string]interface{})
|
||||
for k, v := range m {
|
||||
nm[underscoreToUpperCamelCase(k)] = v
|
||||
}
|
||||
list = append(list, nm)
|
||||
}
|
||||
gr.List = list
|
||||
}
|
||||
// page-1 can do sum only
|
||||
if wdb.Page != nil && *wdb.Page == 1 {
|
||||
var sumFields []string
|
||||
if sumKeys := search[GeneralSumKey]; sumKeys != nil {
|
||||
for _, sumKey := range sumKeys.([]string) {
|
||||
if isInjectionReg.MatchString(sumKey) {
|
||||
err = fmt.Errorf("Ilegal sumKey: %s ", sumKey)
|
||||
return
|
||||
}
|
||||
sumFields = append(sumFields, camelCaseToUnderscore(sumKey))
|
||||
}
|
||||
}
|
||||
if len(sumFields) > 0 {
|
||||
var sb strings.Builder
|
||||
for _, field := range sumFields {
|
||||
sb.Write([]byte(fmt.Sprintf("sum(`%s`) as `%s`, ", field, field)))
|
||||
}
|
||||
if sb.Len() > 16 {
|
||||
if err = db.Select(sb.String()[:sb.Len()-2]).Scan(gr.Sum).Error; err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func QueryStructConditional(db *gorm.DB, search interface{}, list interface{}, sum interface{}, total *int64, maxPagesize, includeEmptyString int) (err error) {
|
||||
wdb := &wrapDB{Db: db, maxPagesize: maxPagesize, includeEmptyString: includeEmptyString}
|
||||
if search != nil {
|
||||
wdb.doDeepWhere("", reflect.ValueOf(search))
|
||||
}
|
||||
if total != nil {
|
||||
if err = wdb.Db.Count(total).Error; err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if *total > 0 {
|
||||
wdb.doOrder().doPage()
|
||||
if list != nil {
|
||||
if err = wdb.Db.Scan(list).Error; err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
// page-1 can do sum only
|
||||
if wdb.Page != nil && *wdb.Page == 1 && sum != nil {
|
||||
sv := reflect.ValueOf(sum)
|
||||
sk := sv.Kind()
|
||||
switch sk {
|
||||
case reflect.Pointer, reflect.UnsafePointer:
|
||||
sv = reflect.ValueOf(sv.Elem().Interface())
|
||||
sk = sv.Kind()
|
||||
if sk == reflect.Struct {
|
||||
if t, n := sv.Type(), sv.NumField(); n > 0 {
|
||||
var sb strings.Builder
|
||||
for i := 0; i < n; i++ {
|
||||
ns := camelCaseToUnderscore(t.Field(i).Name)
|
||||
sb.Write([]byte(fmt.Sprintf("sum(`%s`) as `%s`, ", ns, ns)))
|
||||
}
|
||||
if sb.Len() > 0 {
|
||||
db.Select(sb.String()[:sb.Len()-2]).Scan(sum)
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("[SUM] Unknow: %s , only pointer allowed", sum)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if list != nil {
|
||||
// set empty array
|
||||
s := (*reflect.SliceHeader)(reflect.ValueOf(list).UnsafePointer())
|
||||
if s.Data == 0 {
|
||||
e := make([]interface{}, 0)
|
||||
s.Data = (uintptr)(unsafe.Pointer(&e))
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
200
conditional/conditional_gen_test.go
Normal file
200
conditional/conditional_gen_test.go
Normal file
@ -0,0 +1,200 @@
|
||||
package conditional
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func initDB() *gorm.DB {
|
||||
db, err := gorm.Open(mysql.Open("root:root@tcp(127.0.0.1:3306)/gorm_test?charset=utf8mb4&parseTime=True&loc=Local"), &gorm.Config{Logger: logger.Default.LogMode(logger.Info)})
|
||||
if err != nil {
|
||||
panic("failed to connect database")
|
||||
}
|
||||
// `id` INT unsigned NOT NULL AUTO_INCREMENT COMMENT 'user ID',
|
||||
// `name` VARCHAR(64) NOT NULL COMMENT '钱包地址',
|
||||
// `level` INT unsigned NOT NULL COMMENT '用户等级',
|
||||
// `status` int unsigned NOT NULL DEFAULT '0' COMMENT '结算状态 0: 正常 20禁用',
|
||||
// `created_at` bigint NOT NULL COMMENT '创建时间 毫秒',
|
||||
// `updated_at` bigint NOT NULL COMMENT '更新时间 毫秒',
|
||||
db = db.Table("user")
|
||||
return db
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalNeq(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["neqId"] = uint(1)
|
||||
search["neq_id"] = uint(1)
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalEq(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["id"] = uint(1)
|
||||
search["eq_id"] = uint(1)
|
||||
search["eqId"] = uint(1)
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalLt(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["ltId"] = uint(2)
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalGt(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["gtId"] = uint(2)
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalIn(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
in := make([]uint, 0)
|
||||
in = append(in, 1)
|
||||
in = append(in, 2)
|
||||
in = append(in, 3)
|
||||
search["inId"] = in
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalNin(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
in := make([]uint, 0)
|
||||
in = append(in, 1)
|
||||
in = append(in, 2)
|
||||
in = append(in, 3)
|
||||
search["ninId"] = in
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalLike(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["likeName"] = "_oo"
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalNlike(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["likeName"] = "f%"
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalPage(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["page"] = 2
|
||||
search["pagesize"] = 2
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalOrder(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
//search["orderKey"] = "descId"
|
||||
search["orderKey"] = "Id"
|
||||
search["orderKey"] = "ascId"
|
||||
//search["orderKey"] = "descId or 1"
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 2, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalPage1Sum(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["page"] = 1
|
||||
search[GeneralSumKey] = []string{"level"}
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 2, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalNotAllowEmptyString(t *testing.T) {
|
||||
search := make(map[string]interface{})
|
||||
search["likeName"] = ""
|
||||
gr, err := QueryGeneralConditional(initDB(), search, 2, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
search["likeName"] = "f%"
|
||||
gr, err = QueryGeneralConditional(initDB(), search, 2, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ = json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
||||
|
||||
func TestQueryGeneralConditionalMaxCount(t *testing.T) {
|
||||
// [unsafe] Unrestricted mode : <=0
|
||||
search := make(map[string]interface{})
|
||||
gr, err := QueryGeneralConditional(initDB(), search, -1, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ := json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
|
||||
// [safe] > 0
|
||||
search = make(map[string]interface{})
|
||||
gr, err = QueryGeneralConditional(initDB(), search, 1, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
marshal, _ = json.Marshal(gr)
|
||||
log.Println(string(marshal))
|
||||
}
|
178
conditional/conditional_struct_test.go
Normal file
178
conditional/conditional_struct_test.go
Normal file
@ -0,0 +1,178 @@
|
||||
package conditional
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Level uint `json:"level"`
|
||||
Status uint `json:"status"`
|
||||
CreatedAt uint `json:"createdAt"`
|
||||
UpdatedAt uint `json:"updatedAt"`
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalNeq(t *testing.T) {
|
||||
search := struct {
|
||||
NeqId uint
|
||||
}{NeqId: 1}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalEq(t *testing.T) {
|
||||
//search := struct {
|
||||
// Id uint
|
||||
//}{Id: 1}
|
||||
search := struct {
|
||||
EqId uint
|
||||
}{EqId: 1}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalLt(t *testing.T) {
|
||||
search := struct {
|
||||
LtId uint
|
||||
}{LtId: 1}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalGt(t *testing.T) {
|
||||
search := struct {
|
||||
GtId uint
|
||||
}{GtId: 1}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalIn(t *testing.T) {
|
||||
search := struct {
|
||||
InId []uint
|
||||
}{InId: []uint{1, 2}}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalNin(t *testing.T) {
|
||||
search := struct {
|
||||
NinId []uint
|
||||
}{NinId: []uint{1, 2}}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalLike(t *testing.T) {
|
||||
search := struct {
|
||||
LikeName string
|
||||
}{LikeName: "f%"}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalNlike(t *testing.T) {
|
||||
search := struct {
|
||||
NlikeName string
|
||||
}{NlikeName: "f%"}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalPage(t *testing.T) {
|
||||
search := struct {
|
||||
Page int
|
||||
Pagesize int
|
||||
}{Page: 2, Pagesize: 2}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalOrder(t *testing.T) {
|
||||
search := struct {
|
||||
OrderKey string
|
||||
}{OrderKey: "descId"}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalPage1Sum(t *testing.T) {
|
||||
search := struct {
|
||||
Page int
|
||||
}{Page: 1}
|
||||
sum := new(struct {
|
||||
Level uint
|
||||
})
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, sum, total, 10, 1)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(sum, list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalNotAllowEmptyString(t *testing.T) {
|
||||
search := struct {
|
||||
Name string
|
||||
}{Name: ""}
|
||||
//search := struct {
|
||||
// Name string
|
||||
//}{Name: "foo"}
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), search, list, nil, total, 10, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
||||
|
||||
func TestQueryStructConditionalMaxCount(t *testing.T) {
|
||||
list, total := new([]User), new(int64)
|
||||
err := QueryStructConditional(initDB(), nil, list, nil, total, 2, 0)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
log.Println(list, *total)
|
||||
}
|
25
conditional/example.sql
Normal file
25
conditional/example.sql
Normal file
@ -0,0 +1,25 @@
|
||||
CREATE SCHEMA IF NOT EXISTS gorm_test;
|
||||
USE gorm_test;
|
||||
|
||||
DROP TABLE IF EXISTS `user`;
|
||||
CREATE TABLE IF NOT EXISTS `user`
|
||||
(
|
||||
`id` INT unsigned NOT NULL AUTO_INCREMENT COMMENT 'user ID',
|
||||
`name` VARCHAR(64) NOT NULL COMMENT '钱包地址',
|
||||
`level` INT unsigned NOT NULL COMMENT '用户等级',
|
||||
`status` int unsigned NOT NULL DEFAULT '0' COMMENT '结算状态 0: 正常 20禁用',
|
||||
`created_at` bigint NOT NULL COMMENT '创建时间 毫秒',
|
||||
`updated_at` bigint NOT NULL COMMENT '更新时间 毫秒',
|
||||
PRIMARY KEY (`id`),
|
||||
key key_created_at (created_at)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb3 COMMENT ='user';
|
||||
|
||||
INSERT INTO gorm_test.user (name, level, status, created_at, updated_at)
|
||||
VALUES
|
||||
('Boo', 1, 1, 1682597017126, 1682597017126),
|
||||
('Foo', 2, 2, 1682697017126, 1682697017126),
|
||||
('Hoo', 3, 3, 1682797017126, 1682797017126),
|
||||
('Ioo', 4, 4, 1682897017126, 1682897017126),
|
||||
('Joo', 5, 5, 1682997017126, 1682997017126),
|
||||
('Koo', 6, 6, 1683097017126, 1683097017126);
|
Loading…
x
Reference in New Issue
Block a user