Optimize reflect value length and method (#4280)

* Respect ignore migration when add column (#4276)

continue https://github.com/go-gorm/gorm/pull/4028

* feat: Optimal value type acquisition for v (#4278)

* feat: optimize relect value length and value

* feat: optimize ConvertSliceOfMapToValuesForCreate method

Co-authored-by: yrong1997 <yrong1997@gmail.com>
This commit is contained in:
heige 2021-04-14 13:00:54 +08:00 committed by GitHub
parent 5555b010dc
commit 74e7a9ca07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 12 deletions

View File

@ -288,12 +288,13 @@ func SaveAfterAssociations(create bool) func(db *gorm.DB) {
appendToElems(db.Statement.ReflectValue) appendToElems(db.Statement.ReflectValue)
} }
if elems.Len() > 0 { // optimize elems of reflect value length
if elemLen := elems.Len(); elemLen > 0 {
if v, ok := selectColumns[rel.Name+".*"]; !ok || v { if v, ok := selectColumns[rel.Name+".*"]; !ok || v {
saveAssociations(db, rel, elems.Interface(), selectColumns, restricted, nil) saveAssociations(db, rel, elems.Interface(), selectColumns, restricted, nil)
} }
for i := 0; i < elems.Len(); i++ { for i := 0; i < elemLen; i++ {
appendToJoins(objs[i], elems.Index(i)) appendToJoins(objs[i], elems.Index(i))
} }
} }

View File

@ -42,15 +42,20 @@ func ConvertMapToValuesForCreate(stmt *gorm.Statement, mapValue map[string]inter
func ConvertSliceOfMapToValuesForCreate(stmt *gorm.Statement, mapValues []map[string]interface{}) (values clause.Values) { func ConvertSliceOfMapToValuesForCreate(stmt *gorm.Statement, mapValues []map[string]interface{}) (values clause.Values) {
var ( var (
columns = make([]string, 0, len(mapValues)) columns = make([]string, 0, len(mapValues))
result = map[string][]interface{}{}
selectColumns, restricted = stmt.SelectAndOmitColumns(true, false)
) )
// when the length of mapValues,return directly here
// no need to call stmt.SelectAndOmitColumns method
if len(mapValues) == 0 { if len(mapValues) == 0 {
stmt.AddError(gorm.ErrEmptySlice) stmt.AddError(gorm.ErrEmptySlice)
return return
} }
var (
result = make(map[string][]interface{}, len(mapValues))
selectColumns, restricted = stmt.SelectAndOmitColumns(true, false)
)
for idx, mapValue := range mapValues { for idx, mapValue := range mapValues {
for k, v := range mapValue { for k, v := range mapValue {
if stmt.Schema != nil { if stmt.Schema != nil {

View File

@ -71,10 +71,10 @@ func GetRelationsValues(reflectValue reflect.Value, rels []*Relationship) (refle
reflectResults = reflect.Append(reflectResults, result.Addr()) reflectResults = reflect.Append(reflectResults, result.Addr())
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
for i := 0; i < result.Len(); i++ { for i := 0; i < result.Len(); i++ {
if result.Index(i).Kind() == reflect.Ptr { if elem := result.Index(i); elem.Kind() == reflect.Ptr {
reflectResults = reflect.Append(reflectResults, result.Index(i)) reflectResults = reflect.Append(reflectResults, elem)
} else { } else {
reflectResults = reflect.Append(reflectResults, result.Index(i).Addr()) reflectResults = reflect.Append(reflectResults, elem.Addr())
} }
} }
} }

View File

@ -328,8 +328,10 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) []
} else if _, ok := v[key].(Valuer); ok { } else if _, ok := v[key].(Valuer); ok {
conds = append(conds, clause.Eq{Column: key, Value: v[key]}) conds = append(conds, clause.Eq{Column: key, Value: v[key]})
} else { } else {
values := make([]interface{}, reflectValue.Len()) // optimize relect value length
for i := 0; i < reflectValue.Len(); i++ { valueLen := reflectValue.Len()
values := make([]interface{}, valueLen)
for i := 0; i < valueLen; i++ {
values[i] = reflectValue.Index(i).Interface() values[i] = reflectValue.Index(i).Interface()
} }
@ -396,8 +398,10 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) []
if len(args) == 1 { if len(args) == 1 {
switch reflectValue.Kind() { switch reflectValue.Kind() {
case reflect.Slice, reflect.Array: case reflect.Slice, reflect.Array:
values := make([]interface{}, reflectValue.Len()) // optimize relect value length
for i := 0; i < reflectValue.Len(); i++ { valueLen := reflectValue.Len()
values := make([]interface{}, valueLen)
for i := 0; i < valueLen; i++ {
values[i] = reflectValue.Index(i).Interface() values[i] = reflectValue.Index(i).Interface()
} }