add dynamic table support
This commit is contained in:
parent
c10f807d3c
commit
f231b96237
@ -90,6 +90,10 @@ func (schema Schema) LookUpFieldByBindName(bindNames []string, name string) *Fie
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DynamicTabler interface {
|
||||||
|
DynamicTableName() string
|
||||||
|
}
|
||||||
|
|
||||||
type Tabler interface {
|
type Tabler interface {
|
||||||
TableName() string
|
TableName() string
|
||||||
}
|
}
|
||||||
@ -98,22 +102,15 @@ type TablerWithNamer interface {
|
|||||||
TableName(Namer) string
|
TableName(Namer) string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse get data type from dialector
|
func getSchemaCacheKeyAndModelType(dest interface{}) (modelType reflect.Type, tableName string, err error) {
|
||||||
func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) {
|
|
||||||
return ParseWithSpecialTableName(dest, cacheStore, namer, "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// ParseWithSpecialTableName get data type from dialector with extra schema table
|
|
||||||
func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Namer, specialTableName string) (*Schema, error) {
|
|
||||||
if dest == nil {
|
if dest == nil {
|
||||||
return nil, fmt.Errorf("%w: %+v", ErrUnsupportedDataType, dest)
|
return nil, "", fmt.Errorf("%w: %+v", ErrUnsupportedDataType, dest)
|
||||||
}
|
}
|
||||||
|
|
||||||
value := reflect.ValueOf(dest)
|
value := reflect.ValueOf(dest)
|
||||||
if value.Kind() == reflect.Ptr && value.IsNil() {
|
if value.Kind() == reflect.Ptr && value.IsNil() {
|
||||||
value = reflect.New(value.Type().Elem())
|
value = reflect.New(value.Type().Elem())
|
||||||
}
|
}
|
||||||
modelType := reflect.Indirect(value).Type()
|
modelType = reflect.Indirect(value).Type()
|
||||||
|
|
||||||
if modelType.Kind() == reflect.Interface {
|
if modelType.Kind() == reflect.Interface {
|
||||||
modelType = reflect.Indirect(reflect.ValueOf(dest)).Elem().Type()
|
modelType = reflect.Indirect(reflect.ValueOf(dest)).Elem().Type()
|
||||||
@ -125,9 +122,29 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam
|
|||||||
|
|
||||||
if modelType.Kind() != reflect.Struct {
|
if modelType.Kind() != reflect.Struct {
|
||||||
if modelType.PkgPath() == "" {
|
if modelType.PkgPath() == "" {
|
||||||
return nil, fmt.Errorf("%w: %+v", ErrUnsupportedDataType, dest)
|
return nil, "", fmt.Errorf("%w: %+v", ErrUnsupportedDataType, dest)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("%w: %s.%s", ErrUnsupportedDataType, modelType.PkgPath(), modelType.Name())
|
return nil, "", fmt.Errorf("%w: %s.%s", ErrUnsupportedDataType, modelType.PkgPath(), modelType.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
if value.CanInterface() {
|
||||||
|
if tabler, ok := value.Interface().(DynamicTabler); ok {
|
||||||
|
tableName = tabler.DynamicTableName()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse get data type from dialector
|
||||||
|
func Parse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) {
|
||||||
|
return ParseWithSpecialTableName(dest, cacheStore, namer, "")
|
||||||
|
}
|
||||||
|
|
||||||
|
// ParseWithSpecialTableName get data type from dialector with extra schema table
|
||||||
|
func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Namer, specialTableName string) (*Schema, error) {
|
||||||
|
modelType, tableName, err := getSchemaCacheKeyAndModelType(dest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache the Schema for performance,
|
// Cache the Schema for performance,
|
||||||
@ -135,6 +152,8 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam
|
|||||||
var schemaCacheKey interface{}
|
var schemaCacheKey interface{}
|
||||||
if specialTableName != "" {
|
if specialTableName != "" {
|
||||||
schemaCacheKey = fmt.Sprintf("%p-%s", modelType, specialTableName)
|
schemaCacheKey = fmt.Sprintf("%p-%s", modelType, specialTableName)
|
||||||
|
} else if tableName != "" {
|
||||||
|
schemaCacheKey = tableName
|
||||||
} else {
|
} else {
|
||||||
schemaCacheKey = modelType
|
schemaCacheKey = modelType
|
||||||
}
|
}
|
||||||
@ -148,15 +167,17 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam
|
|||||||
}
|
}
|
||||||
|
|
||||||
modelValue := reflect.New(modelType)
|
modelValue := reflect.New(modelType)
|
||||||
tableName := namer.TableName(modelType.Name())
|
if tableName == "" {
|
||||||
if tabler, ok := modelValue.Interface().(Tabler); ok {
|
tableName = namer.TableName(modelType.Name())
|
||||||
tableName = tabler.TableName()
|
if tabler, ok := modelValue.Interface().(Tabler); ok {
|
||||||
}
|
tableName = tabler.TableName()
|
||||||
if tabler, ok := modelValue.Interface().(TablerWithNamer); ok {
|
}
|
||||||
tableName = tabler.TableName(namer)
|
if tabler, ok := modelValue.Interface().(TablerWithNamer); ok {
|
||||||
}
|
tableName = tabler.TableName(namer)
|
||||||
if en, ok := namer.(embeddedNamer); ok {
|
}
|
||||||
tableName = en.Table
|
if en, ok := namer.(embeddedNamer); ok {
|
||||||
|
tableName = en.Table
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if specialTableName != "" && specialTableName != tableName {
|
if specialTableName != "" && specialTableName != tableName {
|
||||||
tableName = specialTableName
|
tableName = specialTableName
|
||||||
@ -350,19 +371,18 @@ func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Nam
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getOrParse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) {
|
func getOrParse(dest interface{}, cacheStore *sync.Map, namer Namer) (*Schema, error) {
|
||||||
modelType := reflect.ValueOf(dest).Type()
|
modelType, tableName, err := getSchemaCacheKeyAndModelType(dest)
|
||||||
for modelType.Kind() == reflect.Slice || modelType.Kind() == reflect.Array || modelType.Kind() == reflect.Ptr {
|
if err != nil {
|
||||||
modelType = modelType.Elem()
|
return nil, err
|
||||||
|
}
|
||||||
|
var schemaCacheKey interface{}
|
||||||
|
if tableName != "" {
|
||||||
|
schemaCacheKey = tableName
|
||||||
|
} else {
|
||||||
|
schemaCacheKey = modelType
|
||||||
}
|
}
|
||||||
|
|
||||||
if modelType.Kind() != reflect.Struct {
|
if v, ok := cacheStore.Load(schemaCacheKey); ok {
|
||||||
if modelType.PkgPath() == "" {
|
|
||||||
return nil, fmt.Errorf("%w: %+v", ErrUnsupportedDataType, dest)
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("%w: %s.%s", ErrUnsupportedDataType, modelType.PkgPath(), modelType.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
if v, ok := cacheStore.Load(modelType); ok {
|
|
||||||
return v.(*Schema), nil
|
return v.(*Schema), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user