mirror of
https://github.com/tangpanqing/aorm.git
synced 2025-10-05 16:06:56 +08:00
228 lines
5.7 KiB
Go
228 lines
5.7 KiB
Go
package builder
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/tangpanqing/aorm/utils"
|
|
"reflect"
|
|
"strings"
|
|
)
|
|
|
|
type GroupItem struct {
|
|
Prefix string
|
|
Field interface{}
|
|
}
|
|
|
|
type WhereItem struct {
|
|
Prefix string
|
|
Field interface{}
|
|
Opt string
|
|
Val interface{}
|
|
}
|
|
|
|
type SelectItem struct {
|
|
FuncName string
|
|
Prefix string
|
|
Field interface{}
|
|
FieldNew interface{}
|
|
}
|
|
|
|
type SelectExpItem struct {
|
|
Builder **Builder
|
|
FieldName interface{}
|
|
}
|
|
|
|
type OrderItem struct {
|
|
Prefix string
|
|
Field interface{}
|
|
OrderType string
|
|
}
|
|
|
|
type LimitItem struct {
|
|
offset int
|
|
pageSize int
|
|
}
|
|
|
|
type JoinItem struct {
|
|
joinType string
|
|
table interface{}
|
|
tableAlias string
|
|
condition []JoinCondition
|
|
}
|
|
|
|
type JoinCondition struct {
|
|
FieldOfCurrentTable interface{}
|
|
Opt string
|
|
FieldOfOtherTable interface{}
|
|
AliasOfOtherTable string
|
|
}
|
|
|
|
//GenWhereItem 产生一个 WhereItem,用作 where 条件里
|
|
func GenWhereItem(field interface{}, opt string, val interface{}, prefix ...string) WhereItem {
|
|
return WhereItem{getPrefixByField(field, prefix...), field, opt, val}
|
|
}
|
|
|
|
//GenHavingItem 产生一个 WhereItem,用作 having 条件里
|
|
func GenHavingItem(field interface{}, opt string, val interface{}) WhereItem {
|
|
return WhereItem{"", field, opt, val}
|
|
}
|
|
|
|
//GenJoinCondition 产生一个 JoinCondition,用作 join 条件里
|
|
func GenJoinCondition(fieldOfCurrentTable interface{}, opt string, fieldOfOtherTable interface{}, aliasOfOtherTable ...string) JoinCondition {
|
|
alias := ""
|
|
if len(aliasOfOtherTable) > 0 {
|
|
alias = aliasOfOtherTable[0]
|
|
}
|
|
|
|
return JoinCondition{
|
|
FieldOfCurrentTable: fieldOfCurrentTable,
|
|
Opt: opt,
|
|
FieldOfOtherTable: fieldOfOtherTable,
|
|
AliasOfOtherTable: alias,
|
|
}
|
|
}
|
|
|
|
//getPrefixByField 获取字段前缀,如果传入则使用传入值,默认使用该字段的表名
|
|
func getPrefixByField(field interface{}, prefix ...string) string {
|
|
str := ""
|
|
if len(prefix) > 0 {
|
|
str = prefix[0]
|
|
} else {
|
|
if field == nil {
|
|
panic("当前field不能是nil")
|
|
}
|
|
|
|
valueOf := reflect.ValueOf(field)
|
|
if reflect.Ptr == valueOf.Kind() {
|
|
fieldPointer := valueOf.Pointer()
|
|
tablePointer := getFieldMap(fieldPointer).TablePointer
|
|
|
|
tableName := getTableMap(tablePointer)
|
|
strArr := strings.Split(tableName, ".")
|
|
str = utils.UnderLine(strArr[len(strArr)-1])
|
|
} else {
|
|
str = fmt.Sprintf("%v", field)
|
|
}
|
|
}
|
|
|
|
return str
|
|
}
|
|
|
|
//getTableNameByTable 根据传入的表信息,获取表名
|
|
func getTableNameByTable(table interface{}) string {
|
|
if table == nil {
|
|
panic("当前table不能是nil")
|
|
}
|
|
|
|
valueOf := reflect.ValueOf(table)
|
|
if reflect.Ptr == valueOf.Kind() {
|
|
tableName := getTableMap(valueOf.Pointer())
|
|
strArr := strings.Split(tableName, ".")
|
|
return utils.UnderLine(strArr[len(strArr)-1])
|
|
} else {
|
|
return fmt.Sprintf("%v", table)
|
|
}
|
|
}
|
|
|
|
//getFieldName 根据传入字段,获取字段名
|
|
func getFieldName(field interface{}) string {
|
|
valueOf := reflect.ValueOf(field)
|
|
if reflect.Ptr == valueOf.Kind() {
|
|
return utils.UnderLine(getFieldMap(reflect.ValueOf(field).Pointer()).Name)
|
|
} else {
|
|
return fmt.Sprintf("%v", field)
|
|
}
|
|
}
|
|
|
|
//反射表名,优先从方法获取,没有方法则从名字获取
|
|
func getTableNameByReflect(typeOf reflect.Type, valueOf reflect.Value) string {
|
|
method, isSet := typeOf.MethodByName("TableName")
|
|
if isSet {
|
|
var paramList []reflect.Value
|
|
paramList = append(paramList, valueOf)
|
|
res := method.Func.Call(paramList)
|
|
return res[0].String()
|
|
} else {
|
|
arr := strings.Split(typeOf.String(), ".")
|
|
return utils.UnderLine(arr[len(arr)-1])
|
|
}
|
|
}
|
|
|
|
//从结构体反射出来的属性名
|
|
func getFieldMapByReflect(destValue reflect.Value, destType reflect.Type) map[string]int {
|
|
fieldNameMap := make(map[string]int)
|
|
for i := 0; i < destValue.NumField(); i++ {
|
|
fieldNameMap[destType.Field(i).Name] = i
|
|
}
|
|
|
|
return fieldNameMap
|
|
}
|
|
|
|
//获取赋值的地址
|
|
func getScansAddr(columnNameList []string, fieldNameMap map[string]int, destValue reflect.Value) []interface{} {
|
|
var scans []interface{}
|
|
for _, columnName := range columnNameList {
|
|
fieldName := utils.CamelString(strings.ToLower(columnName))
|
|
index, ok := fieldNameMap[fieldName]
|
|
if ok {
|
|
scans = append(scans, destValue.Field(index).Addr().Interface())
|
|
} else {
|
|
var emptyVal interface{}
|
|
scans = append(scans, &emptyVal)
|
|
}
|
|
}
|
|
|
|
return scans
|
|
}
|
|
|
|
//产生关联查询条件
|
|
func genJoinConditionStr(aliasOfCurrentTable string, joinCondition []JoinCondition, paramList []interface{}) (string, []interface{}) {
|
|
var sqlList []string
|
|
for i := 0; i < len(joinCondition); i++ {
|
|
fieldNameOfCurrentTable := getFieldName(joinCondition[i].FieldOfCurrentTable)
|
|
if joinCondition[i].Opt == RawEq {
|
|
if aliasOfCurrentTable == "" {
|
|
aliasOfCurrentTable = getPrefixByField(joinCondition[i].FieldOfCurrentTable)
|
|
}
|
|
|
|
aliasOfOtherTable := joinCondition[i].AliasOfOtherTable
|
|
if aliasOfOtherTable == "" {
|
|
aliasOfOtherTable = getPrefixByField(joinCondition[i].FieldOfOtherTable)
|
|
}
|
|
|
|
fieldNameOfOtherTable := getFieldName(joinCondition[i].FieldOfOtherTable)
|
|
sqlList = append(sqlList, aliasOfCurrentTable+"."+fieldNameOfCurrentTable+"="+aliasOfOtherTable+"."+fieldNameOfOtherTable)
|
|
}
|
|
}
|
|
|
|
return strings.Join(sqlList, " AND "), paramList
|
|
}
|
|
|
|
//将一个interface抽取成数组
|
|
func toAnyArr(val any) []any {
|
|
var values []any
|
|
switch val.(type) {
|
|
case []int:
|
|
for _, value := range val.([]int) {
|
|
values = append(values, value)
|
|
}
|
|
case []int64:
|
|
for _, value := range val.([]int64) {
|
|
values = append(values, value)
|
|
}
|
|
case []float32:
|
|
for _, value := range val.([]float32) {
|
|
values = append(values, value)
|
|
}
|
|
case []float64:
|
|
for _, value := range val.([]float64) {
|
|
values = append(values, value)
|
|
}
|
|
case []string:
|
|
for _, value := range val.([]string) {
|
|
values = append(values, value)
|
|
}
|
|
}
|
|
|
|
return values
|
|
}
|