PageRenderTime 1449ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/vendor/github.com/jinzhu/gorm/utils.go

https://bitbucket.org/jyotiswarp/ppc
Go | 285 lines | 232 code | 38 blank | 15 comment | 71 complexity | 2f5a4d98d8a332609c8beb3422feab46 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-2-Clause, MIT, Apache-2.0, BSD-3-Clause, MPL-2.0
  1. package gorm
  2. import (
  3. "bytes"
  4. "database/sql/driver"
  5. "fmt"
  6. "reflect"
  7. "regexp"
  8. "runtime"
  9. "strings"
  10. "sync"
  11. "time"
  12. )
  13. // NowFunc returns current time, this function is exported in order to be able
  14. // to give the flexibility to the developer to customize it according to their
  15. // needs, e.g:
  16. // gorm.NowFunc = func() time.Time {
  17. // return time.Now().UTC()
  18. // }
  19. var NowFunc = func() time.Time {
  20. return time.Now()
  21. }
  22. // Copied from golint
  23. var commonInitialisms = []string{"API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SSH", "TLS", "TTL", "UID", "UI", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XSRF", "XSS"}
  24. var commonInitialismsReplacer *strings.Replacer
  25. var goSrcRegexp = regexp.MustCompile(`jinzhu/gorm/.*.go`)
  26. var goTestRegexp = regexp.MustCompile(`jinzhu/gorm/.*test.go`)
  27. func init() {
  28. var commonInitialismsForReplacer []string
  29. for _, initialism := range commonInitialisms {
  30. commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
  31. }
  32. commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
  33. }
  34. type safeMap struct {
  35. m map[string]string
  36. l *sync.RWMutex
  37. }
  38. func (s *safeMap) Set(key string, value string) {
  39. s.l.Lock()
  40. defer s.l.Unlock()
  41. s.m[key] = value
  42. }
  43. func (s *safeMap) Get(key string) string {
  44. s.l.RLock()
  45. defer s.l.RUnlock()
  46. return s.m[key]
  47. }
  48. func newSafeMap() *safeMap {
  49. return &safeMap{l: new(sync.RWMutex), m: make(map[string]string)}
  50. }
  51. var smap = newSafeMap()
  52. type strCase bool
  53. const (
  54. lower strCase = false
  55. upper strCase = true
  56. )
  57. // ToDBName convert string to db name
  58. func ToDBName(name string) string {
  59. if v := smap.Get(name); v != "" {
  60. return v
  61. }
  62. if name == "" {
  63. return ""
  64. }
  65. var (
  66. value = commonInitialismsReplacer.Replace(name)
  67. buf = bytes.NewBufferString("")
  68. lastCase, currCase, nextCase strCase
  69. )
  70. for i, v := range value[:len(value)-1] {
  71. nextCase = strCase(value[i+1] >= 'A' && value[i+1] <= 'Z')
  72. if i > 0 {
  73. if currCase == upper {
  74. if lastCase == upper && nextCase == upper {
  75. buf.WriteRune(v)
  76. } else {
  77. if value[i-1] != '_' && value[i+1] != '_' {
  78. buf.WriteRune('_')
  79. }
  80. buf.WriteRune(v)
  81. }
  82. } else {
  83. buf.WriteRune(v)
  84. if i == len(value)-2 && nextCase == upper {
  85. buf.WriteRune('_')
  86. }
  87. }
  88. } else {
  89. currCase = upper
  90. buf.WriteRune(v)
  91. }
  92. lastCase = currCase
  93. currCase = nextCase
  94. }
  95. buf.WriteByte(value[len(value)-1])
  96. s := strings.ToLower(buf.String())
  97. smap.Set(name, s)
  98. return s
  99. }
  100. // SQL expression
  101. type expr struct {
  102. expr string
  103. args []interface{}
  104. }
  105. // Expr generate raw SQL expression, for example:
  106. // DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
  107. func Expr(expression string, args ...interface{}) *expr {
  108. return &expr{expr: expression, args: args}
  109. }
  110. func indirect(reflectValue reflect.Value) reflect.Value {
  111. for reflectValue.Kind() == reflect.Ptr {
  112. reflectValue = reflectValue.Elem()
  113. }
  114. return reflectValue
  115. }
  116. func toQueryMarks(primaryValues [][]interface{}) string {
  117. var results []string
  118. for _, primaryValue := range primaryValues {
  119. var marks []string
  120. for range primaryValue {
  121. marks = append(marks, "?")
  122. }
  123. if len(marks) > 1 {
  124. results = append(results, fmt.Sprintf("(%v)", strings.Join(marks, ",")))
  125. } else {
  126. results = append(results, strings.Join(marks, ""))
  127. }
  128. }
  129. return strings.Join(results, ",")
  130. }
  131. func toQueryCondition(scope *Scope, columns []string) string {
  132. var newColumns []string
  133. for _, column := range columns {
  134. newColumns = append(newColumns, scope.Quote(column))
  135. }
  136. if len(columns) > 1 {
  137. return fmt.Sprintf("(%v)", strings.Join(newColumns, ","))
  138. }
  139. return strings.Join(newColumns, ",")
  140. }
  141. func toQueryValues(values [][]interface{}) (results []interface{}) {
  142. for _, value := range values {
  143. for _, v := range value {
  144. results = append(results, v)
  145. }
  146. }
  147. return
  148. }
  149. func fileWithLineNum() string {
  150. for i := 2; i < 15; i++ {
  151. _, file, line, ok := runtime.Caller(i)
  152. if ok && (!goSrcRegexp.MatchString(file) || goTestRegexp.MatchString(file)) {
  153. return fmt.Sprintf("%v:%v", file, line)
  154. }
  155. }
  156. return ""
  157. }
  158. func isBlank(value reflect.Value) bool {
  159. switch value.Kind() {
  160. case reflect.String:
  161. return value.Len() == 0
  162. case reflect.Bool:
  163. return !value.Bool()
  164. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  165. return value.Int() == 0
  166. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  167. return value.Uint() == 0
  168. case reflect.Float32, reflect.Float64:
  169. return value.Float() == 0
  170. case reflect.Interface, reflect.Ptr:
  171. return value.IsNil()
  172. }
  173. return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
  174. }
  175. func toSearchableMap(attrs ...interface{}) (result interface{}) {
  176. if len(attrs) > 1 {
  177. if str, ok := attrs[0].(string); ok {
  178. result = map[string]interface{}{str: attrs[1]}
  179. }
  180. } else if len(attrs) == 1 {
  181. if attr, ok := attrs[0].(map[string]interface{}); ok {
  182. result = attr
  183. }
  184. if attr, ok := attrs[0].(interface{}); ok {
  185. result = attr
  186. }
  187. }
  188. return
  189. }
  190. func equalAsString(a interface{}, b interface{}) bool {
  191. return toString(a) == toString(b)
  192. }
  193. func toString(str interface{}) string {
  194. if values, ok := str.([]interface{}); ok {
  195. var results []string
  196. for _, value := range values {
  197. results = append(results, toString(value))
  198. }
  199. return strings.Join(results, "_")
  200. } else if bytes, ok := str.([]byte); ok {
  201. return string(bytes)
  202. } else if reflectValue := reflect.Indirect(reflect.ValueOf(str)); reflectValue.IsValid() {
  203. return fmt.Sprintf("%v", reflectValue.Interface())
  204. }
  205. return ""
  206. }
  207. func makeSlice(elemType reflect.Type) interface{} {
  208. if elemType.Kind() == reflect.Slice {
  209. elemType = elemType.Elem()
  210. }
  211. sliceType := reflect.SliceOf(elemType)
  212. slice := reflect.New(sliceType)
  213. slice.Elem().Set(reflect.MakeSlice(sliceType, 0, 0))
  214. return slice.Interface()
  215. }
  216. func strInSlice(a string, list []string) bool {
  217. for _, b := range list {
  218. if b == a {
  219. return true
  220. }
  221. }
  222. return false
  223. }
  224. // getValueFromFields return given fields's value
  225. func getValueFromFields(value reflect.Value, fieldNames []string) (results []interface{}) {
  226. // If value is a nil pointer, Indirect returns a zero Value!
  227. // Therefor we need to check for a zero value,
  228. // as FieldByName could panic
  229. if indirectValue := reflect.Indirect(value); indirectValue.IsValid() {
  230. for _, fieldName := range fieldNames {
  231. if fieldValue := indirectValue.FieldByName(fieldName); fieldValue.IsValid() {
  232. result := fieldValue.Interface()
  233. if r, ok := result.(driver.Valuer); ok {
  234. result, _ = r.Value()
  235. }
  236. results = append(results, result)
  237. }
  238. }
  239. }
  240. return
  241. }
  242. func addExtraSpaceIfExist(str string) string {
  243. if str != "" {
  244. return " " + str
  245. }
  246. return ""
  247. }