1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-26 07:51:30 +00:00

Merge pull request #3408 from nlimpid/develop

add different column name parse strategy
This commit is contained in:
astaxie 2018-11-21 17:18:39 +08:00 committed by GitHub
commit 2a8d6f943f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 5 deletions

View File

@ -109,7 +109,7 @@ func getTableUnique(val reflect.Value) [][]string {
func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string { func getColumnName(ft int, addrField reflect.Value, sf reflect.StructField, col string) string {
column := col column := col
if col == "" { if col == "" {
column = snakeString(sf.Name) column = nameStrategyMap[nameStrategy](sf.Name)
} }
switch ft { switch ft {
case RelForeignKey, RelOneToOne: case RelForeignKey, RelOneToOne:

View File

@ -425,7 +425,7 @@ func (o *orm) getRelQs(md interface{}, mi *modelInfo, fi *fieldInfo) *querySet {
func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) { func (o *orm) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
var name string var name string
if table, ok := ptrStructOrTableName.(string); ok { if table, ok := ptrStructOrTableName.(string); ok {
name = snakeString(table) name = nameStrategyMap[defaultNameStrategy](table)
if mi, ok := modelCache.get(name); ok { if mi, ok := modelCache.get(name); ok {
qs = newQuerySet(o, mi) qs = newQuerySet(o, mi)
} }

View File

@ -358,7 +358,7 @@ func (o *rawSet) QueryRow(containers ...interface{}) error {
_, tags := parseStructTag(fe.Tag.Get(defaultStructTagName)) _, tags := parseStructTag(fe.Tag.Get(defaultStructTagName))
var col string var col string
if col = tags["column"]; col == "" { if col = tags["column"]; col == "" {
col = snakeString(fe.Name) col = nameStrategyMap[nameStrategy](fe.Name)
} }
if v, ok := columnsMp[col]; ok { if v, ok := columnsMp[col]; ok {
value := reflect.ValueOf(v).Elem().Interface() value := reflect.ValueOf(v).Elem().Interface()
@ -509,7 +509,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) {
_, tags := parseStructTag(fe.Tag.Get(defaultStructTagName)) _, tags := parseStructTag(fe.Tag.Get(defaultStructTagName))
var col string var col string
if col = tags["column"]; col == "" { if col = tags["column"]; col == "" {
col = snakeString(fe.Name) col = nameStrategyMap[nameStrategy](fe.Name)
} }
if v, ok := columnsMp[col]; ok { if v, ok := columnsMp[col]; ok {
value := reflect.ValueOf(v).Elem().Interface() value := reflect.ValueOf(v).Elem().Interface()

View File

@ -23,6 +23,18 @@ import (
"time" "time"
) )
type fn func(string) string
var (
nameStrategyMap = map[string]fn{
defaultNameStrategy: snakeString,
SnakeAcronymNameStrategy: snakeStringWithAcronym,
}
defaultNameStrategy = "snakeString"
SnakeAcronymNameStrategy = "snakeStringWithAcronym"
nameStrategy = defaultNameStrategy
)
// StrTo is the target string // StrTo is the target string
type StrTo string type StrTo string
@ -198,6 +210,27 @@ func ToInt64(value interface{}) (d int64) {
return return
} }
func snakeStringWithAcronym(s string) string {
data := make([]byte, 0, len(s)*2)
num := len(s)
for i := 0; i < num; i++ {
d := s[i]
before := false
after := false
if i > 0 {
before = s[i-1] >= 'a' && s[i-1] <= 'z'
}
if i+1 < num {
after = s[i+1] >= 'a' && s[i+1] <= 'z'
}
if i > 0 && d >= 'A' && d <= 'Z' && (before || after) {
data = append(data, '_')
}
data = append(data, d)
}
return strings.ToLower(string(data[:]))
}
// snake string, XxYy to xx_yy , XxYY to xx_y_y // snake string, XxYy to xx_yy , XxYY to xx_y_y
func snakeString(s string) string { func snakeString(s string) string {
data := make([]byte, 0, len(s)*2) data := make([]byte, 0, len(s)*2)
@ -216,6 +249,14 @@ func snakeString(s string) string {
return strings.ToLower(string(data[:])) return strings.ToLower(string(data[:]))
} }
// SetNameStrategy set different name strategy
func SetNameStrategy(s string) {
if SnakeAcronymNameStrategy != s {
nameStrategy = defaultNameStrategy
}
nameStrategy = s
}
// camel string, xx_yy to XxYy // camel string, xx_yy to XxYy
func camelString(s string) string { func camelString(s string) string {
data := make([]byte, 0, len(s)) data := make([]byte, 0, len(s))

View File

@ -51,3 +51,20 @@ func TestSnakeString(t *testing.T) {
} }
} }
} }
func TestSnakeStringWithAcronym(t *testing.T) {
camel := []string{"ID", "PicURL", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "XyXX"}
snake := []string{"id", "pic_url", "hello_world", "hello_world", "hel_lo_word", "pic_url1", "xy_xx"}
answer := make(map[string]string)
for i, v := range camel {
answer[v] = snake[i]
}
for _, v := range camel {
res := snakeStringWithAcronym(v)
if res != answer[v] {
t.Error("Unit Test Fail:", v, res, answer[v])
}
}
}