561 lines
13 KiB
Go
561 lines
13 KiB
Go
// Package database ...
|
|
//
|
|
// Description : mysql ...
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 2022-05-15 11:43
|
|
package database
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"git.zhangdeman.cn/zhangdeman/consts"
|
|
"git.zhangdeman.cn/zhangdeman/database/define"
|
|
"git.zhangdeman.cn/zhangdeman/op_type"
|
|
"git.zhangdeman.cn/zhangdeman/serialize"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
// WithModel ...
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 15:18 2024/1/15
|
|
func WithModel(model any) define.SetOption {
|
|
return func(o *define.Option) {
|
|
o.Model = model
|
|
}
|
|
}
|
|
|
|
// WithTable 设置查询的表名
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 20:56 2023/3/22
|
|
func WithTable(tableName string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
o.Table = tableName
|
|
}
|
|
}
|
|
|
|
// WithWhere 设置where条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 12:17 2022/5/15
|
|
func WithWhere[T op_type.BaseType](where map[string]T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Where {
|
|
o.Where = make(map[string]any)
|
|
}
|
|
for field, value := range where {
|
|
o.Where[field] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithLimit 设置limit条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 12:00 2022/5/15
|
|
func WithLimit[T op_type.Int](limit T, offset T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
o.Limit = int(limit)
|
|
o.Offset = int(offset)
|
|
}
|
|
}
|
|
|
|
// WithLimitByPageAndSize 通过page和size构建条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 21:42 2023/10/14
|
|
func WithLimitByPageAndSize[T op_type.Int](page T, size T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if size > 0 {
|
|
o.Limit = int(size)
|
|
}
|
|
if page <= 0 {
|
|
page = 1
|
|
}
|
|
o.Offset = int((page - 1) * size)
|
|
}
|
|
}
|
|
|
|
// WithIn 设置in条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 12:23 2022/5/15
|
|
func WithIn[T op_type.Array](field string, value T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == value {
|
|
return
|
|
}
|
|
if len(value) == 0 {
|
|
return
|
|
}
|
|
if nil == o.In {
|
|
o.In = make(map[string]any)
|
|
}
|
|
o.In[field] = value
|
|
}
|
|
}
|
|
|
|
// WithBatchIn ...
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 12:24 2022/5/15
|
|
func WithBatchIn[T op_type.Array](batchIn map[string]T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.In {
|
|
o.In = make(map[string]any)
|
|
}
|
|
for field, value := range batchIn {
|
|
WithIn(field, value)
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithNotIn 设置 notin 条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 16:18 2022/5/15
|
|
func WithNotIn[T op_type.Array](field string, value T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.NotIn {
|
|
o.NotIn = make(map[string]any)
|
|
}
|
|
if value == nil || len(value) == 0 {
|
|
return
|
|
}
|
|
o.NotIn[field] = value
|
|
}
|
|
}
|
|
|
|
// WithBatchNotIn 批量设置 NOT IN
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 16:23 2022/5/15
|
|
func WithBatchNotIn[T op_type.Array](data map[string]T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.NotIn {
|
|
o.NotIn = make(map[string]any)
|
|
}
|
|
for field, value := range data {
|
|
if value == nil || len(value) == 0 {
|
|
continue
|
|
}
|
|
o.NotIn[field] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithStart >= 条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:01 2022/5/15
|
|
func WithStart(field string, value any) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Start {
|
|
o.Start = make(map[string]any)
|
|
}
|
|
o.Start[field] = value
|
|
}
|
|
}
|
|
|
|
// WithBatchStart 批量设置起始条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:03 2022/5/15
|
|
func WithBatchStart(data map[string]any) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Start {
|
|
o.Start = make(map[string]any)
|
|
}
|
|
for field, value := range data {
|
|
o.Start[field] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithEnd 设置 < 条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:07 2022/5/15
|
|
func WithEnd(field string, value any) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.End {
|
|
o.End = make(map[string]any)
|
|
}
|
|
o.End[field] = value
|
|
}
|
|
}
|
|
|
|
// WithBatchEnd 批量设置 < 条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:10 2022/5/15
|
|
func WithBatchEnd(data map[string]any) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.End {
|
|
o.End = make(map[string]any)
|
|
}
|
|
for field, value := range data {
|
|
o.End[field] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithLike 设置 like 查询条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:16 2022/5/15
|
|
func WithLike(field string, value string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Like {
|
|
o.Like = make(map[string]string)
|
|
}
|
|
if len(value) == 0 {
|
|
return
|
|
}
|
|
o.Like[field] = value
|
|
}
|
|
}
|
|
|
|
// WithBatchLike 批量设置like条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:19 2022/5/15
|
|
func WithBatchLike(data map[string]string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Like {
|
|
o.Like = make(map[string]string)
|
|
}
|
|
for field, value := range data {
|
|
if len(value) == 0 {
|
|
continue
|
|
}
|
|
o.Like[field] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithNotLike NOT LIKE 语句
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:50 2022/5/15
|
|
func WithNotLike(field string, value string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.NotLike {
|
|
o.NotLike = make(map[string]string)
|
|
}
|
|
if len(value) == 0 {
|
|
return
|
|
}
|
|
o.NotLike[field] = value
|
|
}
|
|
}
|
|
|
|
// WithBatchNotLike ...
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:52 2022/5/15
|
|
func WithBatchNotLike(data map[string]string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.NotLike {
|
|
o.NotLike = make(map[string]string)
|
|
}
|
|
for field, value := range data {
|
|
if len(value) == 0 {
|
|
continue
|
|
}
|
|
o.NotLike[field] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithNotEqual 设置不等于语句
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:31 2022/5/15
|
|
func WithNotEqual[T op_type.BaseType](field string, value T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.NotEqual {
|
|
o.NotEqual = make(map[string]any)
|
|
}
|
|
o.NotEqual[field] = value
|
|
}
|
|
}
|
|
|
|
// WithBatchNotEqual 批量设置不等于条件
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:33 2022/5/15
|
|
func WithBatchNotEqual[T op_type.BaseType](data map[string]T) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.NotEqual {
|
|
o.NotEqual = make(map[string]any)
|
|
}
|
|
for field, value := range data {
|
|
o.NotEqual[field] = value
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithOR 设置OR语句
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 20:03 2022/7/23
|
|
func WithOR(orConditionList ...define.SetOption) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.OR {
|
|
o.OR = make([][]define.SetOption, 0)
|
|
}
|
|
o.OR = append(o.OR, orConditionList)
|
|
}
|
|
}
|
|
|
|
// WithOrder 设置排序规则
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 20:15 2022/10/20
|
|
func WithOrder(orderRuleList ...string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
o.Order = orderRuleList
|
|
}
|
|
}
|
|
|
|
// WithOrderDesc 降序排序
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 15:09 2023/4/3
|
|
func WithOrderDesc(field string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Order {
|
|
o.Order = make([]string, 0)
|
|
}
|
|
o.Order = append(o.Order, field+" desc")
|
|
}
|
|
}
|
|
|
|
// WithOrderAsc 升序排序
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 15:09 2023/4/3
|
|
func WithOrderAsc(field string) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Order {
|
|
o.Order = make([]string, 0)
|
|
}
|
|
o.Order = append(o.Order, field+" asc")
|
|
}
|
|
}
|
|
|
|
// newOption 生成新的option
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:46 2024/8/9
|
|
func newOption(setOptionList ...define.SetOption) *define.Option {
|
|
o := &define.Option{}
|
|
for _, item := range setOptionList {
|
|
item(o)
|
|
}
|
|
return o
|
|
}
|
|
|
|
// optionToSql 基于 option 配置生成sql
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 17:46 2024/8/9
|
|
func optionToSql(o *define.Option) (sqlBuildResult string, bindValue []any) {
|
|
bindValue = make([]any, 0)
|
|
sqlBuildResultBlockList := make([]string, 0)
|
|
// 设置where条件
|
|
for fieldName, fieldValue := range o.Where {
|
|
if nil == fieldValue {
|
|
continue
|
|
}
|
|
if reflect.TypeOf(fieldValue).Kind() == reflect.Slice {
|
|
// 传入数组, in语句
|
|
placeholder, dataList := parseInSql(fieldValue)
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` IN ("+placeholder+")")
|
|
bindValue = append(bindValue, dataList...)
|
|
} else {
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` = ?")
|
|
bindValue = append(bindValue, fieldValue)
|
|
}
|
|
}
|
|
// 设置不等于
|
|
for fieldName, fieldValue := range o.NotEqual {
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` != ?")
|
|
bindValue = append(bindValue, fieldValue)
|
|
}
|
|
|
|
// in 语句
|
|
// 传入数组, in语句
|
|
for fieldName, fieldValue := range o.In {
|
|
placeholder, dataList := parseInSql(fieldValue)
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` IN ("+placeholder+")")
|
|
bindValue = append(bindValue, dataList...)
|
|
}
|
|
|
|
// not in 语句
|
|
for fieldName, fieldValue := range o.NotIn {
|
|
placeholder, dataList := parseInSql(fieldValue)
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` NOT IN ("+placeholder+")")
|
|
bindValue = append(bindValue, dataList...)
|
|
}
|
|
|
|
// like 语句
|
|
for fieldName, fieldValue := range o.Like {
|
|
if len(fieldValue) == 0 {
|
|
continue
|
|
}
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` LIKE \"%?%\"")
|
|
bindValue = append(bindValue, fieldValue)
|
|
}
|
|
|
|
// NOT LIKE 语句
|
|
for fieldName, fieldValue := range o.NotLike {
|
|
if len(fieldValue) == 0 {
|
|
continue
|
|
}
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` NOT LIKE \"%?%\"")
|
|
bindValue = append(bindValue, fieldValue)
|
|
}
|
|
|
|
// >=
|
|
for fieldName, fieldValue := range o.Start {
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` >= ?")
|
|
bindValue = append(bindValue, fieldValue)
|
|
}
|
|
|
|
// <
|
|
for fieldName, fieldValue := range o.End {
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+fieldName+"` < ?")
|
|
bindValue = append(bindValue, fieldValue)
|
|
}
|
|
|
|
// between
|
|
for field, betweenVal := range o.Between {
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+field+"` BETWEEN ? AND ?")
|
|
bindValue = append(bindValue, betweenVal[0], betweenVal[1])
|
|
}
|
|
// not between
|
|
for field, notBetweenVal := range o.NotBetween {
|
|
sqlBuildResultBlockList = append(sqlBuildResultBlockList, "`"+field+"` NOT BETWEEN ? AND ?")
|
|
bindValue = append(bindValue, notBetweenVal[0], notBetweenVal[1])
|
|
}
|
|
|
|
if len(bindValue) > 0 {
|
|
sqlBuildResult = strings.Join(sqlBuildResultBlockList, " AND ")
|
|
}
|
|
return
|
|
}
|
|
|
|
// parseInSql 解析in语句需要绑定占位符以及数据
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 22:07 2024/8/9
|
|
func parseInSql(fieldValue any) (string, []any) {
|
|
byteData, _ := json.Marshal(fieldValue)
|
|
var dataList []any
|
|
decoder := json.NewDecoder(strings.NewReader(string(byteData)))
|
|
decoder.UseNumber()
|
|
_ = decoder.Decode(&dataList)
|
|
// 生成占位符
|
|
placeholderList := make([]string, 0)
|
|
for i := 0; i < len(dataList); i++ {
|
|
placeholderList = append(placeholderList, "?")
|
|
}
|
|
return strings.Join(placeholderList, ","), dataList
|
|
}
|
|
|
|
// WithBetween between 语句
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 15:52 2024/8/23
|
|
func WithBetween(field string, left any, right any) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.Between {
|
|
o.Between = map[string][2]any{}
|
|
}
|
|
o.Between[field] = [2]any{left, right}
|
|
}
|
|
}
|
|
|
|
// WithNotBetween not between 语句
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 15:52 2024/8/23
|
|
func WithNotBetween(field string, left any, right any) define.SetOption {
|
|
return func(o *define.Option) {
|
|
if nil == o.NotBetween {
|
|
o.NotBetween = map[string][2]any{}
|
|
}
|
|
o.NotBetween[field] = [2]any{left, right}
|
|
}
|
|
}
|
|
|
|
// WithAnyCondition 设置任意查询条件, 仅 where 子句 in / not in / like / not like / == / !=
|
|
//
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
//
|
|
// Date : 14:48 2024/8/23
|
|
func WithAnyCondition(column string, operate string, value any) (define.SetOption, error) {
|
|
if nil == value {
|
|
return nil, errors.New("value is nil")
|
|
}
|
|
switch operate {
|
|
case consts.WhereOperateEqual:
|
|
return WithWhere(map[string]any{column: value}), nil
|
|
case consts.WhereOperateNotEqual:
|
|
return WithNotEqual(column, value), nil
|
|
case consts.WhereOperateIn:
|
|
var target []any
|
|
if err := serialize.JSON.Transition(value, &target); nil != err {
|
|
return nil, err
|
|
}
|
|
return WithIn[[]any](column, target), nil
|
|
case consts.WhereOperateNotIn:
|
|
var target []any
|
|
if err := serialize.JSON.Transition(value, &target); nil != err {
|
|
return nil, err
|
|
}
|
|
return WithNotIn[[]any](column, target), nil
|
|
case consts.WhereOperateLike:
|
|
return WithLike(column, fmt.Sprintf("%v", value)), nil
|
|
case consts.WhereOperateNotLike:
|
|
return WithNotLike(column, fmt.Sprintf("%v", value)), nil
|
|
default:
|
|
return nil, errors.New(operate + " : operate is not support")
|
|
}
|
|
}
|