Repository navigation
Expand file tree
/
Copy pathrows_test.go
More file actions
147 lines (136 loc) · 3.26 KB
/
Copy pathrows_test.go
File metadata and controls
147 lines (136 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package dbx
import (
"reflect"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
// resolveColumn simulates the column resolution logic used in ScanStruct and all.
// It tries exact match first, then strips the table alias prefix (first dot) as fallback.
func resolveColumn(dbNameMap map[string]*FieldInfo, col string) (*FieldInfo, bool) {
if fi, ok := dbNameMap[col]; ok {
return fi, true
}
if dotIdx := strings.Index(col, "."); dotIdx >= 0 {
if fi, ok := dbNameMap[col[dotIdx+1:]]; ok {
return fi, true
}
}
return nil, false
}
func TestResolveColumn_StripTablePrefix(t *testing.T) {
type Address struct {
City string `db:"city"`
State string `db:"state"`
}
type Person struct {
Name string `db:"name"`
Email string `db:"email"`
Address Address `db:"address"`
}
si := getStructInfo(reflect.TypeOf(Person{}), nil)
tests := []struct {
name string
col string
wantMatch bool
wantField string
}{
{
name: "exact match without prefix",
col: "name",
wantMatch: true,
wantField: "name",
},
{
name: "table alias prefix stripped",
col: "t.name",
wantMatch: true,
wantField: "name",
},
{
name: "nested struct exact match",
col: "address.city",
wantMatch: true,
wantField: "address.city",
},
{
name: "table alias prefix with nested struct",
col: "src.address.city",
wantMatch: true,
wantField: "address.city",
},
{
name: "unknown column no prefix",
col: "nonexistent",
wantMatch: false,
},
{
name: "unknown column with prefix",
col: "t.nonexistent",
wantMatch: false,
},
{
name: "schema.table.column strips first prefix",
col: "myschema.name",
wantMatch: true,
wantField: "name",
},
{
name: "email exact match",
col: "email",
wantMatch: true,
wantField: "email",
},
{
name: "email with table prefix",
col: "p.email",
wantMatch: true,
wantField: "email",
},
{
name: "nested state with table prefix",
col: "p.address.state",
wantMatch: true,
wantField: "address.state",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fi, ok := resolveColumn(si.dbNameMap, tt.col)
assert.Equal(t, tt.wantMatch, ok, "match result for %q", tt.col)
if tt.wantMatch && ok {
assert.Equal(t, tt.wantField, fi.dbName, "resolved field for %q", tt.col)
}
})
}
}
func TestResolveColumn_CustomFieldMapper(t *testing.T) {
type Product struct {
ID int `db:"pk,id"`
LongName string
ShortDesc string
}
si := getStructInfo(reflect.TypeOf(Product{}), DefaultFieldMapFunc)
// DefaultFieldMapFunc maps "LongName" -> "long_name", "ShortDesc" -> "short_desc"
tests := []struct {
col string
wantMatch bool
wantField string
}{
{"long_name", true, "long_name"},
{"t.long_name", true, "long_name"},
{"short_desc", true, "short_desc"},
{"src.short_desc", true, "short_desc"},
{"id", true, "id"},
{"p.id", true, "id"},
}
for _, tt := range tests {
t.Run(tt.col, func(t *testing.T) {
fi, ok := resolveColumn(si.dbNameMap, tt.col)
assert.Equal(t, tt.wantMatch, ok)
if tt.wantMatch && ok {
assert.Equal(t, tt.wantField, fi.dbName)
}
})
}
}