Handle create with default db values
This commit is contained in:
		
							parent
							
								
									15ce5b3cdd
								
							
						
					
					
						commit
						43ce0b8af2
					
				| @ -59,8 +59,10 @@ func ConvertToCreateValues(stmt *gorm.Statement) (clause.Values, []map[string]in | |||||||
| 		) | 		) | ||||||
| 
 | 
 | ||||||
| 		for _, db := range stmt.Schema.DBNames { | 		for _, db := range stmt.Schema.DBNames { | ||||||
| 			if v, ok := selectColumns[db]; (ok && v) || (!ok && !restricted) { | 			if stmt.Schema.FieldsWithDefaultDBValue[db] == nil { | ||||||
| 				values.Columns = append(values.Columns, clause.Column{Name: db}) | 				if v, ok := selectColumns[db]; (ok && v) || (!ok && !restricted) { | ||||||
|  | 					values.Columns = append(values.Columns, clause.Column{Name: db}) | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| @ -68,6 +70,7 @@ func ConvertToCreateValues(stmt *gorm.Statement) (clause.Values, []map[string]in | |||||||
| 		switch reflectValue.Kind() { | 		switch reflectValue.Kind() { | ||||||
| 		case reflect.Slice, reflect.Array: | 		case reflect.Slice, reflect.Array: | ||||||
| 			values.Values = make([][]interface{}, reflectValue.Len()) | 			values.Values = make([][]interface{}, reflectValue.Len()) | ||||||
|  | 			defaultValueFieldsHavingValue := map[string][]interface{}{} | ||||||
| 			for i := 0; i < reflectValue.Len(); i++ { | 			for i := 0; i < reflectValue.Len(); i++ { | ||||||
| 				rv := reflect.Indirect(reflectValue.Index(i)) | 				rv := reflect.Indirect(reflectValue.Index(i)) | ||||||
| 				values.Values[i] = make([]interface{}, len(values.Columns)) | 				values.Values[i] = make([]interface{}, len(values.Columns)) | ||||||
| @ -80,44 +83,57 @@ func ConvertToCreateValues(stmt *gorm.Statement) (clause.Values, []map[string]in | |||||||
| 						} else if field.AutoCreateTime > 0 || field.AutoUpdateTime > 0 { | 						} else if field.AutoCreateTime > 0 || field.AutoUpdateTime > 0 { | ||||||
| 							field.Set(rv, curTime) | 							field.Set(rv, curTime) | ||||||
| 							values.Values[i][idx], _ = field.ValueOf(rv) | 							values.Values[i][idx], _ = field.ValueOf(rv) | ||||||
| 						} else if field.HasDefaultValue { |  | ||||||
| 							if len(returnningValues) == 0 { |  | ||||||
| 								returnningValues = make([]map[string]interface{}, reflectValue.Len()) |  | ||||||
| 							} |  | ||||||
| 
 |  | ||||||
| 							if returnningValues[i] == nil { |  | ||||||
| 								returnningValues[i] = map[string]interface{}{} |  | ||||||
| 							} |  | ||||||
| 
 |  | ||||||
| 							// FIXME
 |  | ||||||
| 							returnningValues[i][column.Name] = field.ReflectValueOf(reflectValue).Addr().Interface() |  | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 
 | ||||||
|  | 				for db, field := range stmt.Schema.FieldsWithDefaultDBValue { | ||||||
|  | 					if v, ok := selectColumns[db]; (ok && v) || (!ok && !restricted) { | ||||||
|  | 						if v, isZero := field.ValueOf(rv); !isZero { | ||||||
|  | 							if len(defaultValueFieldsHavingValue[db]) == 0 { | ||||||
|  | 								defaultValueFieldsHavingValue[db] = make([]interface{}, reflectValue.Len()) | ||||||
|  | 							} | ||||||
|  | 							defaultValueFieldsHavingValue[db][i] = v | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			for db, vs := range defaultValueFieldsHavingValue { | ||||||
|  | 				values.Columns = append(values.Columns, clause.Column{Name: db}) | ||||||
|  | 				for idx := range values.Values { | ||||||
|  | 					if vs[idx] == nil { | ||||||
|  | 						values.Values[idx] = append(values.Values[idx], clause.Expr{SQL: "DEFAULT"}) | ||||||
|  | 					} else { | ||||||
|  | 						values.Values[idx] = append(values.Values[idx], vs[idx]) | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		case reflect.Struct: | 		case reflect.Struct: | ||||||
| 			values.Values = [][]interface{}{make([]interface{}, len(values.Columns))} | 			values.Values = [][]interface{}{make([]interface{}, len(values.Columns))} | ||||||
| 			for idx, column := range values.Columns { | 			for idx, column := range values.Columns { | ||||||
| 				field := stmt.Schema.FieldsByDBName[column.Name] | 				field := stmt.Schema.FieldsByDBName[column.Name] | ||||||
| 				if values.Values[0][idx], _ = field.ValueOf(reflectValue); isZero { | 				if values.Values[0][idx], isZero = field.ValueOf(reflectValue); isZero { | ||||||
| 					if field.DefaultValueInterface != nil { | 					if field.DefaultValueInterface != nil { | ||||||
| 						values.Values[0][idx] = field.DefaultValueInterface | 						values.Values[0][idx] = field.DefaultValueInterface | ||||||
| 						field.Set(reflectValue, field.DefaultValueInterface) | 						field.Set(reflectValue, field.DefaultValueInterface) | ||||||
| 					} else if field.AutoCreateTime > 0 || field.AutoUpdateTime > 0 { | 					} else if field.AutoCreateTime > 0 || field.AutoUpdateTime > 0 { | ||||||
| 						field.Set(reflectValue, curTime) | 						field.Set(reflectValue, curTime) | ||||||
| 						values.Values[0][idx], _ = field.ValueOf(reflectValue) | 						values.Values[0][idx], _ = field.ValueOf(reflectValue) | ||||||
| 					} else if field.HasDefaultValue { | 					} | ||||||
| 						if len(returnningValues) == 0 { | 				} | ||||||
| 							returnningValues = make([]map[string]interface{}, 1) | 			} | ||||||
| 						} |  | ||||||
| 
 | 
 | ||||||
| 						values.Values[0][idx] = clause.Expr{SQL: "DEFAULT"} | 			for db, field := range stmt.Schema.FieldsWithDefaultDBValue { | ||||||
| 						returnningValues[0][column.Name] = field.ReflectValueOf(reflectValue).Addr().Interface() | 				if v, ok := selectColumns[db]; (ok && v) || (!ok && !restricted) { | ||||||
| 					} else if field.PrimaryKey { | 					if v, isZero := field.ValueOf(reflectValue); !isZero { | ||||||
|  | 						values.Columns = append(values.Columns, clause.Column{Name: db}) | ||||||
|  | 						values.Values[0] = append(values.Values[0], v) | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
| 		return values, returnningValues | 		return values, returnningValues | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,19 +14,20 @@ import ( | |||||||
| var ErrUnsupportedDataType = errors.New("unsupported data type") | var ErrUnsupportedDataType = errors.New("unsupported data type") | ||||||
| 
 | 
 | ||||||
| type Schema struct { | type Schema struct { | ||||||
| 	Name                    string | 	Name                     string | ||||||
| 	ModelType               reflect.Type | 	ModelType                reflect.Type | ||||||
| 	Table                   string | 	Table                    string | ||||||
| 	PrioritizedPrimaryField *Field | 	PrioritizedPrimaryField  *Field | ||||||
| 	DBNames                 []string | 	DBNames                  []string | ||||||
| 	PrimaryFields           []*Field | 	PrimaryFields            []*Field | ||||||
| 	Fields                  []*Field | 	Fields                   []*Field | ||||||
| 	FieldsByName            map[string]*Field | 	FieldsByName             map[string]*Field | ||||||
| 	FieldsByDBName          map[string]*Field | 	FieldsByDBName           map[string]*Field | ||||||
| 	Relationships           Relationships | 	FieldsWithDefaultDBValue map[string]*Field // fields with default value assigned by database
 | ||||||
| 	err                     error | 	Relationships            Relationships | ||||||
| 	namer                   Namer | 	err                      error | ||||||
| 	cacheStore              *sync.Map | 	namer                    Namer | ||||||
|  | 	cacheStore               *sync.Map | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (schema Schema) String() string { | func (schema Schema) String() string { | ||||||
| @ -146,6 +147,20 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	schema.FieldsWithDefaultDBValue = map[string]*Field{} | ||||||
|  | 	for db, field := range schema.FieldsByDBName { | ||||||
|  | 		if field.HasDefaultValue && field.DefaultValueInterface == nil { | ||||||
|  | 			schema.FieldsWithDefaultDBValue[db] = field | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if schema.PrioritizedPrimaryField != nil { | ||||||
|  | 		switch schema.PrioritizedPrimaryField.DataType { | ||||||
|  | 		case Int, Uint: | ||||||
|  | 			schema.FieldsWithDefaultDBValue[schema.PrioritizedPrimaryField.DBName] = schema.PrioritizedPrimaryField | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	cacheStore.Store(modelType, schema) | 	cacheStore.Store(modelType, schema) | ||||||
| 
 | 
 | ||||||
| 	// parse relations for unidentified fields
 | 	// parse relations for unidentified fields
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu