1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- package rest_gorm
- import (
- "fmt"
- "reflect"
- "strings"
- "git.ali33.ru/fcg-xvii/rest"
- "gorm.io/gorm"
- )
- func Preload(obj any, fields rest.FieldList, q *gorm.DB) (*gorm.DB, error) {
- return preloadPrefix(obj, fields, q, "")
- }
- func preloadPrefix(obj any, fields rest.FieldList, q *gorm.DB, prefix string) (*gorm.DB, error) {
- val := reflect.ValueOf(obj)
- names, err := namesExt(val)
- if err != nil {
- return nil, err
- }
- for _, name := range names {
- if f, check := fields.Field(name.eName); check {
- q = q.Preload(prefix + name.eName)
- if f.IsObject() {
- if q, err = preloadPrefix(name.eValue, f.Names, q, prefix+name.eName+"."); err != nil {
- return nil, err
- }
- }
- }
- }
- return q, nil
- }
- type eExtName struct {
- eName string
- eValue any
- }
- func fElemType(t reflect.Type) reflect.Type {
- switch t.Kind() {
- case reflect.Ptr, reflect.Interface, reflect.Slice:
- return fElemType(t.Elem())
- }
- return t
- }
- func namesExt(val reflect.Value) (res []eExtName, err error) {
- k := val.Kind()
- switch k {
- case reflect.Ptr, reflect.Interface, reflect.Slice:
- return namesExt(val.Elem())
- }
- if k != reflect.Struct {
- return nil, fmt.Errorf("type [ %v ] is not a struct", k)
- }
- t := reflect.TypeOf(val.Interface())
- for i := 0; i < t.NumField(); i++ {
- fType := t.Field(i)
- tag := fType.Tag.Get("rest")
- if len(tag) > 0 && strings.Contains(tag, "ext") {
- rVal := reflect.New(fElemType(fType.Type))
- res = append(
- res,
- eExtName{
- eName: fType.Name,
- eValue: rVal.Interface(),
- },
- )
- }
- }
- return
- }
|