| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- package sql
- import (
- "errors"
- "github.com/iancoleman/strcase"
- "reflect"
- "strings"
- )
- const (
- sqlResultTagPartSeparator = ";"
- sqlResultTagPartKeyValueSeparator = ":"
- )
- const (
- sqlResultTagKey = "sqlresult"
- sqlResultIgnore = "-"
- sqlResultColumn = "column"
- sqlResultParseTime = "parseTime"
- sqlResultAes = "aes"
- )
- type Result struct {
- ColumnMap map[string]ResultColumn
- }
- func ParseSqlResult(e any) (*Result, error) {
- if e == nil {
- return nil, errors.New("没有传递实体")
- }
- entityType := reflect.TypeOf(e)
- if entityType.Kind() == reflect.Ptr {
- entityType = entityType.Elem()
- }
- if entityType.Kind() != reflect.Struct {
- return nil, errors.New("传递的实体不是结构类型")
- }
- entityValue := reflect.ValueOf(e)
- if entityValue.Kind() == reflect.Ptr {
- entityValue = entityValue.Elem()
- }
- sqlResult := new(Result)
- sqlResult.ColumnMap = make(map[string]ResultColumn)
- fieldNum := entityType.NumField()
- for i := 0; i < fieldNum; i++ {
- field := entityType.Field(i)
- fieldValue := entityValue.Field(i)
- column, err := parseSqlResultColumn(field, fieldValue)
- if err != nil {
- return nil, err
- }
- if column == nil {
- continue
- }
- sqlResult.ColumnMap[field.Name] = *column
- }
- return sqlResult, nil
- }
- type ResultColumn struct {
- Name string
- ParseTime string
- AESKey string
- // 原字段的反射结构
- OriginFieldType reflect.Type
- OriginFieldValue reflect.Value
- // 值类型的反射结构
- FieldTypeElem reflect.Type
- FieldValueElem reflect.Value
- }
- func parseSqlResultColumn(field reflect.StructField, fieldValue reflect.Value) (*ResultColumn, error) {
- valueFieldType := field.Type
- valueFieldValue := fieldValue
- if valueFieldType.Kind() == reflect.Ptr {
- valueFieldType = valueFieldType.Elem()
- if !valueFieldValue.IsValid() || valueFieldValue.IsNil() || valueFieldValue.IsZero() {
- valueFieldValue = reflect.Zero(valueFieldType)
- } else {
- valueFieldValue = fieldValue.Elem()
- }
- }
- sqlColumn := &ResultColumn{
- Name: strcase.ToSnake(field.Name),
- ParseTime: "",
- AESKey: "",
- OriginFieldType: field.Type,
- OriginFieldValue: fieldValue,
- FieldTypeElem: valueFieldType,
- FieldValueElem: valueFieldValue,
- }
- sqlResultTag, ok := field.Tag.Lookup(sqlResultTagKey)
- if !ok {
- return sqlColumn, nil
- }
- if sqlResultTag == sqlResultIgnore {
- return nil, nil
- }
- sqlResultParts := strings.Split(sqlResultTag, sqlResultTagPartSeparator)
- if sqlResultParts != nil || len(sqlResultParts) != 0 {
- for _, sqlResultPart := range sqlResultParts {
- sqlPartKeyValue := strings.SplitN(strings.TrimSpace(sqlResultPart), sqlResultTagPartKeyValueSeparator, 2)
- switch sqlPartKeyValue[0] {
- case sqlResultColumn:
- sqlColumn.Name = strings.TrimSpace(sqlPartKeyValue[1])
- case sqlResultParseTime:
- sqlColumn.ParseTime = strings.TrimSpace(sqlPartKeyValue[1])
- case sqlResultAes:
- if len(strings.TrimSpace(sqlPartKeyValue[1])) != 32 {
- return nil, errors.New("AES密钥长度应该为32个字节")
- }
- sqlColumn.AESKey = strings.TrimSpace(sqlPartKeyValue[1])
- default:
- continue
- }
- }
- }
- return sqlColumn, nil
- }
|