Allow customize table name with TableName

This commit is contained in:
Jinzhu 2020-06-02 15:48:19 +08:00
parent e959a67f87
commit 2218e32999
2 changed files with 30 additions and 3 deletions

View File

@ -82,6 +82,10 @@ func (schema Schema) LookUpField(name string) *Field {
return nil return nil
} }
type Tabler interface {
TableName() string
}
// get data type from dialector // get data type from dialector
func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) { func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) {
modelType := reflect.ValueOf(dest).Type() modelType := reflect.ValueOf(dest).Type()
@ -100,10 +104,16 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error)
return v.(*Schema), nil return v.(*Schema), nil
} }
modelValue := reflect.New(modelType)
tableName := namer.TableName(modelType.Name())
if tabler, ok := modelValue.Interface().(Tabler); ok {
tableName = tabler.TableName()
}
schema := &Schema{ schema := &Schema{
Name: modelType.Name(), Name: modelType.Name(),
ModelType: modelType, ModelType: modelType,
Table: namer.TableName(modelType.Name()), Table: tableName,
FieldsByName: map[string]*Field{}, FieldsByName: map[string]*Field{},
FieldsByDBName: map[string]*Field{}, FieldsByDBName: map[string]*Field{},
Relationships: Relationships{Relations: map[string]*Relationship{}}, Relationships: Relationships{Relations: map[string]*Relationship{}},
@ -200,10 +210,9 @@ func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error)
} }
} }
reflectValue := reflect.New(modelType)
callbacks := []string{"BeforeCreate", "AfterCreate", "BeforeUpdate", "AfterUpdate", "BeforeSave", "AfterSave", "BeforeDelete", "AfterDelete", "AfterFind"} callbacks := []string{"BeforeCreate", "AfterCreate", "BeforeUpdate", "AfterUpdate", "BeforeSave", "AfterSave", "BeforeDelete", "AfterDelete", "AfterFind"}
for _, name := range callbacks { for _, name := range callbacks {
if methodValue := reflectValue.MethodByName(name); methodValue.IsValid() { if methodValue := modelValue.MethodByName(name); methodValue.IsValid() {
switch methodValue.Type().String() { switch methodValue.Type().String() {
case "func(*gorm.DB) error": // TODO hack case "func(*gorm.DB) error": // TODO hack
reflect.Indirect(reflect.ValueOf(schema)).FieldByName(name).SetBool(true) reflect.Indirect(reflect.ValueOf(schema)).FieldByName(name).SetBool(true)

View File

@ -142,3 +142,21 @@ func TestParseSchemaWithAdvancedDataType(t *testing.T) {
}) })
} }
} }
type CustomizeTable struct {
}
func (CustomizeTable) TableName() string {
return "customize"
}
func TestCustomizeTableName(t *testing.T) {
customize, err := schema.Parse(&CustomizeTable{}, &sync.Map{}, schema.NamingStrategy{})
if err != nil {
t.Fatalf("failed to parse pointer user, got error %v", err)
}
if customize.Table != "customize" {
t.Errorf("Failed to customize table with TableName method")
}
}