fix:serializer contain field panic (#5461)
This commit is contained in:
		
							parent
							
								
									a70af2a4c0
								
							
						
					
					
						commit
						3e6ab99043
					
				| @ -950,7 +950,7 @@ func (field *Field) setupNewValuePool() { | |||||||
| 			New: func() interface{} { | 			New: func() interface{} { | ||||||
| 				return &serializer{ | 				return &serializer{ | ||||||
| 					Field:      field, | 					Field:      field, | ||||||
| 					Serializer: reflect.New(reflect.Indirect(reflect.ValueOf(field.Serializer)).Type()).Interface().(SerializerInterface), | 					Serializer: field.Serializer, | ||||||
| 				} | 				} | ||||||
| 			}, | 			}, | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -16,13 +16,14 @@ import ( | |||||||
| 
 | 
 | ||||||
| type SerializerStruct struct { | type SerializerStruct struct { | ||||||
| 	gorm.Model | 	gorm.Model | ||||||
| 	Name            []byte                 `gorm:"json"` | 	Name                   []byte                 `gorm:"json"` | ||||||
| 	Roles           Roles                  `gorm:"serializer:json"` | 	Roles                  Roles                  `gorm:"serializer:json"` | ||||||
| 	Contracts       map[string]interface{} `gorm:"serializer:json"` | 	Contracts              map[string]interface{} `gorm:"serializer:json"` | ||||||
| 	JobInfo         Job                    `gorm:"type:bytes;serializer:gob"` | 	JobInfo                Job                    `gorm:"type:bytes;serializer:gob"` | ||||||
| 	CreatedTime     int64                  `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
 | 	CreatedTime            int64                  `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
 | ||||||
| 	UpdatedTime     *int64                 `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
 | 	UpdatedTime            *int64                 `gorm:"serializer:unixtime;type:time"` // store time in db, use int as field type
 | ||||||
| 	EncryptedString EncryptedString | 	CustomSerializerString string                 `gorm:"serializer:custom"` | ||||||
|  | 	EncryptedString        EncryptedString | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type Roles []string | type Roles []string | ||||||
| @ -52,7 +53,32 @@ func (es EncryptedString) Value(ctx context.Context, field *schema.Field, dst re | |||||||
| 	return "hello" + string(es), nil | 	return "hello" + string(es), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type CustomSerializer struct { | ||||||
|  | 	prefix []byte | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewCustomSerializer(prefix string) *CustomSerializer { | ||||||
|  | 	return &CustomSerializer{prefix: []byte(prefix)} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *CustomSerializer) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error) { | ||||||
|  | 	switch value := dbValue.(type) { | ||||||
|  | 	case []byte: | ||||||
|  | 		err = field.Set(ctx, dst, bytes.TrimPrefix(value, c.prefix)) | ||||||
|  | 	case string: | ||||||
|  | 		err = field.Set(ctx, dst, strings.TrimPrefix(value, string(c.prefix))) | ||||||
|  | 	default: | ||||||
|  | 		err = fmt.Errorf("unsupported data %#v", dbValue) | ||||||
|  | 	} | ||||||
|  | 	return err | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *CustomSerializer) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) { | ||||||
|  | 	return fmt.Sprintf("%s%s", c.prefix, fieldValue), nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestSerializer(t *testing.T) { | func TestSerializer(t *testing.T) { | ||||||
|  | 	schema.RegisterSerializer("custom", NewCustomSerializer("hello")) | ||||||
| 	DB.Migrator().DropTable(&SerializerStruct{}) | 	DB.Migrator().DropTable(&SerializerStruct{}) | ||||||
| 	if err := DB.Migrator().AutoMigrate(&SerializerStruct{}); err != nil { | 	if err := DB.Migrator().AutoMigrate(&SerializerStruct{}); err != nil { | ||||||
| 		t.Fatalf("no error should happen when migrate scanner, valuer struct, got error %v", err) | 		t.Fatalf("no error should happen when migrate scanner, valuer struct, got error %v", err) | ||||||
| @ -74,6 +100,7 @@ func TestSerializer(t *testing.T) { | |||||||
| 			Location: "Kenmawr", | 			Location: "Kenmawr", | ||||||
| 			IsIntern: false, | 			IsIntern: false, | ||||||
| 		}, | 		}, | ||||||
|  | 		CustomSerializerString: "world", | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err := DB.Create(&data).Error; err != nil { | 	if err := DB.Create(&data).Error; err != nil { | ||||||
| @ -90,6 +117,7 @@ func TestSerializer(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestSerializerAssignFirstOrCreate(t *testing.T) { | func TestSerializerAssignFirstOrCreate(t *testing.T) { | ||||||
|  | 	schema.RegisterSerializer("custom", NewCustomSerializer("hello")) | ||||||
| 	DB.Migrator().DropTable(&SerializerStruct{}) | 	DB.Migrator().DropTable(&SerializerStruct{}) | ||||||
| 	if err := DB.Migrator().AutoMigrate(&SerializerStruct{}); err != nil { | 	if err := DB.Migrator().AutoMigrate(&SerializerStruct{}); err != nil { | ||||||
| 		t.Fatalf("no error should happen when migrate scanner, valuer struct, got error %v", err) | 		t.Fatalf("no error should happen when migrate scanner, valuer struct, got error %v", err) | ||||||
| @ -109,6 +137,7 @@ func TestSerializerAssignFirstOrCreate(t *testing.T) { | |||||||
| 			Location: "Shadyside", | 			Location: "Shadyside", | ||||||
| 			IsIntern: false, | 			IsIntern: false, | ||||||
| 		}, | 		}, | ||||||
|  | 		CustomSerializerString: "world", | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// first time insert record
 | 	// first time insert record
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 wws
						wws