Merge cf471d38427ec4eca4e694b8bc617680f4da3b72 into 1ad419004fa8ae90145d4e3ff4fcb2629996b54b
This commit is contained in:
		
						commit
						04f645b6ab
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					gorm.test
 | 
				
			||||||
@ -7,7 +7,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func AssignUpdateAttributes(scope *Scope) {
 | 
					func AssignUpdateAttributes(scope *Scope) {
 | 
				
			||||||
	if attrs, ok := scope.InstanceGet("gorm:update_interface"); ok {
 | 
						if attrs, ok := scope.InstanceGet("gorm:update_interface"); ok {
 | 
				
			||||||
		if maps := convertInterfaceToMap(attrs); len(maps) > 0 {
 | 
							if maps := convertInterfaceToMap(attrs, false); len(maps) > 0 {
 | 
				
			||||||
			protected, ok := scope.Get("gorm:ignore_protected_attrs")
 | 
								protected, ok := scope.Get("gorm:ignore_protected_attrs")
 | 
				
			||||||
			_, updateColumn := scope.Get("gorm:update_column")
 | 
								_, updateColumn := scope.Get("gorm:update_column")
 | 
				
			||||||
			updateAttrs, hasUpdate := scope.updatedAttrsWithValues(maps, ok && protected.(bool))
 | 
								updateAttrs, hasUpdate := scope.updatedAttrsWithValues(maps, ok && protected.(bool))
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										8
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								main.go
									
									
									
									
									
								
							@ -200,7 +200,7 @@ func (s *DB) FirstOrInit(out interface{}, where ...interface{}) *DB {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		c.NewScope(out).inlineCondition(where...).initialize()
 | 
							c.NewScope(out).inlineCondition(where...).initialize()
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		c.NewScope(out).updatedAttrsWithValues(convertInterfaceToMap(s.search.AssignAttrs), false)
 | 
							c.NewScope(out).updatedAttrsWithValues(convertInterfaceToMap(s.search.AssignAttrs, false), false)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return c
 | 
						return c
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -223,6 +223,12 @@ func (s *DB) Update(attrs ...interface{}) *DB {
 | 
				
			|||||||
	return s.Updates(toSearchableMap(attrs...), true)
 | 
						return s.Updates(toSearchableMap(attrs...), true)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (s *DB) UpdateAll(value interface{}) *DB {
 | 
				
			||||||
 | 
						return s.clone().NewScope(value).
 | 
				
			||||||
 | 
							InstanceSet("gorm:update_interface", convertInterfaceToMap(value, true)).
 | 
				
			||||||
 | 
							callCallbacks(s.parent.callback.updates).db
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DB {
 | 
					func (s *DB) Updates(values interface{}, ignoreProtectedAttrs ...bool) *DB {
 | 
				
			||||||
	return s.clone().NewScope(s.Value).
 | 
						return s.clone().NewScope(s.Value).
 | 
				
			||||||
		Set("gorm:ignore_protected_attrs", len(ignoreProtectedAttrs) > 0).
 | 
							Set("gorm:ignore_protected_attrs", len(ignoreProtectedAttrs) > 0).
 | 
				
			||||||
 | 
				
			|||||||
@ -375,10 +375,10 @@ func (scope *Scope) rows() (*sql.Rows, error) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (scope *Scope) initialize() *Scope {
 | 
					func (scope *Scope) initialize() *Scope {
 | 
				
			||||||
	for _, clause := range scope.Search.WhereConditions {
 | 
						for _, clause := range scope.Search.WhereConditions {
 | 
				
			||||||
		scope.updatedAttrsWithValues(convertInterfaceToMap(clause["query"]), false)
 | 
							scope.updatedAttrsWithValues(convertInterfaceToMap(clause["query"], false), false)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	scope.updatedAttrsWithValues(convertInterfaceToMap(scope.Search.InitAttrs), false)
 | 
						scope.updatedAttrsWithValues(convertInterfaceToMap(scope.Search.InitAttrs, false), false)
 | 
				
			||||||
	scope.updatedAttrsWithValues(convertInterfaceToMap(scope.Search.AssignAttrs), false)
 | 
						scope.updatedAttrsWithValues(convertInterfaceToMap(scope.Search.AssignAttrs, false), false)
 | 
				
			||||||
	return scope
 | 
						return scope
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -158,3 +158,44 @@ func TestUpdateColumn(t *testing.T) {
 | 
				
			|||||||
		t.Errorf("updatedAt should not be updated with update column")
 | 
							t.Errorf("updatedAt should not be updated with update column")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestAlwaysUpdate(t *testing.T) {
 | 
				
			||||||
 | 
						type Always struct {
 | 
				
			||||||
 | 
							Id       int64
 | 
				
			||||||
 | 
							Name     string
 | 
				
			||||||
 | 
							Code     string
 | 
				
			||||||
 | 
							Price    int64
 | 
				
			||||||
 | 
							IsActive bool
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						DB.DropTable(&Always{})
 | 
				
			||||||
 | 
						DB.CreateTable(&Always{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						obj1 := Always{Name: "obj1", Code: "code_1", Price: 10, IsActive: true}
 | 
				
			||||||
 | 
						obj2 := Always{Name: "obj2", Code: "code_2", Price: 20, IsActive: true}
 | 
				
			||||||
 | 
						obj3 := Always{Name: "obj3", Code: "code_10", Price: 100, IsActive: true}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// save initial
 | 
				
			||||||
 | 
						DB.Save(&obj1).Save(&obj2).Save(&obj3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// now update via struct price should change to zero
 | 
				
			||||||
 | 
						obj2.Price = 0
 | 
				
			||||||
 | 
						DB.UpdateAll(obj2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var obj2_1 Always
 | 
				
			||||||
 | 
						DB.First(&obj2_1, obj2.Id)
 | 
				
			||||||
 | 
						if obj2_1.Price != 0 {
 | 
				
			||||||
 | 
							t.Errorf("UpdateAll did not update Price for obj2: %#v", obj2_1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// test bool
 | 
				
			||||||
 | 
						obj3.IsActive = false
 | 
				
			||||||
 | 
						DB.UpdateAll(obj3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var obj3_1 Always
 | 
				
			||||||
 | 
						DB.First(&obj3_1, obj3.Id)
 | 
				
			||||||
 | 
						if obj3_1.IsActive {
 | 
				
			||||||
 | 
							t.Errorf("UpdateAll did not update IsActive for obj3: %#v", obj3_1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -40,7 +40,7 @@ func toSearchableMap(attrs ...interface{}) (result interface{}) {
 | 
				
			|||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func convertInterfaceToMap(values interface{}) map[string]interface{} {
 | 
					func convertInterfaceToMap(values interface{}, skipBlankCheck bool) map[string]interface{} {
 | 
				
			||||||
	attrs := map[string]interface{}{}
 | 
						attrs := map[string]interface{}{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch value := values.(type) {
 | 
						switch value := values.(type) {
 | 
				
			||||||
@ -50,7 +50,7 @@ func convertInterfaceToMap(values interface{}) map[string]interface{} {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	case []interface{}:
 | 
						case []interface{}:
 | 
				
			||||||
		for _, v := range value {
 | 
							for _, v := range value {
 | 
				
			||||||
			for key, value := range convertInterfaceToMap(v) {
 | 
								for key, value := range convertInterfaceToMap(v, skipBlankCheck) {
 | 
				
			||||||
				attrs[key] = value
 | 
									attrs[key] = value
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -65,7 +65,7 @@ func convertInterfaceToMap(values interface{}) map[string]interface{} {
 | 
				
			|||||||
		default:
 | 
							default:
 | 
				
			||||||
			scope := Scope{Value: values}
 | 
								scope := Scope{Value: values}
 | 
				
			||||||
			for _, field := range scope.Fields() {
 | 
								for _, field := range scope.Fields() {
 | 
				
			||||||
				if !field.IsBlank {
 | 
									if skipBlankCheck || !field.IsBlank {
 | 
				
			||||||
					attrs[field.DBName] = field.Field.Interface()
 | 
										attrs[field.DBName] = field.Field.Interface()
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user