mirror of
https://github.com/hanzoai/sqlbuilder.git
synced 2026-10-01 00:37:42 +00:00
fix #65 Struct#InsertInto* methods are aware of omitempty options now
This commit is contained in:
@@ -182,6 +182,7 @@ func (s *Struct) UpdateForTag(table string, tag string, value interface{}) *Upda
|
||||
} else {
|
||||
val = dereferencedValue(val)
|
||||
}
|
||||
|
||||
data := val.Interface()
|
||||
assignments = append(assignments, ub.Assign(quoted[i], data))
|
||||
}
|
||||
@@ -252,23 +253,60 @@ func (s *Struct) buildColsAndValuesForTag(ib *InsertBuilder, tag string, value .
|
||||
if len(vs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
cols := make([]string, 0, len(fields))
|
||||
values := make([][]interface{}, len(vs))
|
||||
nilCols := make([]int, len(fields))
|
||||
|
||||
for _, f := range fields {
|
||||
for idx, f := range fields {
|
||||
cols = append(cols, f)
|
||||
name := sf.fieldAlias[f]
|
||||
shouldOmitempty := false
|
||||
|
||||
if omitEmptyTagMap, ok := sf.omitEmptyFields[f]; ok {
|
||||
if omitEmptyTagMap.containsAny("", tag) {
|
||||
shouldOmitempty = true
|
||||
}
|
||||
}
|
||||
|
||||
for i, v := range vs {
|
||||
data := v.FieldByName(name).Interface()
|
||||
values[i] = append(values[i], data)
|
||||
val := v.FieldByName(name)
|
||||
|
||||
if isEmptyValue(val) && shouldOmitempty {
|
||||
nilCols[idx]++
|
||||
}
|
||||
|
||||
val = dereferencedValue(val)
|
||||
|
||||
if val.IsValid() {
|
||||
values[i] = append(values[i], val.Interface())
|
||||
} else {
|
||||
values[i] = append(values[i], nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cols = s.quoteFields(sf, cols)
|
||||
ib.Cols(cols...)
|
||||
// Try to filter out nil values if possible.
|
||||
filteredCols := make([]string, 0, len(cols))
|
||||
filteredValues := make([][]interface{}, len(values))
|
||||
|
||||
for _, value := range values {
|
||||
for i, cnt := range nilCols {
|
||||
// If all values are nil in a column, ignore the column completedly.
|
||||
if cnt == len(values) {
|
||||
continue
|
||||
}
|
||||
|
||||
filteredCols = append(filteredCols, cols[i])
|
||||
|
||||
for n, value := range values {
|
||||
filteredValues[n] = append(filteredValues[n], value[i])
|
||||
}
|
||||
}
|
||||
|
||||
filteredCols = s.quoteFields(sf, filteredCols)
|
||||
ib.Cols(filteredCols...)
|
||||
|
||||
for _, value := range filteredValues {
|
||||
ib.Values(value...)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,6 +623,7 @@ func TestStructOmitEmptyForMultipleTags(t *testing.T) {
|
||||
|
||||
i := 123
|
||||
b := "bbbb"
|
||||
c := uint16(2)
|
||||
e := true
|
||||
sql2, args2 := st.UpdateForTag("foo", "patch2", &structOmitEmptyForMultipleTags{
|
||||
A: i,
|
||||
@@ -634,6 +635,24 @@ func TestStructOmitEmptyForMultipleTags(t *testing.T) {
|
||||
|
||||
a.Equal(sql2, "UPDATE foo SET `aa` = ?")
|
||||
a.Equal(args2, []interface{}{i})
|
||||
|
||||
value1 := &structOmitEmptyForMultipleTags{
|
||||
A: i,
|
||||
B: &b,
|
||||
C: 0,
|
||||
D: nil,
|
||||
E: false, // should be false value.
|
||||
}
|
||||
value2 := &structOmitEmptyForMultipleTags{
|
||||
A: i,
|
||||
B: &b,
|
||||
C: c, // should not be omitted as C in value1 is not empty.
|
||||
D: nil,
|
||||
E: true,
|
||||
}
|
||||
sql3, args3 := st.InsertIntoForTag("foo", "patch2", value1, value2).Build()
|
||||
a.Equal(sql3, "INSERT INTO foo (`aa`, cc) VALUES (?, ?), (?, ?)")
|
||||
a.Equal(args3, []interface{}{i, uint16(0), i, c})
|
||||
}
|
||||
|
||||
type structWithPointers struct {
|
||||
|
||||
Reference in New Issue
Block a user