Files
aorm/builder/builder.go
tangpanqing 35a18b5af9 update
2023-01-12 13:11:09 +08:00

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
}