Refactor ORM: rename _modelCache struct to modelCache

This commit is contained in:
greenhandatsjtu 2022-05-21 10:06:31 +08:00
parent 411fbb8cdb
commit f9d2b4cb9a
10 changed files with 52 additions and 50 deletions

View File

@ -100,7 +100,7 @@ func (d *commandSyncDb) Run() error {
var drops []string var drops []string
var err error var err error
if d.force { if d.force {
drops, err = modelCache.getDbDropSQL(d.al) drops, err = defaultModelCache.getDbDropSQL(d.al)
if err != nil { if err != nil {
return err return err
} }
@ -109,7 +109,7 @@ func (d *commandSyncDb) Run() error {
db := d.al.DB db := d.al.DB
if d.force && len(drops) > 0 { if d.force && len(drops) > 0 {
for i, mi := range modelCache.allOrdered() { for i, mi := range defaultModelCache.allOrdered() {
query := drops[i] query := drops[i]
if !d.noInfo { if !d.noInfo {
fmt.Printf("drop table `%s`\n", mi.table) fmt.Printf("drop table `%s`\n", mi.table)
@ -127,7 +127,7 @@ func (d *commandSyncDb) Run() error {
} }
} }
createQueries, indexes, err := modelCache.getDbCreateSQL(d.al) createQueries, indexes, err := defaultModelCache.getDbCreateSQL(d.al)
if err != nil { if err != nil {
return err return err
} }
@ -141,7 +141,7 @@ func (d *commandSyncDb) Run() error {
} }
ctx := context.Background() ctx := context.Background()
for i, mi := range modelCache.allOrdered() { for i, mi := range defaultModelCache.allOrdered() {
if !isApplicableTableForDB(mi.addrField, d.al.Name) { if !isApplicableTableForDB(mi.addrField, d.al.Name) {
fmt.Printf("table `%s` is not applicable to database '%s'\n", mi.table, d.al.Name) fmt.Printf("table `%s` is not applicable to database '%s'\n", mi.table, d.al.Name)
@ -258,12 +258,12 @@ func (d *commandSQLAll) Parse(args []string) {
// Run orm line command. // Run orm line command.
func (d *commandSQLAll) Run() error { func (d *commandSQLAll) Run() error {
createQueries, indexes, err := modelCache.getDbCreateSQL(d.al) createQueries, indexes, err := defaultModelCache.getDbCreateSQL(d.al)
if err != nil { if err != nil {
return err return err
} }
var all []string var all []string
for i, mi := range modelCache.allOrdered() { for i, mi := range defaultModelCache.allOrdered() {
queries := []string{createQueries[i]} queries := []string{createQueries[i]}
for _, idx := range indexes[mi.table] { for _, idx := range indexes[mi.table] {
queries = append(queries, idx.SQL) queries = append(queries, idx.SQL)

View File

@ -1038,7 +1038,7 @@ func (d *dbBase) ReadBatch(ctx context.Context, q dbQuerier, qs *querySet, mi *m
slice := ind slice := ind
if unregister { if unregister {
mi, _ = modelCache.get(name) mi, _ = defaultModelCache.get(name)
tCols = mi.fields.dbcols tCols = mi.fields.dbcols
colsNum = len(tCols) colsNum = len(tCols)
} }

View File

@ -156,7 +156,7 @@ outFor:
typ := val.Type() typ := val.Type()
name := getFullName(typ) name := getFullName(typ)
var value interface{} var value interface{}
if mmi, ok := modelCache.getByFullName(name); ok { if mmi, ok := defaultModelCache.getByFullName(name); ok {
if _, vu, exist := getExistPk(mmi, val); exist { if _, vu, exist := getExistPk(mmi, val); exist {
value = vu value = vu
} }

View File

@ -78,7 +78,7 @@ func (f *filterOrmDecorator) Read(md interface{}, cols ...string) error {
} }
func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error { func (f *filterOrmDecorator) ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "ReadWithCtx", Method: "ReadWithCtx",
Args: []interface{}{md, cols}, Args: []interface{}{md, cols},
@ -100,7 +100,7 @@ func (f *filterOrmDecorator) ReadForUpdate(md interface{}, cols ...string) error
} }
func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error { func (f *filterOrmDecorator) ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "ReadForUpdateWithCtx", Method: "ReadForUpdateWithCtx",
Args: []interface{}{md, cols}, Args: []interface{}{md, cols},
@ -122,7 +122,7 @@ func (f *filterOrmDecorator) ReadOrCreate(md interface{}, col1 string, cols ...s
} }
func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) { func (f *filterOrmDecorator) ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "ReadOrCreateWithCtx", Method: "ReadOrCreateWithCtx",
Args: []interface{}{md, col1, cols}, Args: []interface{}{md, col1, cols},
@ -144,7 +144,7 @@ func (f *filterOrmDecorator) LoadRelated(md interface{}, name string, args ...ut
} }
func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) { func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "LoadRelatedWithCtx", Method: "LoadRelatedWithCtx",
Args: []interface{}{md, name, args}, Args: []interface{}{md, name, args},
@ -162,7 +162,7 @@ func (f *filterOrmDecorator) LoadRelatedWithCtx(ctx context.Context, md interfac
} }
func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer { func (f *filterOrmDecorator) QueryM2M(md interface{}, name string) QueryM2Mer {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "QueryM2M", Method: "QueryM2M",
Args: []interface{}{md, name}, Args: []interface{}{md, name},
@ -202,7 +202,7 @@ func (f *filterOrmDecorator) QueryTable(ptrStructOrTableName interface{}) QueryS
md = ptrStructOrTableName md = ptrStructOrTableName
} }
if m, ok := modelCache.getByFullName(name); ok { if m, ok := defaultModelCache.getByFullName(name); ok {
mi = m mi = m
} }
@ -256,7 +256,7 @@ func (f *filterOrmDecorator) Insert(md interface{}) (int64, error) {
} }
func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) { func (f *filterOrmDecorator) InsertWithCtx(ctx context.Context, md interface{}) (int64, error) {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "InsertWithCtx", Method: "InsertWithCtx",
Args: []interface{}{md}, Args: []interface{}{md},
@ -278,7 +278,7 @@ func (f *filterOrmDecorator) InsertOrUpdate(md interface{}, colConflitAndArgs ..
} }
func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) { func (f *filterOrmDecorator) InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "InsertOrUpdateWithCtx", Method: "InsertOrUpdateWithCtx",
Args: []interface{}{md, colConflitAndArgs}, Args: []interface{}{md, colConflitAndArgs},
@ -311,7 +311,7 @@ func (f *filterOrmDecorator) InsertMultiWithCtx(ctx context.Context, bulk int, m
if (sind.Kind() == reflect.Array || sind.Kind() == reflect.Slice) && sind.Len() > 0 { if (sind.Kind() == reflect.Array || sind.Kind() == reflect.Slice) && sind.Len() > 0 {
ind := reflect.Indirect(sind.Index(0)) ind := reflect.Indirect(sind.Index(0))
md = ind.Interface() md = ind.Interface()
mi, _ = modelCache.getByMd(md) mi, _ = defaultModelCache.getByMd(md)
} }
inv := &Invocation{ inv := &Invocation{
@ -335,7 +335,7 @@ func (f *filterOrmDecorator) Update(md interface{}, cols ...string) (int64, erro
} }
func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) { func (f *filterOrmDecorator) UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "UpdateWithCtx", Method: "UpdateWithCtx",
Args: []interface{}{md, cols}, Args: []interface{}{md, cols},
@ -357,7 +357,7 @@ func (f *filterOrmDecorator) Delete(md interface{}, cols ...string) (int64, erro
} }
func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) { func (f *filterOrmDecorator) DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) {
mi, _ := modelCache.getByMd(md) mi, _ := defaultModelCache.getByMd(md)
inv := &Invocation{ inv := &Invocation{
Method: "DeleteWithCtx", Method: "DeleteWithCtx",
Args: []interface{}{md, cols}, Args: []interface{}{md, cols},

View File

@ -49,7 +49,7 @@ func (i *Interface) TableEngine() string {
func TestDbBase_GetTables(t *testing.T) { func TestDbBase_GetTables(t *testing.T) {
RegisterModel(&Interface{}) RegisterModel(&Interface{})
mi, ok := modelCache.get("INTERFACE_") mi, ok := defaultModelCache.get("INTERFACE_")
assert.True(t, ok) assert.True(t, ok)
assert.NotNil(t, mi) assert.NotNil(t, mi)

View File

@ -32,10 +32,10 @@ const (
defaultStructTagDelim = ";" defaultStructTagDelim = ";"
) )
var modelCache = NewModelCacheHandler() var defaultModelCache = NewModelCacheHandler()
// model info collection // model info collection
type _modelCache struct { type modelCache struct {
sync.RWMutex // only used outsite for bootStrap sync.RWMutex // only used outsite for bootStrap
orders []string orders []string
cache map[string]*modelInfo cache map[string]*modelInfo
@ -43,16 +43,16 @@ type _modelCache struct {
done bool done bool
} }
// NewModelCacheHandler generator of _modelCache // NewModelCacheHandler generator of modelCache
func NewModelCacheHandler() *_modelCache { func NewModelCacheHandler() *modelCache {
return &_modelCache{ return &modelCache{
cache: make(map[string]*modelInfo), cache: make(map[string]*modelInfo),
cacheByFullName: make(map[string]*modelInfo), cacheByFullName: make(map[string]*modelInfo),
} }
} }
// get all model info // get all model info
func (mc *_modelCache) all() map[string]*modelInfo { func (mc *modelCache) all() map[string]*modelInfo {
m := make(map[string]*modelInfo, len(mc.cache)) m := make(map[string]*modelInfo, len(mc.cache))
for k, v := range mc.cache { for k, v := range mc.cache {
m[k] = v m[k] = v
@ -61,7 +61,7 @@ func (mc *_modelCache) all() map[string]*modelInfo {
} }
// get ordered model info // get ordered model info
func (mc *_modelCache) allOrdered() []*modelInfo { func (mc *modelCache) allOrdered() []*modelInfo {
m := make([]*modelInfo, 0, len(mc.orders)) m := make([]*modelInfo, 0, len(mc.orders))
for _, table := range mc.orders { for _, table := range mc.orders {
m = append(m, mc.cache[table]) m = append(m, mc.cache[table])
@ -70,18 +70,18 @@ func (mc *_modelCache) allOrdered() []*modelInfo {
} }
// get model info by table name // get model info by table name
func (mc *_modelCache) get(table string) (mi *modelInfo, ok bool) { func (mc *modelCache) get(table string) (mi *modelInfo, ok bool) {
mi, ok = mc.cache[table] mi, ok = mc.cache[table]
return return
} }
// get model info by full name // get model info by full name
func (mc *_modelCache) getByFullName(name string) (mi *modelInfo, ok bool) { func (mc *modelCache) getByFullName(name string) (mi *modelInfo, ok bool) {
mi, ok = mc.cacheByFullName[name] mi, ok = mc.cacheByFullName[name]
return return
} }
func (mc *_modelCache) getByMd(md interface{}) (*modelInfo, bool) { func (mc *modelCache) getByMd(md interface{}) (*modelInfo, bool) {
val := reflect.ValueOf(md) val := reflect.ValueOf(md)
ind := reflect.Indirect(val) ind := reflect.Indirect(val)
typ := ind.Type() typ := ind.Type()
@ -90,7 +90,7 @@ func (mc *_modelCache) getByMd(md interface{}) (*modelInfo, bool) {
} }
// set model info to collection // set model info to collection
func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo { func (mc *modelCache) set(table string, mi *modelInfo) *modelInfo {
mii := mc.cache[table] mii := mc.cache[table]
mc.cache[table] = mi mc.cache[table] = mi
mc.cacheByFullName[mi.fullName] = mi mc.cacheByFullName[mi.fullName] = mi
@ -101,7 +101,7 @@ func (mc *_modelCache) set(table string, mi *modelInfo) *modelInfo {
} }
// clean all model info. // clean all model info.
func (mc *_modelCache) clean() { func (mc *modelCache) clean() {
mc.Lock() mc.Lock()
defer mc.Unlock() defer mc.Unlock()
@ -112,7 +112,7 @@ func (mc *_modelCache) clean() {
} }
// bootstrap bootstrap for models // bootstrap bootstrap for models
func (mc *_modelCache) bootstrap() { func (mc *modelCache) bootstrap() {
mc.Lock() mc.Lock()
defer mc.Unlock() defer mc.Unlock()
if mc.done { if mc.done {
@ -328,7 +328,7 @@ end:
} }
// register register models to model cache // register register models to model cache
func (mc *_modelCache) register(prefixOrSuffixStr string, prefixOrSuffix bool, models ...interface{}) (err error) { func (mc *modelCache) register(prefixOrSuffixStr string, prefixOrSuffix bool, models ...interface{}) (err error) {
for _, model := range models { for _, model := range models {
val := reflect.ValueOf(model) val := reflect.ValueOf(model)
typ := reflect.Indirect(val).Type() typ := reflect.Indirect(val).Type()
@ -395,7 +395,7 @@ func (mc *_modelCache) register(prefixOrSuffixStr string, prefixOrSuffix bool, m
} }
// getDbDropSQL get database scheme drop sql queries // getDbDropSQL get database scheme drop sql queries
func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) { func (mc *modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
if len(mc.cache) == 0 { if len(mc.cache) == 0 {
err = errors.New("no Model found, need register your model") err = errors.New("no Model found, need register your model")
return return
@ -410,7 +410,7 @@ func (mc *_modelCache) getDbDropSQL(al *alias) (queries []string, err error) {
} }
// getDbCreateSQL get database scheme creation sql queries // getDbCreateSQL get database scheme creation sql queries
func (mc *_modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes map[string][]dbIndex, err error) { func (mc *modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes map[string][]dbIndex, err error) {
if len(mc.cache) == 0 { if len(mc.cache) == 0 {
err = errors.New("no Model found, need register your model") err = errors.New("no Model found, need register your model")
return return
@ -552,5 +552,5 @@ func (mc *_modelCache) getDbCreateSQL(al *alias) (queries []string, tableIndexes
// ResetModelCache Clean model cache. Then you can re-RegisterModel. // ResetModelCache Clean model cache. Then you can re-RegisterModel.
// Common use this api for test case. // Common use this api for test case.
func ResetModelCache() { func ResetModelCache() {
modelCache.clean() defaultModelCache.clean()
} }

View File

@ -21,14 +21,14 @@ func RegisterModel(models ...interface{}) {
// RegisterModelWithPrefix register models with a prefix // RegisterModelWithPrefix register models with a prefix
func RegisterModelWithPrefix(prefix string, models ...interface{}) { func RegisterModelWithPrefix(prefix string, models ...interface{}) {
if err := modelCache.register(prefix, true, models...); err != nil { if err := defaultModelCache.register(prefix, true, models...); err != nil {
panic(err) panic(err)
} }
} }
// RegisterModelWithSuffix register models with a suffix // RegisterModelWithSuffix register models with a suffix
func RegisterModelWithSuffix(suffix string, models ...interface{}) { func RegisterModelWithSuffix(suffix string, models ...interface{}) {
if err := modelCache.register(suffix, false, models...); err != nil { if err := defaultModelCache.register(suffix, false, models...); err != nil {
panic(err) panic(err)
} }
} }
@ -36,5 +36,5 @@ func RegisterModelWithSuffix(suffix string, models ...interface{}) {
// BootStrap bootstrap models. // BootStrap bootstrap models.
// make all model parsed and can not add more models // make all model parsed and can not add more models
func BootStrap() { func BootStrap() {
modelCache.bootstrap() defaultModelCache.bootstrap()
} }

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build go1.8
// +build go1.8 // +build go1.8
// Package orm provide ORM for MySQL/PostgreSQL/sqlite // Package orm provide ORM for MySQL/PostgreSQL/sqlite
@ -130,7 +131,7 @@ func (*ormBase) getPtrMiInd(md interface{}) (mi *modelInfo, ind reflect.Value) {
func getTypeMi(mdTyp reflect.Type) *modelInfo { func getTypeMi(mdTyp reflect.Type) *modelInfo {
name := getFullName(mdTyp) name := getFullName(mdTyp)
if mi, ok := modelCache.getByFullName(name); ok { if mi, ok := defaultModelCache.getByFullName(name); ok {
return mi return mi
} }
panic(fmt.Errorf("<Ormer> table: `%s` not found, make sure it was registered with `RegisterModel()`", name)) panic(fmt.Errorf("<Ormer> table: `%s` not found, make sure it was registered with `RegisterModel()`", name))
@ -476,12 +477,12 @@ func (o *ormBase) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
var name string var name string
if table, ok := ptrStructOrTableName.(string); ok { if table, ok := ptrStructOrTableName.(string); ok {
name = nameStrategyMap[defaultNameStrategy](table) name = nameStrategyMap[defaultNameStrategy](table)
if mi, ok := modelCache.get(name); ok { if mi, ok := defaultModelCache.get(name); ok {
qs = newQuerySet(o, mi) qs = newQuerySet(o, mi)
} }
} else { } else {
name = getFullName(indirectType(reflect.TypeOf(ptrStructOrTableName))) name = getFullName(indirectType(reflect.TypeOf(ptrStructOrTableName)))
if mi, ok := modelCache.getByFullName(name); ok { if mi, ok := defaultModelCache.getByFullName(name); ok {
qs = newQuerySet(o, mi) qs = newQuerySet(o, mi)
} }
} }

View File

@ -314,7 +314,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
structMode = true structMode = true
fn := getFullName(typ) fn := getFullName(typ)
if mi, ok := modelCache.getByFullName(fn); ok { if mi, ok := defaultModelCache.getByFullName(fn); ok {
sMi = mi sMi = mi
} }
} else { } else {
@ -475,7 +475,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
structMode = true structMode = true
fn := getFullName(typ) fn := getFullName(typ)
if mi, ok := modelCache.getByFullName(fn); ok { if mi, ok := defaultModelCache.getByFullName(fn); ok {
sMi = mi sMi = mi
} }
} else { } else {

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
//go:build go1.8
// +build go1.8 // +build go1.8
package orm package orm
@ -214,7 +215,7 @@ func TestSyncDb(t *testing.T) {
err := RunSyncdb("default", true, Debug) err := RunSyncdb("default", true, Debug)
throwFail(t, err) throwFail(t, err)
modelCache.clean() defaultModelCache.clean()
} }
func TestRegisterModels(_ *testing.T) { func TestRegisterModels(_ *testing.T) {
@ -250,10 +251,10 @@ func TestModelSyntax(t *testing.T) {
user := &User{} user := &User{}
ind := reflect.ValueOf(user).Elem() ind := reflect.ValueOf(user).Elem()
fn := getFullName(ind.Type()) fn := getFullName(ind.Type())
_, ok := modelCache.getByFullName(fn) _, ok := defaultModelCache.getByFullName(fn)
throwFail(t, AssertIs(ok, true)) throwFail(t, AssertIs(ok, true))
mi, ok := modelCache.get("user") mi, ok := defaultModelCache.get("user")
throwFail(t, AssertIs(ok, true)) throwFail(t, AssertIs(ok, true))
if ok { if ok {
throwFail(t, AssertIs(mi.fields.GetByName("ShouldSkip") == nil, true)) throwFail(t, AssertIs(mi.fields.GetByName("ShouldSkip") == nil, true))
@ -2628,9 +2629,9 @@ func TestIgnoreCaseTag(t *testing.T) {
Name02 string `orm:"COLUMN(Name)"` Name02 string `orm:"COLUMN(Name)"`
Name03 string `orm:"Column(name)"` Name03 string `orm:"Column(name)"`
} }
modelCache.clean() defaultModelCache.clean()
RegisterModel(&testTagModel{}) RegisterModel(&testTagModel{})
info, ok := modelCache.get("test_tag_model") info, ok := defaultModelCache.get("test_tag_model")
throwFail(t, AssertIs(ok, true)) throwFail(t, AssertIs(ok, true))
throwFail(t, AssertNot(info, nil)) throwFail(t, AssertNot(info, nil))
if t == nil { if t == nil {