func getFields(typ reflect.Type) fields { num := typ.NumField() fs := newFields(num) for i := 0; i < num; i++ { f := typ.Field(i) if f.Anonymous { typ := f.Type if typ.Kind() == reflect.Ptr { typ = typ.Elem() } for _, ff := range getFields(typ).List { ff.index = append(f.Index, ff.index...) fs.Add(ff) } continue } if f.PkgPath != "" && !f.Anonymous { continue } name, opts := parseTag(f.Tag.Get("pg")) if name == "-" { continue } if name == "" { name = pgutil.Underscore(f.Name) } fieldType := indirectType(f.Type) if fieldType.Kind() == reflect.Struct { for _, ff := range getFields(fieldType).List { ff.PGName = name + "." + ff.Name ff.Name = name + "__" + ff.Name ff.index = append(f.Index, ff.index...) fs.Add(ff) } } var flags int8 if opts.Contains("nullempty") { flags |= nullEmpty } field := &field{ Name: name, index: f.Index, flags: flags, appender: getAppender(fieldType), decoder: getDecoder(fieldType), } fs.Add(field) } return fs }
func fields(typ reflect.Type) map[string]*pgValue { num := typ.NumField() dst := make(map[string]*pgValue, num) for i := 0; i < num; i++ { f := typ.Field(i) if f.Anonymous { typ := f.Type if typ.Kind() == reflect.Ptr { typ = typ.Elem() } for name, ff := range fields(typ) { dst[name] = newPGValue(ff.Source, append(f.Index, ff.Index...)) } continue } if f.PkgPath != "" { continue } name, opts := parseTag(f.Tag.Get("pg")) if name == "-" { continue } if name == "" { name = pgutil.Underscore(f.Name) } tt := indirectType(f.Type) if tt.Kind() == reflect.Struct { for subname, ff := range fields(tt) { dst[name+"__"+subname] = newPGValue(ff.Source, append(f.Index, ff.Index...)) } } val := newPGValue(f, f.Index) if opts.Contains("nullempty") { val.NullEmpty = true } dst[name] = val } return dst }