ParseWithSpecialTableName get data type from dialector with extra schema table
(dest interface{}, cacheStore *sync.Map, namer Namer, specialTableName string)
| 137 | |
| 138 | // ParseWithSpecialTableName get data type from dialector with extra schema table |
| 139 | func ParseWithSpecialTableName(dest interface{}, cacheStore *sync.Map, namer Namer, specialTableName string) (*Schema, error) { |
| 140 | if dest == nil { |
| 141 | return nil, fmt.Errorf("%w: %+v", ErrUnsupportedDataType, dest) |
| 142 | } |
| 143 | |
| 144 | modelType := reflect.ValueOf(dest).Type() |
| 145 | if modelType.Kind() == reflect.Ptr { |
| 146 | modelType = modelType.Elem() |
| 147 | } |
| 148 | |
| 149 | if modelType.Kind() != reflect.Struct { |
| 150 | if modelType.Kind() == reflect.Interface { |
| 151 | modelType = reflect.Indirect(reflect.ValueOf(dest)).Elem().Type() |
| 152 | } |
| 153 | |
| 154 | for modelType.Kind() == reflect.Slice || modelType.Kind() == reflect.Array || modelType.Kind() == reflect.Ptr { |
| 155 | modelType = modelType.Elem() |
| 156 | } |
| 157 | |
| 158 | if modelType.Kind() != reflect.Struct { |
| 159 | if modelType.PkgPath() == "" { |
| 160 | return nil, fmt.Errorf("%w: %+v", ErrUnsupportedDataType, dest) |
| 161 | } |
| 162 | return nil, fmt.Errorf("%w: %s.%s", ErrUnsupportedDataType, modelType.PkgPath(), modelType.Name()) |
| 163 | } |
| 164 | } |
| 165 | |
| 166 | // Cache the Schema for performance, |
| 167 | // Use the modelType or modelType + schemaTable (if it present) as cache key. |
| 168 | var schemaCacheKey interface{} = modelType |
| 169 | if specialTableName != "" { |
| 170 | schemaCacheKey = fmt.Sprintf("%p-%s", modelType, specialTableName) |
| 171 | } |
| 172 | |
| 173 | // Load exist schema cache, return if exists |
| 174 | if v, ok := cacheStore.Load(schemaCacheKey); ok { |
| 175 | s := v.(*Schema) |
| 176 | // Wait for the initialization of other goroutines to complete |
| 177 | <-s.initialized |
| 178 | return s, s.err |
| 179 | } |
| 180 | |
| 181 | var tableName string |
| 182 | modelValue := reflect.New(modelType) |
| 183 | if specialTableName != "" { |
| 184 | tableName = specialTableName |
| 185 | } else if en, ok := namer.(embeddedNamer); ok { |
| 186 | tableName = en.Table |
| 187 | } else if tabler, ok := modelValue.Interface().(Tabler); ok { |
| 188 | tableName = tabler.TableName() |
| 189 | } else if tabler, ok := modelValue.Interface().(TablerWithNamer); ok { |
| 190 | tableName = tabler.TableName(namer) |
| 191 | } else { |
| 192 | tableName = namer.TableName(modelType.Name()) |
| 193 | } |
| 194 | |
| 195 | schema := &Schema{ |
| 196 | Name: modelType.Name(), |
no test coverage detected