xorm/mapper.go

177 lines
3.5 KiB
Go
Raw Normal View History

2013-05-03 07:26:51 +00:00
package xorm
import (
2013-12-18 03:31:32 +00:00
"strings"
2014-02-10 03:26:08 +00:00
"sync"
2013-05-03 07:26:51 +00:00
)
2013-09-11 08:23:10 +00:00
// name translation between struct, fields names and table, column names
2013-05-03 07:26:51 +00:00
type IMapper interface {
2013-12-18 03:31:32 +00:00
Obj2Table(string) string
Table2Obj(string) string
2013-05-03 07:26:51 +00:00
}
2014-02-10 03:26:08 +00:00
type CacheMapper struct {
oriMapper IMapper
obj2tableCache map[string]string
obj2tableMutex sync.RWMutex
table2objCache map[string]string
table2objMutex sync.RWMutex
}
func NewCacheMapper(mapper IMapper) *CacheMapper {
return &CacheMapper{oriMapper: mapper, obj2tableCache: make(map[string]string),
table2objCache: make(map[string]string),
}
}
func (m *CacheMapper) Obj2Table(o string) string {
m.obj2tableMutex.RLock()
t, ok := m.obj2tableCache[o]
m.obj2tableMutex.RUnlock()
if ok {
return t
}
t = m.oriMapper.Obj2Table(o)
m.obj2tableMutex.Lock()
m.obj2tableCache[o] = t
m.obj2tableMutex.Unlock()
return t
}
func (m *CacheMapper) Table2Obj(t string) string {
m.table2objMutex.RLock()
o, ok := m.table2objCache[t]
m.table2objMutex.RUnlock()
if ok {
return o
}
o = m.oriMapper.Table2Obj(t)
m.table2objMutex.Lock()
m.table2objCache[t] = o
m.table2objMutex.Unlock()
return o
}
2013-11-22 06:11:07 +00:00
// SameMapper implements IMapper and provides same name between struct and
// database table
2013-09-06 06:32:20 +00:00
type SameMapper struct {
}
func (m SameMapper) Obj2Table(o string) string {
2013-12-18 03:31:32 +00:00
return o
2013-09-06 06:32:20 +00:00
}
func (m SameMapper) Table2Obj(t string) string {
2013-12-18 03:31:32 +00:00
return t
2013-09-06 06:32:20 +00:00
}
2013-11-22 06:11:07 +00:00
// SnakeMapper implements IMapper and provides name transaltion between
// struct and database table
2013-05-03 07:26:51 +00:00
type SnakeMapper struct {
}
func snakeCasedName(name string) string {
2013-12-18 03:31:32 +00:00
newstr := make([]rune, 0)
for idx, chr := range name {
if isUpper := 'A' <= chr && chr <= 'Z'; isUpper {
if idx > 0 {
newstr = append(newstr, '_')
}
chr -= ('A' - 'a')
}
newstr = append(newstr, chr)
}
2013-05-03 07:26:51 +00:00
2013-12-18 03:31:32 +00:00
return string(newstr)
2013-05-03 07:26:51 +00:00
}
2013-11-15 03:01:13 +00:00
/*func pascal2Sql(s string) (d string) {
2013-12-09 02:29:23 +00:00
d = ""
lastIdx := 0
for i := 0; i < len(s); i++ {
if s[i] >= 'A' && s[i] <= 'Z' {
if lastIdx < i {
d += s[lastIdx+1 : i]
}
if i != 0 {
d += "_"
}
d += string(s[i] + 32)
lastIdx = i
}
}
d += s[lastIdx+1:]
return
2013-11-15 03:01:13 +00:00
}*/
2013-05-03 07:26:51 +00:00
func (mapper SnakeMapper) Obj2Table(name string) string {
2013-12-18 03:31:32 +00:00
return snakeCasedName(name)
2013-05-03 07:26:51 +00:00
}
func titleCasedName(name string) string {
2013-12-18 03:31:32 +00:00
newstr := make([]rune, 0)
upNextChar := true
2013-05-03 07:26:51 +00:00
2013-12-18 03:31:32 +00:00
name = strings.ToLower(name)
2013-12-12 06:33:26 +00:00
2013-12-18 03:31:32 +00:00
for _, chr := range name {
switch {
case upNextChar:
upNextChar = false
if 'a' <= chr && chr <= 'z' {
chr -= ('a' - 'A')
}
case chr == '_':
upNextChar = true
continue
}
2013-05-03 07:26:51 +00:00
2013-12-18 03:31:32 +00:00
newstr = append(newstr, chr)
}
2013-05-03 07:26:51 +00:00
2013-12-18 03:31:32 +00:00
return string(newstr)
2013-05-03 07:26:51 +00:00
}
func (mapper SnakeMapper) Table2Obj(name string) string {
2013-12-18 03:31:32 +00:00
return titleCasedName(name)
2013-05-03 07:26:51 +00:00
}
2013-11-27 07:53:05 +00:00
// provide prefix table name support
type PrefixMapper struct {
2013-12-18 03:31:32 +00:00
Mapper IMapper
Prefix string
2013-11-27 07:53:05 +00:00
}
func (mapper PrefixMapper) Obj2Table(name string) string {
2013-12-18 03:31:32 +00:00
return mapper.Prefix + mapper.Mapper.Obj2Table(name)
2013-11-27 07:53:05 +00:00
}
func (mapper PrefixMapper) Table2Obj(name string) string {
2013-12-18 03:31:32 +00:00
return mapper.Mapper.Table2Obj(name[len(mapper.Prefix):])
2013-11-27 07:53:05 +00:00
}
func NewPrefixMapper(mapper IMapper, prefix string) PrefixMapper {
2013-12-18 03:31:32 +00:00
return PrefixMapper{mapper, prefix}
2013-11-27 07:53:05 +00:00
}
// provide suffix table name support
type SuffixMapper struct {
2013-12-18 03:31:32 +00:00
Mapper IMapper
Suffix string
2013-11-27 07:53:05 +00:00
}
func (mapper SuffixMapper) Obj2Table(name string) string {
2013-12-18 03:31:32 +00:00
return mapper.Suffix + mapper.Mapper.Obj2Table(name)
2013-11-27 07:53:05 +00:00
}
func (mapper SuffixMapper) Table2Obj(name string) string {
2013-12-18 03:31:32 +00:00
return mapper.Mapper.Table2Obj(name[len(mapper.Suffix):])
2013-11-27 07:53:05 +00:00
}
func NewSuffixMapper(mapper IMapper, suffix string) SuffixMapper {
2013-12-18 03:31:32 +00:00
return SuffixMapper{mapper, suffix}
2013-11-27 07:53:05 +00:00
}