Add field permission test
This commit is contained in:
		
							parent
							
								
									c8e7878b3e
								
							
						
					
					
						commit
						d50879cc28
					
				| @ -10,7 +10,7 @@ import ( | ||||
| ) | ||||
| 
 | ||||
| func SetupUpdateReflectValue(db *gorm.DB) { | ||||
| 	if db.Error == nil { | ||||
| 	if db.Error == nil && db.Statement.Schema != nil { | ||||
| 		if !db.Statement.ReflectValue.CanAddr() || db.Statement.Model != db.Statement.Dest { | ||||
| 			db.Statement.ReflectValue = reflect.ValueOf(db.Statement.Model) | ||||
| 			for db.Statement.ReflectValue.Kind() == reflect.Ptr { | ||||
| @ -172,6 +172,7 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { | ||||
| 		sort.Strings(keys) | ||||
| 
 | ||||
| 		for _, k := range keys { | ||||
| 			if stmt.Schema != nil { | ||||
| 				if field := stmt.Schema.LookUpField(k); field != nil { | ||||
| 					if field.DBName != "" { | ||||
| 						if v, ok := selectColumns[field.DBName]; (ok && v) || (!ok && !restricted) { | ||||
| @ -181,17 +182,28 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { | ||||
| 					} else if v, ok := selectColumns[field.Name]; (ok && v) || (!ok && !restricted) { | ||||
| 						assignValue(field, value[k]) | ||||
| 					} | ||||
| 			} else if v, ok := selectColumns[k]; (ok && v) || (!ok && !restricted) { | ||||
| 					continue | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if v, ok := selectColumns[k]; (ok && v) || (!ok && !restricted) { | ||||
| 				set = append(set, clause.Assignment{Column: clause.Column{Name: k}, Value: value[k]}) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if !stmt.DisableUpdateTime { | ||||
| 		if !stmt.DisableUpdateTime && stmt.Schema != nil { | ||||
| 			for _, field := range stmt.Schema.FieldsByDBName { | ||||
| 				if field.AutoUpdateTime > 0 && value[field.Name] == nil && value[field.DBName] == nil { | ||||
| 					now := stmt.DB.NowFunc() | ||||
| 					set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now}) | ||||
| 					assignValue(field, now) | ||||
| 
 | ||||
| 					if field.AutoUpdateTime == schema.UnixNanosecond { | ||||
| 						set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now.UnixNano()}) | ||||
| 					} else if field.DataType == schema.Time { | ||||
| 						set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now}) | ||||
| 					} else { | ||||
| 						set = append(set, clause.Assignment{Column: clause.Column{Name: field.DBName}, Value: now.Unix()}) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @ -205,7 +217,13 @@ func ConvertToAssignments(stmt *gorm.Statement) (set clause.Set) { | ||||
| 						value, isZero := field.ValueOf(updatingValue) | ||||
| 						if !stmt.DisableUpdateTime { | ||||
| 							if field.AutoUpdateTime > 0 { | ||||
| 								if field.AutoUpdateTime == schema.UnixNanosecond { | ||||
| 									value = stmt.DB.NowFunc().UnixNano() | ||||
| 								} else if field.DataType == schema.Time { | ||||
| 									value = stmt.DB.NowFunc() | ||||
| 								} else { | ||||
| 									value = stmt.DB.NowFunc().Unix() | ||||
| 								} | ||||
| 								isZero = false | ||||
| 							} | ||||
| 						} | ||||
|  | ||||
| @ -133,33 +133,6 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// setup permission
 | ||||
| 	if _, ok := field.TagSettings["-"]; ok { | ||||
| 		field.Creatable = false | ||||
| 		field.Updatable = false | ||||
| 		field.Readable = false | ||||
| 	} | ||||
| 
 | ||||
| 	if v, ok := field.TagSettings["<-"]; ok { | ||||
| 		if v != "<-" { | ||||
| 			if !strings.Contains(v, "create") { | ||||
| 				field.Creatable = false | ||||
| 			} | ||||
| 
 | ||||
| 			if !strings.Contains(v, "update") { | ||||
| 				field.Updatable = false | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		field.Readable = false | ||||
| 	} | ||||
| 
 | ||||
| 	if _, ok := field.TagSettings["->"]; ok { | ||||
| 		field.Creatable = false | ||||
| 		field.Updatable = false | ||||
| 		field.Readable = true | ||||
| 	} | ||||
| 
 | ||||
| 	if dbName, ok := field.TagSettings["COLUMN"]; ok { | ||||
| 		field.DBName = dbName | ||||
| 	} | ||||
| @ -276,6 +249,39 @@ func (schema *Schema) ParseField(fieldStruct reflect.StructField) *Field { | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// setup permission
 | ||||
| 	if _, ok := field.TagSettings["-"]; ok { | ||||
| 		field.Creatable = false | ||||
| 		field.Updatable = false | ||||
| 		field.Readable = false | ||||
| 		field.DataType = "" | ||||
| 	} | ||||
| 
 | ||||
| 	if v, ok := field.TagSettings["->"]; ok { | ||||
| 		field.Creatable = false | ||||
| 		field.Updatable = false | ||||
| 		if strings.ToLower(v) == "false" { | ||||
| 			field.Readable = false | ||||
| 		} else { | ||||
| 			field.Readable = true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if v, ok := field.TagSettings["<-"]; ok { | ||||
| 		field.Creatable = true | ||||
| 		field.Updatable = true | ||||
| 
 | ||||
| 		if v != "<-" { | ||||
| 			if !strings.Contains(v, "create") { | ||||
| 				field.Creatable = false | ||||
| 			} | ||||
| 
 | ||||
| 			if !strings.Contains(v, "update") { | ||||
| 				field.Updatable = false | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if _, ok := field.TagSettings["EMBEDDED"]; ok || fieldStruct.Anonymous { | ||||
| 		var err error | ||||
| 		field.Creatable = false | ||||
| @ -510,14 +516,14 @@ func (field *Field) setupValuerAndSetter() { | ||||
| 					return err | ||||
| 				} | ||||
| 			case time.Time: | ||||
| 				if field.AutoCreateTime == UnixNanosecond { | ||||
| 				if field.AutoCreateTime == UnixNanosecond || field.AutoUpdateTime == UnixNanosecond { | ||||
| 					field.ReflectValueOf(value).SetInt(data.UnixNano()) | ||||
| 				} else { | ||||
| 					field.ReflectValueOf(value).SetInt(data.Unix()) | ||||
| 				} | ||||
| 			case *time.Time: | ||||
| 				if data != nil { | ||||
| 					if field.AutoCreateTime == UnixNanosecond { | ||||
| 					if field.AutoCreateTime == UnixNanosecond || field.AutoUpdateTime == UnixNanosecond { | ||||
| 						field.ReflectValueOf(value).SetInt(data.UnixNano()) | ||||
| 					} else { | ||||
| 						field.ReflectValueOf(value).SetInt(data.Unix()) | ||||
|  | ||||
| @ -225,6 +225,7 @@ type UserWithPermissionControl struct { | ||||
| 	Name4 string `gorm:"<-:create"` | ||||
| 	Name5 string `gorm:"<-:update"` | ||||
| 	Name6 string `gorm:"<-:create,update"` | ||||
| 	Name7 string `gorm:"->:false;<-:create,update"` | ||||
| } | ||||
| 
 | ||||
| func TestParseFieldWithPermission(t *testing.T) { | ||||
| @ -235,12 +236,13 @@ func TestParseFieldWithPermission(t *testing.T) { | ||||
| 
 | ||||
| 	fields := []schema.Field{ | ||||
| 		{Name: "ID", DBName: "id", BindNames: []string{"ID"}, DataType: schema.Uint, PrimaryKey: true, Size: 64, Creatable: true, Updatable: true, Readable: true}, | ||||
| 		{Name: "Name", DBName: "name", BindNames: []string{"Name"}, DataType: schema.String, Tag: `gorm:"-"`, Creatable: false, Updatable: false, Readable: false}, | ||||
| 		{Name: "Name", DBName: "", BindNames: []string{"Name"}, DataType: "", Tag: `gorm:"-"`, Creatable: false, Updatable: false, Readable: false}, | ||||
| 		{Name: "Name2", DBName: "name2", BindNames: []string{"Name2"}, DataType: schema.String, Tag: `gorm:"->"`, Creatable: false, Updatable: false, Readable: true}, | ||||
| 		{Name: "Name3", DBName: "name3", BindNames: []string{"Name3"}, DataType: schema.String, Tag: `gorm:"<-"`, Creatable: true, Updatable: true, Readable: false}, | ||||
| 		{Name: "Name4", DBName: "name4", BindNames: []string{"Name4"}, DataType: schema.String, Tag: `gorm:"<-:create"`, Creatable: true, Updatable: false, Readable: false}, | ||||
| 		{Name: "Name5", DBName: "name5", BindNames: []string{"Name5"}, DataType: schema.String, Tag: `gorm:"<-:update"`, Creatable: false, Updatable: true, Readable: false}, | ||||
| 		{Name: "Name6", DBName: "name6", BindNames: []string{"Name6"}, DataType: schema.String, Tag: `gorm:"<-:create,update"`, Creatable: true, Updatable: true, Readable: false}, | ||||
| 		{Name: "Name3", DBName: "name3", BindNames: []string{"Name3"}, DataType: schema.String, Tag: `gorm:"<-"`, Creatable: true, Updatable: true, Readable: true}, | ||||
| 		{Name: "Name4", DBName: "name4", BindNames: []string{"Name4"}, DataType: schema.String, Tag: `gorm:"<-:create"`, Creatable: true, Updatable: false, Readable: true}, | ||||
| 		{Name: "Name5", DBName: "name5", BindNames: []string{"Name5"}, DataType: schema.String, Tag: `gorm:"<-:update"`, Creatable: false, Updatable: true, Readable: true}, | ||||
| 		{Name: "Name6", DBName: "name6", BindNames: []string{"Name6"}, DataType: schema.String, Tag: `gorm:"<-:create,update"`, Creatable: true, Updatable: true, Readable: true}, | ||||
| 		{Name: "Name7", DBName: "name7", BindNames: []string{"Name7"}, DataType: schema.String, Tag: `gorm:"->:false;<-:create,update"`, Creatable: true, Updatable: true, Readable: false}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, f := range fields { | ||||
|  | ||||
| @ -54,15 +54,19 @@ func checkSchemaField(t *testing.T, s *schema.Schema, f *schema.Field, fc func(* | ||||
| 		} else { | ||||
| 			tests.AssertObjEqual(t, parsedField, f, "Name", "DBName", "BindNames", "DataType", "DBDataType", "PrimaryKey", "AutoIncrement", "Creatable", "Updatable", "Readable", "HasDefaultValue", "DefaultValue", "NotNull", "Unique", "Comment", "Size", "Precision", "Tag", "TagSettings") | ||||
| 
 | ||||
| 			if f.DBName != "" { | ||||
| 				if field, ok := s.FieldsByDBName[f.DBName]; !ok || parsedField != field { | ||||
| 					t.Errorf("schema %v failed to look up field with dbname %v", s, f.DBName) | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			for _, name := range []string{f.DBName, f.Name} { | ||||
| 				if name != "" { | ||||
| 					if field := s.LookUpField(name); field == nil || parsedField != field { | ||||
| 						t.Errorf("schema %v failed to look up field with dbname %v", s, f.DBName) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			if f.PrimaryKey { | ||||
| 				var found bool | ||||
|  | ||||
| @ -1,56 +0,0 @@ | ||||
| package tests_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| func TestCustomizeColumn(t *testing.T) { | ||||
| 	type CustomizeColumn struct { | ||||
| 		ID   int64      `gorm:"column:mapped_id; primary_key:yes"` | ||||
| 		Name string     `gorm:"column:mapped_name"` | ||||
| 		Date *time.Time `gorm:"column:mapped_time"` | ||||
| 	} | ||||
| 
 | ||||
| 	DB.Migrator().DropTable(&CustomizeColumn{}) | ||||
| 	DB.AutoMigrate(&CustomizeColumn{}) | ||||
| 
 | ||||
| 	expected := "foo" | ||||
| 	now := time.Now() | ||||
| 	cc := CustomizeColumn{ID: 666, Name: expected, Date: &now} | ||||
| 
 | ||||
| 	if count := DB.Create(&cc).RowsAffected; count != 1 { | ||||
| 		t.Error("There should be one record be affected when create record") | ||||
| 	} | ||||
| 
 | ||||
| 	var cc1 CustomizeColumn | ||||
| 	DB.First(&cc1, "mapped_name = ?", "foo") | ||||
| 
 | ||||
| 	if cc1.Name != expected { | ||||
| 		t.Errorf("Failed to query CustomizeColumn") | ||||
| 	} | ||||
| 
 | ||||
| 	cc.Name = "bar" | ||||
| 	DB.Save(&cc) | ||||
| 
 | ||||
| 	var cc2 CustomizeColumn | ||||
| 	DB.First(&cc2, "mapped_id = ?", 666) | ||||
| 	if cc2.Name != "bar" { | ||||
| 		t.Errorf("Failed to query CustomizeColumn") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestCustomColumnAndIgnoredFieldClash(t *testing.T) { | ||||
| 	// Make sure an ignored field does not interfere with another field's custom
 | ||||
| 	// column name that matches the ignored field.
 | ||||
| 	type CustomColumnAndIgnoredFieldClash struct { | ||||
| 		Body    string `gorm:"-"` | ||||
| 		RawBody string `gorm:"column:body"` | ||||
| 	} | ||||
| 
 | ||||
| 	DB.Migrator().DropTable(&CustomColumnAndIgnoredFieldClash{}) | ||||
| 
 | ||||
| 	if err := DB.AutoMigrate(&CustomColumnAndIgnoredFieldClash{}); err != nil { | ||||
| 		t.Errorf("Should not raise error: %v", err) | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										172
									
								
								tests/customize_field_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								tests/customize_field_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,172 @@ | ||||
| package tests_test | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"gorm.io/gorm" | ||||
| 	. "gorm.io/gorm/utils/tests" | ||||
| ) | ||||
| 
 | ||||
| func TestCustomizeColumn(t *testing.T) { | ||||
| 	type CustomizeColumn struct { | ||||
| 		ID   int64      `gorm:"column:mapped_id; primary_key:yes"` | ||||
| 		Name string     `gorm:"column:mapped_name"` | ||||
| 		Date *time.Time `gorm:"column:mapped_time"` | ||||
| 	} | ||||
| 
 | ||||
| 	DB.Migrator().DropTable(&CustomizeColumn{}) | ||||
| 	DB.AutoMigrate(&CustomizeColumn{}) | ||||
| 
 | ||||
| 	expected := "foo" | ||||
| 	now := time.Now() | ||||
| 	cc := CustomizeColumn{ID: 666, Name: expected, Date: &now} | ||||
| 
 | ||||
| 	if count := DB.Create(&cc).RowsAffected; count != 1 { | ||||
| 		t.Error("There should be one record be affected when create record") | ||||
| 	} | ||||
| 
 | ||||
| 	var cc1 CustomizeColumn | ||||
| 	DB.First(&cc1, "mapped_name = ?", "foo") | ||||
| 
 | ||||
| 	if cc1.Name != expected { | ||||
| 		t.Errorf("Failed to query CustomizeColumn") | ||||
| 	} | ||||
| 
 | ||||
| 	cc.Name = "bar" | ||||
| 	DB.Save(&cc) | ||||
| 
 | ||||
| 	var cc2 CustomizeColumn | ||||
| 	DB.First(&cc2, "mapped_id = ?", 666) | ||||
| 	if cc2.Name != "bar" { | ||||
| 		t.Errorf("Failed to query CustomizeColumn") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestCustomColumnAndIgnoredFieldClash(t *testing.T) { | ||||
| 	// Make sure an ignored field does not interfere with another field's custom
 | ||||
| 	// column name that matches the ignored field.
 | ||||
| 	type CustomColumnAndIgnoredFieldClash struct { | ||||
| 		Body    string `gorm:"-"` | ||||
| 		RawBody string `gorm:"column:body"` | ||||
| 	} | ||||
| 
 | ||||
| 	DB.Migrator().DropTable(&CustomColumnAndIgnoredFieldClash{}) | ||||
| 
 | ||||
| 	if err := DB.AutoMigrate(&CustomColumnAndIgnoredFieldClash{}); err != nil { | ||||
| 		t.Errorf("Should not raise error: %v", err) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestCustomizeField(t *testing.T) { | ||||
| 	type CustomizeFieldStruct struct { | ||||
| 		gorm.Model | ||||
| 		Name                   string | ||||
| 		FieldAllowCreate       string `gorm:"<-:create"` | ||||
| 		FieldAllowUpdate       string `gorm:"<-:update"` | ||||
| 		FieldAllowSave         string `gorm:"<-"` | ||||
| 		FieldAllowSave2        string `gorm:"<-:create,update"` | ||||
| 		FieldAllowSave3        string `gorm:"->:false;<-:create"` | ||||
| 		FieldReadonly          string `gorm:"->"` | ||||
| 		FieldIgnore            string `gorm:"-"` | ||||
| 		AutoUnixCreateTime     int64  `gorm:"autocreatetime"` | ||||
| 		AutoUnixNanoCreateTime int64  `gorm:"autocreatetime:nano"` | ||||
| 		AutoUnixUpdateTime     int64  `gorm:"autoupdatetime"` | ||||
| 		AutoUnixNanoUpdateTime int64  `gorm:"autoupdatetime:nano"` | ||||
| 	} | ||||
| 
 | ||||
| 	DB.Migrator().DropTable(&CustomizeFieldStruct{}) | ||||
| 
 | ||||
| 	if err := DB.AutoMigrate(&CustomizeFieldStruct{}); err != nil { | ||||
| 		t.Errorf("Failed to migrate, got error: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if DB.Migrator().HasColumn(&CustomizeFieldStruct{}, "FieldIgnore") { | ||||
| 		t.Errorf("FieldIgnore should not be created") | ||||
| 	} | ||||
| 
 | ||||
| 	if DB.Migrator().HasColumn(&CustomizeFieldStruct{}, "field_ignore") { | ||||
| 		t.Errorf("FieldIgnore should not be created") | ||||
| 	} | ||||
| 
 | ||||
| 	generateStruct := func(name string) *CustomizeFieldStruct { | ||||
| 		return &CustomizeFieldStruct{ | ||||
| 			Name:             name, | ||||
| 			FieldAllowCreate: name + "_allow_create", | ||||
| 			FieldAllowUpdate: name + "_allow_update", | ||||
| 			FieldAllowSave:   name + "_allow_save", | ||||
| 			FieldAllowSave2:  name + "_allow_save2", | ||||
| 			FieldAllowSave3:  name + "_allow_save3", | ||||
| 			FieldReadonly:    name + "_allow_readonly", | ||||
| 			FieldIgnore:      name + "_allow_ignore", | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	create := generateStruct("create") | ||||
| 	DB.Create(&create) | ||||
| 
 | ||||
| 	var result CustomizeFieldStruct | ||||
| 	DB.Find(&result, "name = ?", "create") | ||||
| 
 | ||||
| 	AssertObjEqual(t, result, create, "Name", "FieldAllowCreate", "FieldAllowSave", "FieldAllowSave2") | ||||
| 
 | ||||
| 	if result.FieldAllowUpdate != "" || result.FieldReadonly != "" || result.FieldIgnore != "" || result.FieldAllowSave3 != "" { | ||||
| 		t.Fatalf("invalid result: %#v", result) | ||||
| 	} | ||||
| 
 | ||||
| 	if result.AutoUnixCreateTime != result.AutoUnixUpdateTime || result.AutoUnixCreateTime == 0 { | ||||
| 		t.Fatalf("invalid create/update unix time: %#v", result) | ||||
| 	} | ||||
| 
 | ||||
| 	if result.AutoUnixNanoCreateTime != result.AutoUnixNanoUpdateTime || result.AutoUnixNanoCreateTime == 0 || result.AutoUnixNanoCreateTime/result.AutoUnixCreateTime < 1e6 { | ||||
| 		t.Fatalf("invalid create/update unix nano time: %#v", result) | ||||
| 	} | ||||
| 
 | ||||
| 	result.FieldAllowUpdate = "field_allow_update_updated" | ||||
| 	result.FieldReadonly = "field_readonly_updated" | ||||
| 	result.FieldIgnore = "field_ignore_updated" | ||||
| 	DB.Save(&result) | ||||
| 
 | ||||
| 	var result2 CustomizeFieldStruct | ||||
| 	DB.Find(&result2, "name = ?", "create") | ||||
| 
 | ||||
| 	if result2.FieldAllowUpdate != result.FieldAllowUpdate || result2.FieldReadonly != "" || result2.FieldIgnore != "" { | ||||
| 		t.Fatalf("invalid updated result: %#v", result2) | ||||
| 	} | ||||
| 
 | ||||
| 	if err := DB.Table("customize_field_structs").Where("1 = 1").UpdateColumn("field_readonly", "readonly").Error; err != nil { | ||||
| 		t.Fatalf("failed to update field_readonly column") | ||||
| 	} | ||||
| 
 | ||||
| 	var result3 CustomizeFieldStruct | ||||
| 	DB.Find(&result3, "name = ?", "create") | ||||
| 
 | ||||
| 	if result3.FieldReadonly != "readonly" { | ||||
| 		t.Fatalf("invalid updated result: %#v", result3) | ||||
| 	} | ||||
| 
 | ||||
| 	var result4 CustomizeFieldStruct | ||||
| 	if err := DB.First(&result4, "field_allow_save3 = ?", create.FieldAllowSave3).Error; err != nil { | ||||
| 		t.Fatalf("failed to query with inserted field, got error %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	AssertEqual(t, result3, result4) | ||||
| 
 | ||||
| 	createWithDefaultTime := generateStruct("create_with_default_time") | ||||
| 	createWithDefaultTime.AutoUnixCreateTime = 100 | ||||
| 	createWithDefaultTime.AutoUnixUpdateTime = 100 | ||||
| 	createWithDefaultTime.AutoUnixNanoCreateTime = 100 | ||||
| 	createWithDefaultTime.AutoUnixNanoUpdateTime = 100 | ||||
| 	DB.Create(&createWithDefaultTime) | ||||
| 
 | ||||
| 	var createWithDefaultTimeResult CustomizeFieldStruct | ||||
| 	DB.Find(&createWithDefaultTimeResult, "name = ?", createWithDefaultTime.Name) | ||||
| 
 | ||||
| 	if createWithDefaultTimeResult.AutoUnixCreateTime != createWithDefaultTimeResult.AutoUnixUpdateTime || createWithDefaultTimeResult.AutoUnixCreateTime != 100 { | ||||
| 		t.Fatalf("invalid create/update unix time: %#v", createWithDefaultTimeResult) | ||||
| 	} | ||||
| 
 | ||||
| 	if createWithDefaultTimeResult.AutoUnixNanoCreateTime != createWithDefaultTimeResult.AutoUnixNanoUpdateTime || createWithDefaultTimeResult.AutoUnixNanoCreateTime != 100 { | ||||
| 		t.Fatalf("invalid create/update unix nano time: %#v", createWithDefaultTimeResult) | ||||
| 	} | ||||
| } | ||||
| @ -6,7 +6,7 @@ require ( | ||||
| 	github.com/jinzhu/now v1.1.1 | ||||
| 	gorm.io/driver/mysql v0.0.0-20200602015408-0407d0c21cf0 | ||||
| 	gorm.io/driver/postgres v0.0.0-20200602015520-15fcc29eb286 | ||||
| 	gorm.io/driver/sqlite v0.0.0-20200602015323-284b563f81c8 | ||||
| 	gorm.io/driver/sqlite v1.0.0 | ||||
| 	gorm.io/driver/sqlserver v0.0.0-20200602144728-79c224f6c1a2 | ||||
| 	gorm.io/gorm v0.0.0-00010101000000-000000000000 | ||||
| ) | ||||
|  | ||||
| @ -67,6 +67,22 @@ func TestFind(t *testing.T) { | ||||
| 		} | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("FirstPtrMap", func(t *testing.T) { | ||||
| 		var first = map[string]interface{}{} | ||||
| 		if err := DB.Model(&User{}).Where("name = ?", "find").First(&first).Error; err != nil { | ||||
| 			t.Errorf("errors happened when query first: %v", err) | ||||
| 		} else { | ||||
| 			for _, name := range []string{"Name", "Age", "Birthday"} { | ||||
| 				t.Run(name, func(t *testing.T) { | ||||
| 					dbName := DB.NamingStrategy.ColumnName("", name) | ||||
| 					reflectValue := reflect.Indirect(reflect.ValueOf(users[0])) | ||||
| 					AssertEqual(t, first[dbName], reflectValue.FieldByName(name).Interface()) | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	}) | ||||
| 
 | ||||
| 	t.Run("FirstSliceOfMap", func(t *testing.T) { | ||||
| 		var allMap = []map[string]interface{}{} | ||||
| 		if err := DB.Model(&User{}).Where("name = ?", "find").Find(&allMap).Error; err != nil { | ||||
| 			t.Errorf("errors happened when query first: %v", err) | ||||
| @ -83,6 +99,7 @@ func TestFind(t *testing.T) { | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func TestFillSmallerStruct(t *testing.T) { | ||||
|  | ||||
| @ -122,3 +122,19 @@ func TestQueryRaw(t *testing.T) { | ||||
| 	DB.Raw("select * from users WHERE id = ?", users[1].ID).First(&user) | ||||
| 	CheckUser(t, user, *users[1]) | ||||
| } | ||||
| 
 | ||||
| func TestDryRun(t *testing.T) { | ||||
| 	user := *GetUser("dry-run", Config{}) | ||||
| 
 | ||||
| 	dryRunDB := DB.Session(&gorm.Session{DryRun: true}) | ||||
| 
 | ||||
| 	stmt := dryRunDB.Create(&user).Statement | ||||
| 	if stmt.SQL.String() == "" || len(stmt.Vars) != 9 { | ||||
| 		t.Errorf("Failed to generate sql, got %v", stmt.SQL.String()) | ||||
| 	} | ||||
| 
 | ||||
| 	stmt2 := dryRunDB.Find(&user, "id = ?", user.ID).Statement | ||||
| 	if stmt2.SQL.String() == "" || len(stmt2.Vars) != 1 { | ||||
| 		t.Errorf("Failed to generate sql, got %v", stmt2.SQL.String()) | ||||
| 	} | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Jinzhu
						Jinzhu