From 0aaefebf4fdbd9ab9e8d8ad23b7a585987abdfb9 Mon Sep 17 00:00:00 2001 From: Jinzhu Date: Tue, 7 Oct 2014 22:33:57 +0800 Subject: [PATCH] Add support for custom column names --- README.md | 10 ++++++++++ customize_column_test.go | 42 ++++++++++++++++++++++++++++++++++++++++ scope.go | 28 +++++++++++++++++++-------- 3 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 customize_column_test.go diff --git a/README.md b/README.md index b7f3985f..83456cc0 100644 --- a/README.md +++ b/README.md @@ -979,6 +979,16 @@ type Animal struct { } ``` +If your column names differ from the struct fields, you can specify them like this: + +```go +type Animal struct { + AnimalId int64 `gorm:"column:beast_id; primary_key:yes"` + Birthday time.Time `gorm:"column:day_of_the_beast"` + Age int64 `gorm:"column:age_of_the_beast"` +} +``` + ## More examples with query chain ```go diff --git a/customize_column_test.go b/customize_column_test.go new file mode 100644 index 00000000..5c63e9d6 --- /dev/null +++ b/customize_column_test.go @@ -0,0 +1,42 @@ +package gorm_test + +import ( + "testing" + "time" +) + +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"` +} + +func TestCustomizeColumn(t *testing.T) { + col := "mapped_name" + DB.DropTable(&CustomizeColumn{}) + DB.AutoMigrate(&CustomizeColumn{}) + + scope := DB.Model("").NewScope(&CustomizeColumn{}) + if !scope.Dialect().HasColumn(scope, scope.TableName(), col) { + t.Errorf("CustomizeColumn should have column %s", col) + } + + col = "mapped_id" + if scope.PrimaryKey() != col { + t.Errorf("CustomizeColumn should have primary key %s, but got %q", col, scope.PrimaryKey()) + } + + expected := "foo" + cc := CustomizeColumn{Id: 666, Name: expected, Date: time.Now()} + + if count := DB.Save(&cc).RowsAffected; count != 1 { + t.Error("There should be one record be affected when create record") + } + + var ccs []CustomizeColumn + DB.Find(&ccs) + + if len(ccs) > 0 && ccs[0].Name != expected && ccs[0].Id != 666 { + t.Errorf("Failed to query CustomizeColumn") + } +} diff --git a/scope.go b/scope.go index 300054f4..006259a8 100644 --- a/scope.go +++ b/scope.go @@ -175,13 +175,20 @@ func (scope *Scope) CallMethod(name string) { call := func(value interface{}) { if fm := reflect.ValueOf(value).MethodByName(name); fm.IsValid() { switch f := fm.Interface().(type) { - case func(): f() - case func(s *Scope): f(scope) - case func(s *DB): f(scope.db.new()) - case func() error: scope.Err(f()) - case func(s *Scope) error: scope.Err(f(scope)) - case func(s *DB) error: scope.Err(f(scope.db.new())) - default: scope.Err(errors.New(fmt.Sprintf("unsupported function %v", name))) + case func(): + f() + case func(s *Scope): + f(scope) + case func(s *DB): + f(scope.db.new()) + case func() error: + scope.Err(f()) + case func(s *Scope) error: + scope.Err(f(scope)) + case func(s *DB) error: + scope.Err(f(scope.db.new())) + default: + scope.Err(errors.New(fmt.Sprintf("unsupported function %v", name))) } } } @@ -275,7 +282,6 @@ func (scope *Scope) FieldByName(name string) (field *Field, ok bool) { func (scope *Scope) fieldFromStruct(fieldStruct reflect.StructField, withRelation bool) []*Field { var field Field field.Name = fieldStruct.Name - field.DBName = ToSnake(fieldStruct.Name) value := scope.IndirectValue().FieldByName(fieldStruct.Name) indirectValue := reflect.Indirect(value) @@ -290,6 +296,12 @@ func (scope *Scope) fieldFromStruct(fieldStruct reflect.StructField, withRelatio field.Tag = fieldStruct.Tag + if value, ok := settings["COLUMN"]; ok { + field.DBName = value + } else { + field.DBName = ToSnake(fieldStruct.Name) + } + tagIdentifier := "sql" if scope.db != nil { tagIdentifier = scope.db.parent.tagIdentifier