Skip to content

Commit 29f9f5e

Browse files
authored
Merge pull request jmoiron#429 from snigle/reflectx
fix reflectx dominant field
2 parents d5886a9 + d456884 commit 29f9f5e

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

reflectx/reflect.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -429,9 +429,14 @@ QueueLoop:
429429

430430
flds := &StructMap{Index: m, Tree: root, Paths: map[string]*FieldInfo{}, Names: map[string]*FieldInfo{}}
431431
for _, fi := range flds.Index {
432-
flds.Paths[fi.Path] = fi
433-
if fi.Name != "" && !fi.Embedded {
434-
flds.Names[fi.Path] = fi
432+
// check if nothing has already been pushed with the same path
433+
// sometimes you can choose to override a type using embedded struct
434+
fld, ok := flds.Paths[fi.Path]
435+
if !ok || fld.Embedded {
436+
flds.Paths[fi.Path] = fi
437+
if fi.Name != "" && !fi.Embedded {
438+
flds.Names[fi.Path] = fi
439+
}
435440
}
436441
}
437442

reflectx/reflect_test.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,52 @@ func TestBasicEmbeddedWithTags(t *testing.T) {
141141
// }
142142

143143
v := m.FieldByName(zv, "a")
144-
if ival(v) != z.Bar.Foo.A { // the dominant field
145-
t.Errorf("Expecting %d, got %d", z.Bar.Foo.A, ival(v))
144+
if ival(v) != z.A { // the dominant field
145+
t.Errorf("Expecting %d, got %d", z.A, ival(v))
146+
}
147+
v = m.FieldByName(zv, "b")
148+
if ival(v) != z.B {
149+
t.Errorf("Expecting %d, got %d", z.B, ival(v))
150+
}
151+
}
152+
153+
func TestBasicEmbeddedWithSameName(t *testing.T) {
154+
type Foo struct {
155+
A int `db:"a"`
156+
Foo int `db:"Foo"` // Same name as the embedded struct
157+
}
158+
159+
type FooExt struct {
160+
Foo
161+
B int `db:"b"`
162+
}
163+
164+
m := NewMapper("db")
165+
166+
z := FooExt{}
167+
z.A = 1
168+
z.B = 2
169+
z.Foo.Foo = 3
170+
171+
zv := reflect.ValueOf(z)
172+
fields := m.TypeMap(reflect.TypeOf(z))
173+
174+
if len(fields.Index) != 4 {
175+
t.Errorf("Expecting 3 fields, found %d", len(fields.Index))
176+
}
177+
178+
v := m.FieldByName(zv, "a")
179+
if ival(v) != z.A { // the dominant field
180+
t.Errorf("Expecting %d, got %d", z.A, ival(v))
146181
}
147182
v = m.FieldByName(zv, "b")
148183
if ival(v) != z.B {
149184
t.Errorf("Expecting %d, got %d", z.B, ival(v))
150185
}
186+
v = m.FieldByName(zv, "Foo")
187+
if ival(v) != z.Foo.Foo {
188+
t.Errorf("Expecting %d, got %d", z.Foo.Foo, ival(v))
189+
}
151190
}
152191

153192
func TestFlatTags(t *testing.T) {

0 commit comments

Comments
 (0)