parent
90106d82c5
commit
eb26dcc597
20
README.md
20
README.md
@ -974,6 +974,26 @@ type Animal struct {
|
||||
}
|
||||
```
|
||||
|
||||
If your column names differ from the struct fields, you can specify them like this:
|
||||
|
||||
```go
|
||||
type Animal struct { // animals
|
||||
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"`
|
||||
}
|
||||
```
|
||||
|
||||
Note that if your primary key has a custom column name, you will still have to
|
||||
specify `primary_key`, even if your struct field is named `Id`:
|
||||
|
||||
```go
|
||||
type Foo struct {
|
||||
Id int64 `gorm:"column:foo_id; primary_key:yes"`
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## More examples with query chain
|
||||
|
||||
```go
|
||||
|
@ -41,6 +41,19 @@ func Query(scope *Scope) {
|
||||
return
|
||||
}
|
||||
|
||||
colToFieldMap := make(map[string]string)
|
||||
if destType != nil && destType.Kind() == reflect.Struct {
|
||||
for i := 0; i < destType.NumField(); i++ {
|
||||
fieldName := destType.Field(i).Name
|
||||
dbColumnName := ToSnake(fieldName)
|
||||
settings := parseTagSetting(destType.Field(i).Tag.Get("gorm"))
|
||||
if colName, ok := settings["COLUMN"]; ok && colName != "" {
|
||||
dbColumnName = colName
|
||||
}
|
||||
colToFieldMap[dbColumnName] = fieldName
|
||||
}
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
anyRecordFound = true
|
||||
@ -52,7 +65,11 @@ func Query(scope *Scope) {
|
||||
columns, _ := rows.Columns()
|
||||
var values []interface{}
|
||||
for _, value := range columns {
|
||||
field := elem.FieldByName(SnakeToUpperCamel(strings.ToLower(value)))
|
||||
fieldName, ok := colToFieldMap[value]
|
||||
if !ok {
|
||||
fieldName = SnakeToUpperCamel(strings.ToLower(value))
|
||||
}
|
||||
field := elem.FieldByName(fieldName)
|
||||
if field.IsValid() {
|
||||
values = append(values, field.Addr().Interface())
|
||||
} else {
|
||||
|
37
main_test.go
37
main_test.go
@ -553,3 +553,40 @@ func BenchmarkRawSql(b *testing.B) {
|
||||
db.Exec(delete_sql, id)
|
||||
}
|
||||
}
|
||||
|
||||
type MappedFields struct {
|
||||
Id int64 `gorm:"column:mapped_id; primary_key:yes"`
|
||||
Name string `gorm:"column:mapped_name"`
|
||||
Date time.Time `gorm:"column:mapped_time"`
|
||||
}
|
||||
|
||||
func TestMappedFields(t *testing.T) {
|
||||
col := "mapped_name"
|
||||
db := db.Model("")
|
||||
scope := db.NewScope(&MappedFields{})
|
||||
if !scope.Dialect().HasColumn(scope, "mapped_fields", col) {
|
||||
t.Errorf("MappedFields should have column %s", col)
|
||||
}
|
||||
col = "mapped_id"
|
||||
if scope.PrimaryKey() != col {
|
||||
t.Errorf("MappedFields should have primary key %s, but got %q", col, scope.PrimaryKey())
|
||||
}
|
||||
|
||||
expected := "foo"
|
||||
mf := MappedFields{Id: 666, Name: expected, Date: time.Now()}
|
||||
if !db.NewRecord(mf) || !db.NewRecord(&mf) {
|
||||
t.Error("MappedFields should be new record before create")
|
||||
}
|
||||
if count := db.Save(&mf).RowsAffected; count != 1 {
|
||||
t.Error("There should be one record be affected when create record")
|
||||
}
|
||||
|
||||
var mfs []MappedFields
|
||||
db.Table("mapped_fields").Find(&mfs)
|
||||
if len(mfs) != 1 {
|
||||
t.Errorf("Query from specified table")
|
||||
}
|
||||
if len(mfs) > 0 && mfs[0].Name != expected {
|
||||
t.Errorf("Failed to query MappedFields, expected %q, got %q", expected, mfs[0].Name)
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ func runMigration() {
|
||||
db.Exec("drop table animals")
|
||||
db.Exec("drop table user_languages")
|
||||
db.Exec("drop table languages")
|
||||
db.Exec("drop table mapped_fields")
|
||||
|
||||
if err := db.CreateTable(&Animal{}).Error; err != nil {
|
||||
panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
|
||||
@ -37,6 +38,10 @@ func runMigration() {
|
||||
panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
|
||||
}
|
||||
|
||||
if err := db.CreateTable(MappedFields{}).Error; err != nil {
|
||||
panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
|
||||
}
|
||||
|
||||
if err := db.AutoMigrate(Address{}).Error; err != nil {
|
||||
panic(fmt.Sprintf("No error should happen when create table, but got %+v", err))
|
||||
}
|
||||
|
4
scope.go
4
scope.go
@ -258,6 +258,10 @@ func (scope *Scope) fieldFromStruct(fieldStruct reflect.StructField) *Field {
|
||||
|
||||
// Search for primary key tag identifier
|
||||
settings := parseTagSetting(fieldStruct.Tag.Get("gorm"))
|
||||
if colName, ok := settings["COLUMN"]; ok && colName != "" {
|
||||
field.DBName = colName
|
||||
}
|
||||
|
||||
if scope.PrimaryKey() == field.DBName {
|
||||
field.IsPrimaryKey = true
|
||||
}
|
||||
|
3
utils.go
3
utils.go
@ -109,6 +109,9 @@ func GetPrimaryKey(value interface{}) string {
|
||||
|
||||
settings := parseTagSetting(fieldStruct.Tag.Get("gorm"))
|
||||
if _, ok := settings["PRIMARY_KEY"]; ok {
|
||||
if colName, ok2 := settings["COLUMN"]; ok2 {
|
||||
return colName
|
||||
}
|
||||
return fieldStruct.Name
|
||||
} else if fieldStruct.Name == "Id" {
|
||||
hasId = true
|
||||
|
Loading…
x
Reference in New Issue
Block a user