diff --git a/helpers.go b/helpers.go index f59db48b..7efa7294 100644 --- a/helpers.go +++ b/helpers.go @@ -490,9 +490,8 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, args := make([]interface{}, 0, len(table.ColumnsSeq())) for _, col := range table.Columns() { - lColName := strings.ToLower(col.Name) if useCol && !col.IsVersion && !col.IsCreated && !col.IsUpdated { - if _, ok := session.Statement.columnMap[lColName]; !ok { + if _, ok := getFlagForColumn(session.Statement.columnMap, col); !ok { continue } } @@ -528,18 +527,18 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, } if session.Statement.ColumnStr != "" { - if _, ok := session.Statement.columnMap[lColName]; !ok { + if _, ok := getFlagForColumn(session.Statement.columnMap, col); !ok { continue } } if session.Statement.OmitStr != "" { - if _, ok := session.Statement.columnMap[lColName]; ok { + if _, ok := getFlagForColumn(session.Statement.columnMap, col); ok { continue } } // !evalphobia! set fieldValue as nil when column is nullable and zero-value - if _, ok := session.Statement.nullableMap[lColName]; ok { + if _, ok := getFlagForColumn(session.Statement.nullableMap, col); ok { if col.Nullable && isZero(fieldValue.Interface()) { var nilValue *int fieldValue = reflect.ValueOf(nilValue) @@ -578,3 +577,23 @@ func genCols(table *core.Table, session *Session, bean interface{}, useCol bool, func indexName(tableName, idxName string) string { return fmt.Sprintf("IDX_%v_%v", tableName, idxName) } + +func getFlagForColumn(m map[string]bool, col *core.Column) (val bool, has bool) { + + if len(m) == 0 { + return false, false + } + + n := len(col.Name) + + for mk := range m { + if len(mk) != n { + continue + } + if strings.EqualFold(mk, col.Name) { + return m[mk], true + } + } + + return false, false +} diff --git a/session.go b/session.go index 10033313..8f325000 100644 --- a/session.go +++ b/session.go @@ -2318,12 +2318,12 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error continue } if session.Statement.ColumnStr != "" { - if _, ok := session.Statement.columnMap[strings.ToLower(col.Name)]; !ok { + if _, ok := getFlagForColumn(session.Statement.columnMap, col); !ok { continue } } if session.Statement.OmitStr != "" { - if _, ok := session.Statement.columnMap[strings.ToLower(col.Name)]; ok { + if _, ok := getFlagForColumn(session.Statement.columnMap, col); ok { continue } } @@ -2373,12 +2373,12 @@ func (session *Session) innerInsertMulti(rowsSlicePtr interface{}) (int64, error continue } if session.Statement.ColumnStr != "" { - if _, ok := session.Statement.columnMap[strings.ToLower(col.Name)]; !ok { + if _, ok := getFlagForColumn(session.Statement.columnMap, col); !ok { continue } } if session.Statement.OmitStr != "" { - if _, ok := session.Statement.columnMap[strings.ToLower(col.Name)]; ok { + if _, ok := getFlagForColumn(session.Statement.columnMap, col); ok { continue } } diff --git a/statement.go b/statement.go index 07fa14bf..02c9f598 100644 --- a/statement.go +++ b/statement.go @@ -273,9 +273,8 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, requiredField := useAllCols includeNil := useAllCols - lColName := strings.ToLower(col.Name) - if b, ok := mustColumnMap[lColName]; ok { + if b, ok := getFlagForColumn(mustColumnMap, col); ok { if b { requiredField = true } else { @@ -284,7 +283,7 @@ func buildUpdates(engine *Engine, table *core.Table, bean interface{}, } // !evalphobia! set fieldValue as nil when column is nullable and zero-value - if b, ok := nullableMap[lColName]; ok { + if b, ok := getFlagForColumn(nullableMap, col); ok { if b && col.Nullable && isZero(fieldValue.Interface()) { var nilValue *int fieldValue = reflect.ValueOf(nilValue) @@ -533,7 +532,8 @@ func buildConds(engine *Engine, table *core.Table, bean interface{}, fieldType := reflect.TypeOf(fieldValue.Interface()) requiredField := useAllCols - if b, ok := mustColumnMap[strings.ToLower(col.Name)]; ok { + + if b, ok := getFlagForColumn(mustColumnMap, col); ok { if b { requiredField = true } else { @@ -993,7 +993,7 @@ func (statement *Statement) genColumnStr() string { for _, col := range columns { if statement.OmitStr != "" { - if _, ok := statement.columnMap[strings.ToLower(col.Name)]; ok { + if _, ok := getFlagForColumn(statement.columnMap, col); ok { continue } } diff --git a/statement_test.go b/statement_test.go index 3929a76e..91de19bd 100644 --- a/statement_test.go +++ b/statement_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "strings" + "github.com/go-xorm/core" ) @@ -83,6 +85,70 @@ func BenchmarkColumnsStringGeneration(b *testing.B) { } } +func BenchmarkGetFlagForColumnWithICKey_ContainsKey(b *testing.B) { + + b.StopTimer() + + mapCols := make(map[string]bool) + cols := []*core.Column{ + &core.Column{Name: `ID`}, + &core.Column{Name: `IsDeleted`}, + &core.Column{Name: `Caption`}, + &core.Column{Name: `Code1`}, + &core.Column{Name: `Code2`}, + &core.Column{Name: `Code3`}, + &core.Column{Name: `ParentID`}, + &core.Column{Name: `Latitude`}, + &core.Column{Name: `Longitude`}, + } + + for _, col := range cols { + mapCols[strings.ToLower(col.Name)] = true + } + + b.StartTimer() + + for i := 0; i < b.N; i++ { + + for _, col := range cols { + + if _, ok := getFlagForColumn(mapCols, col); !ok { + b.Fatal("Unexpected result") + } + } + } +} + +func BenchmarkGetFlagForColumnWithICKey_EmptyMap(b *testing.B) { + + b.StopTimer() + + mapCols := make(map[string]bool) + cols := []*core.Column{ + &core.Column{Name: `ID`}, + &core.Column{Name: `IsDeleted`}, + &core.Column{Name: `Caption`}, + &core.Column{Name: `Code1`}, + &core.Column{Name: `Code2`}, + &core.Column{Name: `Code3`}, + &core.Column{Name: `ParentID`}, + &core.Column{Name: `Latitude`}, + &core.Column{Name: `Longitude`}, + } + + b.StartTimer() + + for i := 0; i < b.N; i++ { + + for _, col := range cols { + + if _, ok := getFlagForColumn(mapCols, col); ok { + b.Fatal("Unexpected result") + } + } + } +} + type TestType struct { ID int64 `xorm:"ID PK"` IsDeleted bool `xorm:"IsDeleted"`