From 2d0b215ef4dc42d4b3a0cb255fa3f69bcab3f984 Mon Sep 17 00:00:00 2001 From: Arseny Sazanov Date: Fri, 29 Jan 2021 02:21:01 +0300 Subject: [PATCH] upgrade ORM alias support --- reflect/orm/orm.go | 28 +++++++++++++++++++++------ reflect/orm/orm_test.go | 42 ++++++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 15 deletions(-) diff --git a/reflect/orm/orm.go b/reflect/orm/orm.go index 8005c20..63365b5 100644 --- a/reflect/orm/orm.go +++ b/reflect/orm/orm.go @@ -34,6 +34,7 @@ type ( Aliases []Alias Join Join TableName Table + TableAlias Alias StructName Typ } ) @@ -45,8 +46,10 @@ var ( // custom tag for "sugar" columns values prepare for Update squirrel library staff const ( - tagDB = "db" // must be for all DTO structs fields, this tag also used by sqlx - tagOrmUseIN = "orm_use_in" + tagDB = "db" // must be for all DTO structs fields, this tag also used by sqlx + tagOrmUseIN = "orm_use_in" + + underscored = "_" // special name fo field contains tag orn_tab_name, orm_alias, orm_join tagOrmAlias = "orm_alias" tagOrmJoin = "orm_join" tagOrmTableName = "orm_table_name" @@ -108,17 +111,28 @@ func GetDataForUpdate(obj interface{}) map[Column]Argument { return cv } -func GetTableName(obj interface{}) string { +func GetTableName(obj interface{}) Table { meta := GetMetaDTO(obj) return meta.TableName } +func GetTableAlias(obj interface{}) Alias { + meta := GetMetaDTO(obj) + return meta.TableAlias +} + +func GetTableNameWithAlias(obj interface{}) string { + meta := GetMetaDTO(obj) + if meta.TableName != "" && meta.TableAlias != "" { + return meta.TableName + " as " + meta.TableAlias + } + return "" +} + func getNoneCacheMetaDTO(obj interface{}) *MetaDTO { meta := &MetaDTO{ ColsMap: map[ormUseInTagValue][]Column{ormUseInSelect: {}, ormUseInCreate: {}, ormUseInUpdate: {}}, Aliases: []Alias{}, - Join: "", - TableName: "", StructName: getObjTypeNameByReflect(obj), } if obj == nil { @@ -129,6 +143,8 @@ func getNoneCacheMetaDTO(obj interface{}) *MetaDTO { meta.TableName = getMetaInfoForOrmTagOnlyOne(tagOrmTableName, obj) + meta.TableAlias = getMetaInfoForOrmTagOnlyOne(tagOrmAlias, obj) + meta.Aliases = getMetaInfoForOrmAliasTag(obj) for _, v := range []string{ormUseInSelect, ormUseInCreate, ormUseInUpdate} { @@ -156,7 +172,7 @@ func getMetaInfoForOrmTagOnlyOne(value ormUseInTagValue, obj interface{}) string for i := 0; i < t.NumField(); i++ { field := t.Field(i) - if tagValue := field.Tag.Get(value); !isTagEmpty(tagValue) { + if tagValue := field.Tag.Get(value); !isTagEmpty(tagValue) && field.Name == underscored { return tagValue // we search first usage of tag, for high root component only, } } diff --git a/reflect/orm/orm_test.go b/reflect/orm/orm_test.go index ef96b40..7dbe6f2 100644 --- a/reflect/orm/orm_test.go +++ b/reflect/orm/orm_test.go @@ -10,10 +10,10 @@ import ( type ( BaseDTO struct { - ID int64 `db:"id" orm_use_in:"select"` - CreatedAt time.Time `db:"created_at" orm_use_in:"select"` - UpdatedAt time.Time `db:"updated_at" orm_use_in:"select,update"` - _ bool `orm_use_in:"select,create,update"` + ID int64 `db:"id" orm_use_in:"select"` + CreatedAt time.Time `db:"created_at" orm_use_in:"select"` + UpdatedAt time.Time `db:"updated_at" orm_use_in:"select,update"` + _ interface{} `orm_use_in:"select,create,update"` } A struct { @@ -23,14 +23,14 @@ type ( UpdateOnly int `db:"update_field" orm_use_in:"update"` NoDbTagField string `orm_use_for:"update"` NoTagField string - _ bool `orm_table_name:"A"` + _ interface{} `orm_table_name:"A" orm_alias:"a"` } B struct { BaseDTO - CUS float64 `db:"cus_field" orm_use_in:"create,update,select"` - CUS2 int `db:"cus2_field" orm_use_in:"create,update,select"` - _ bool `orm_table_name:"B"` + CUS float64 `db:"cus_field" orm_use_in:"create,update,select"` + CUS2 int `db:"cus2_field" orm_use_in:"create,update,select"` + _ interface{} `orm_table_name:"B" orm_alias:"b"` } C struct { @@ -41,7 +41,8 @@ type ( BadStruct struct { *A - _ struct{ a int } + _ struct{ a int } + bad_name_field interface{} `orm_table_name:"B" orm_alias:"b"` } ) @@ -177,4 +178,27 @@ func (suite *OrmTestSuit) Test_GetTableName() { assert.Equal(t, "B", GetTableName(&B{})) assert.Equal(t, "", GetTableName(&C{})) assert.Equal(t, "", GetTableName(nil)) + assert.Equal(t, "", GetTableName(&BadStruct{})) +} + +func (suite *OrmTestSuit) Test_GetTableAlias() { + t := suite.T() + + assert.Equal(t, "a", GetTableAlias(&A{})) + assert.Equal(t, "b", GetTableAlias(&B{})) + assert.Equal(t, "", GetTableAlias(&C{})) + assert.Equal(t, "", GetTableAlias(nil)) + assert.Equal(t, "", GetTableAlias(&BadStruct{})) +} + +func (suite *OrmTestSuit) Test_GetTableNameWithAlias() { + t := suite.T() + + _ = BadStruct{}.bad_name_field + + assert.Equal(t, "A as a", GetTableNameWithAlias(&A{})) + assert.Equal(t, "B as b", GetTableNameWithAlias(&B{})) + assert.Equal(t, "", GetTableNameWithAlias(&C{})) + assert.Equal(t, "", GetTableNameWithAlias(nil)) + assert.Equal(t, "", GetTableNameWithAlias(&BadStruct{})) }