91 lines
2.4 KiB
Go
91 lines
2.4 KiB
Go
package reflect
|
|
|
|
import (
|
|
"fmt"
|
|
"reflect"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"git.ma-al.com/goc_daniel/b2b/app/db"
|
|
)
|
|
|
|
// TODO: instead of matching with string.Contains use something less error-prone
|
|
func checkIfContainsJSON(i int, t reflect.Type, name string) string {
|
|
if wholeTag, ok := t.Field(i).Tag.Lookup("json"); ok {
|
|
tags := strings.Split(wholeTag, ",")
|
|
for _, tag := range tags {
|
|
if name == strings.TrimSpace(tag) {
|
|
return db.DB.NamingStrategy.ColumnName(t.Name(), t.Field(i).Name)
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Not tail recursive but should do fine. Goes only as deep as the hierarchy of
|
|
// inlined structs.
|
|
// TODO: improve used internally checkIfContainsJSON
|
|
func GetGormColumnFromJsonField(jsonName string, t reflect.Type) (string, error) {
|
|
var res string
|
|
for i := range make([]bool, t.NumField()) {
|
|
if tag, ok := t.Field(i).Tag.Lookup("json"); ok && strings.Contains(tag, "inline") {
|
|
var err error
|
|
res, err = GetGormColumnFromJsonField(jsonName, t.Field(i).Type)
|
|
if err != nil {
|
|
return "", fmt.Errorf("no field of struct %q has a name %q in its json form", t.Name(), jsonName)
|
|
}
|
|
|
|
} else {
|
|
res = checkIfContainsJSON(i, t, jsonName)
|
|
}
|
|
if res != "" {
|
|
return res, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("no field of struct %q has a name %q in its json form", t.Name(), jsonName)
|
|
}
|
|
|
|
func GetTableName[T any]() string {
|
|
var model T
|
|
typ := reflect.TypeOf(model).Name()
|
|
return db.DB.NamingStrategy.TableName(typ)
|
|
}
|
|
|
|
func GetParamFromFieldTag[T any](object T, fieldname string, tagname string, paramname string) string {
|
|
if table, ok := reflect.TypeOf(object).FieldByName(fieldname); ok {
|
|
if t, ok := table.Tag.Lookup(tagname); ok {
|
|
if paramname == "" {
|
|
return t
|
|
}
|
|
re := regexp.MustCompile(`(?m)` + paramname + `:(\w*)`)
|
|
f := re.FindAllStringSubmatch(t, -1)
|
|
if len(re.FindAllStringSubmatch(t, -1)) > 0 {
|
|
return f[0][1]
|
|
}
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func GetPrimaryKey[T any](item T) string {
|
|
var search func(T) string = func(item T) string {
|
|
val := reflect.ValueOf(item)
|
|
typ := reflect.TypeOf(item)
|
|
for i := 0; i < val.NumField(); i++ {
|
|
if gg, ok := typ.Field(i).Tag.Lookup("gorm"); ok {
|
|
xx := strings.Split(gg, ";")
|
|
for _, t := range xx {
|
|
if strings.HasPrefix(strings.ToLower(t), "primarykey") {
|
|
return db.DB.NamingStrategy.TableName(typ.Field(i).Name)
|
|
}
|
|
}
|
|
}
|
|
if val.Field(i).Type().String() == "db.Model" {
|
|
return db.DB.NamingStrategy.TableName("ID")
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
return search(item)
|
|
}
|