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)
}
if elems.Len() > 0 {
// optimize elems of reflect value length
if elemLen := elems.Len(); elemLen > 0 {
if v, ok := selectColumns[rel.Name+".*"]; !ok || v {
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))
}
}

View File

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

View File

@ -71,10 +71,10 @@ func GetRelationsValues(reflectValue reflect.Value, rels []*Relationship) (refle
reflectResults = reflect.Append(reflectResults, result.Addr())
case reflect.Slice, reflect.Array:
for i := 0; i < result.Len(); i++ {
if result.Index(i).Kind() == reflect.Ptr {
reflectResults = reflect.Append(reflectResults, result.Index(i))
if elem := result.Index(i); elem.Kind() == reflect.Ptr {
reflectResults = reflect.Append(reflectResults, elem)
} 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 {
conds = append(conds, clause.Eq{Column: key, Value: v[key]})
} else {
values := make([]interface{}, reflectValue.Len())
for i := 0; i < reflectValue.Len(); i++ {
// optimize relect value length
valueLen := reflectValue.Len()
values := make([]interface{}, valueLen)
for i := 0; i < valueLen; i++ {
values[i] = reflectValue.Index(i).Interface()
}
@ -396,8 +398,10 @@ func (stmt *Statement) BuildCondition(query interface{}, args ...interface{}) []
if len(args) == 1 {
switch reflectValue.Kind() {
case reflect.Slice, reflect.Array:
values := make([]interface{}, reflectValue.Len())
for i := 0; i < reflectValue.Len(); i++ {
// optimize relect value length
valueLen := reflectValue.Len()
values := make([]interface{}, valueLen)
for i := 0; i < valueLen; i++ {
values[i] = reflectValue.Index(i).Interface()
}