|
|
@@ -1,5 +1,98 @@
|
|
|
package tag
|
|
|
|
|
|
+import (
|
|
|
+ "errors"
|
|
|
+ "github.com/iancoleman/strcase"
|
|
|
+ "reflect"
|
|
|
+ "strings"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ sqlResultTagPartSeparator = ";"
|
|
|
+ sqlResultTagPartKeyValueSeparator = ":"
|
|
|
+)
|
|
|
+
|
|
|
+const (
|
|
|
+ sqlResultTagKey = "sqlresult"
|
|
|
+ sqlResultColumn = "column"
|
|
|
+ sqlResultIgnore = "-"
|
|
|
+ sqlResultCallback = "callback"
|
|
|
+)
|
|
|
+
|
|
|
type SqlResult struct {
|
|
|
- ColumnMap map[string]SqlColumn
|
|
|
+ ColumnMap map[string]SqlResultColumn
|
|
|
+}
|
|
|
+
|
|
|
+func ParseSqlResult(e any) (*SqlResult, 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("传递的不是实体结构")
|
|
|
+ }
|
|
|
+
|
|
|
+ sqlResult := new(SqlResult)
|
|
|
+ sqlResult.ColumnMap = make(map[string]SqlResultColumn)
|
|
|
+
|
|
|
+ fieldNum := entityType.NumField()
|
|
|
+ for i := 0; i < fieldNum; i++ {
|
|
|
+ column, err := parseSqlResultColumn(entityType.Field(i))
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+
|
|
|
+ if column == nil {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ sqlResult.ColumnMap[column.Name] = *column
|
|
|
+ }
|
|
|
+
|
|
|
+ return sqlResult, nil
|
|
|
+}
|
|
|
+
|
|
|
+type SqlResultColumn struct {
|
|
|
+ Name string
|
|
|
+ ResultColumnName string
|
|
|
+ Callback bool
|
|
|
+}
|
|
|
+
|
|
|
+func parseSqlResultColumn(field reflect.StructField) (*SqlResultColumn, error) {
|
|
|
+ sqlColumn := &SqlResultColumn{
|
|
|
+ Name: strcase.ToSnake(field.Name),
|
|
|
+ ResultColumnName: strcase.ToSnake(field.Name),
|
|
|
+ Callback: false,
|
|
|
+ }
|
|
|
+
|
|
|
+ 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.Split(strings.TrimSpace(sqlResultPart), sqlResultTagPartKeyValueSeparator)
|
|
|
+ switch sqlPartKeyValue[0] {
|
|
|
+ case sqlResultColumn:
|
|
|
+ sqlColumn.ResultColumnName = strings.TrimSpace(sqlPartKeyValue[1])
|
|
|
+ case sqlResultCallback:
|
|
|
+ sqlColumn.Callback = true
|
|
|
+ default:
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return sqlColumn, nil
|
|
|
}
|