123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- package gorm_test
- import (
- "database/sql/driver"
- "encoding/json"
- "errors"
- "testing"
- "github.com/jinzhu/gorm"
- )
- func TestScannableSlices(t *testing.T) {
- if err := DB.AutoMigrate(&RecordWithSlice{}).Error; err != nil {
- t.Errorf("Should create table with slice values correctly: %s", err)
- }
- r1 := RecordWithSlice{
- Strings: ExampleStringSlice{"a", "b", "c"},
- Structs: ExampleStructSlice{
- {"name1", "value1"},
- {"name2", "value2"},
- },
- }
- if err := DB.Save(&r1).Error; err != nil {
- t.Errorf("Should save record with slice values")
- }
- var r2 RecordWithSlice
- if err := DB.Find(&r2).Error; err != nil {
- t.Errorf("Should fetch record with slice values")
- }
- if len(r2.Strings) != 3 || r2.Strings[0] != "a" || r2.Strings[1] != "b" || r2.Strings[2] != "c" {
- t.Errorf("Should have serialised and deserialised a string array")
- }
- if len(r2.Structs) != 2 || r2.Structs[0].Name != "name1" || r2.Structs[0].Value != "value1" || r2.Structs[1].Name != "name2" || r2.Structs[1].Value != "value2" {
- t.Errorf("Should have serialised and deserialised a struct array")
- }
- }
- type RecordWithSlice struct {
- ID uint64
- Strings ExampleStringSlice `sql:"type:text"`
- Structs ExampleStructSlice `sql:"type:text"`
- }
- type ExampleStringSlice []string
- func (l ExampleStringSlice) Value() (driver.Value, error) {
- bytes, err := json.Marshal(l)
- return string(bytes), err
- }
- func (l *ExampleStringSlice) Scan(input interface{}) error {
- switch value := input.(type) {
- case string:
- return json.Unmarshal([]byte(value), l)
- case []byte:
- return json.Unmarshal(value, l)
- default:
- return errors.New("not supported")
- }
- }
- type ExampleStruct struct {
- Name string
- Value string
- }
- type ExampleStructSlice []ExampleStruct
- func (l ExampleStructSlice) Value() (driver.Value, error) {
- bytes, err := json.Marshal(l)
- return string(bytes), err
- }
- func (l *ExampleStructSlice) Scan(input interface{}) error {
- switch value := input.(type) {
- case string:
- return json.Unmarshal([]byte(value), l)
- case []byte:
- return json.Unmarshal(value, l)
- default:
- return errors.New("not supported")
- }
- }
- type ScannerDataType struct {
- Street string `sql:"TYPE:varchar(24)"`
- }
- func (ScannerDataType) Value() (driver.Value, error) {
- return nil, nil
- }
- func (*ScannerDataType) Scan(input interface{}) error {
- return nil
- }
- type ScannerDataTypeTestStruct struct {
- Field1 int
- ScannerDataType *ScannerDataType `sql:"TYPE:json"`
- }
- type ScannerDataType2 struct {
- Street string `sql:"TYPE:varchar(24)"`
- }
- func (ScannerDataType2) Value() (driver.Value, error) {
- return nil, nil
- }
- func (*ScannerDataType2) Scan(input interface{}) error {
- return nil
- }
- type ScannerDataTypeTestStruct2 struct {
- Field1 int
- ScannerDataType *ScannerDataType2
- }
- func TestScannerDataType(t *testing.T) {
- scope := gorm.Scope{Value: &ScannerDataTypeTestStruct{}}
- if field, ok := scope.FieldByName("ScannerDataType"); ok {
- if DB.Dialect().DataTypeOf(field.StructField) != "json" {
- t.Errorf("data type for scanner is wrong")
- }
- }
- scope = gorm.Scope{Value: &ScannerDataTypeTestStruct2{}}
- if field, ok := scope.FieldByName("ScannerDataType"); ok {
- if DB.Dialect().DataTypeOf(field.StructField) != "varchar(24)" {
- t.Errorf("data type for scanner is wrong")
- }
- }
- }
|