github.com/systematiccaos/gorm@v1.22.6/callbacks/helper.go (about) 1 package callbacks 2 3 import ( 4 "sort" 5 6 "github.com/systematiccaos/gorm" 7 "github.com/systematiccaos/gorm/clause" 8 ) 9 10 // ConvertMapToValuesForCreate convert map to values 11 func ConvertMapToValuesForCreate(stmt *gorm.Statement, mapValue map[string]interface{}) (values clause.Values) { 12 values.Columns = make([]clause.Column, 0, len(mapValue)) 13 selectColumns, restricted := stmt.SelectAndOmitColumns(true, false) 14 15 var keys = make([]string, 0, len(mapValue)) 16 for k := range mapValue { 17 keys = append(keys, k) 18 } 19 sort.Strings(keys) 20 21 for _, k := range keys { 22 value := mapValue[k] 23 if stmt.Schema != nil { 24 if field := stmt.Schema.LookUpField(k); field != nil { 25 k = field.DBName 26 } 27 } 28 29 if v, ok := selectColumns[k]; (ok && v) || (!ok && !restricted) { 30 values.Columns = append(values.Columns, clause.Column{Name: k}) 31 if len(values.Values) == 0 { 32 values.Values = [][]interface{}{{}} 33 } 34 35 values.Values[0] = append(values.Values[0], value) 36 } 37 } 38 return 39 } 40 41 // ConvertSliceOfMapToValuesForCreate convert slice of map to values 42 func ConvertSliceOfMapToValuesForCreate(stmt *gorm.Statement, mapValues []map[string]interface{}) (values clause.Values) { 43 var ( 44 columns = make([]string, 0, len(mapValues)) 45 ) 46 47 // when the length of mapValues is zero,return directly here 48 // no need to call stmt.SelectAndOmitColumns method 49 if len(mapValues) == 0 { 50 stmt.AddError(gorm.ErrEmptySlice) 51 return 52 } 53 54 var ( 55 result = make(map[string][]interface{}, len(mapValues)) 56 selectColumns, restricted = stmt.SelectAndOmitColumns(true, false) 57 ) 58 59 for idx, mapValue := range mapValues { 60 for k, v := range mapValue { 61 if stmt.Schema != nil { 62 if field := stmt.Schema.LookUpField(k); field != nil { 63 k = field.DBName 64 } 65 } 66 67 if _, ok := result[k]; !ok { 68 if v, ok := selectColumns[k]; (ok && v) || (!ok && !restricted) { 69 result[k] = make([]interface{}, len(mapValues)) 70 columns = append(columns, k) 71 } else { 72 continue 73 } 74 } 75 76 result[k][idx] = v 77 } 78 } 79 80 sort.Strings(columns) 81 values.Values = make([][]interface{}, len(mapValues)) 82 values.Columns = make([]clause.Column, len(columns)) 83 for idx, column := range columns { 84 values.Columns[idx] = clause.Column{Name: column} 85 86 for i, v := range result[column] { 87 if len(values.Values[i]) == 0 { 88 values.Values[i] = make([]interface{}, len(columns)) 89 } 90 91 values.Values[i][idx] = v 92 } 93 } 94 return 95 } 96 97 func hasReturning(tx *gorm.DB, supportReturning bool) (bool, gorm.ScanMode) { 98 if supportReturning { 99 if c, ok := tx.Statement.Clauses["RETURNING"]; ok { 100 returning, _ := c.Expression.(clause.Returning) 101 if len(returning.Columns) == 0 || (len(returning.Columns) == 1 && returning.Columns[0].Name == "*") { 102 return true, 0 103 } 104 return true, gorm.ScanUpdate 105 } 106 } 107 return false, 0 108 }