utils.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package gorm
  2. import (
  3. "database/sql/driver"
  4. "fmt"
  5. "reflect"
  6. "regexp"
  7. "runtime"
  8. "strings"
  9. "sync"
  10. "time"
  11. )
  12. // NowFunc returns current time, this function is exported in order to be able
  13. // to give the flexibility to the developer to customize it according to their
  14. // needs, e.g:
  15. // gorm.NowFunc = func() time.Time {
  16. // return time.Now().UTC()
  17. // }
  18. var NowFunc = func() time.Time {
  19. return time.Now()
  20. }
  21. // Copied from golint
  22. 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"}
  23. var commonInitialismsReplacer *strings.Replacer
  24. var goSrcRegexp = regexp.MustCompile(`jinzhu/gorm(@.*)?/.*.go`)
  25. var goTestRegexp = regexp.MustCompile(`jinzhu/gorm(@.*)?/.*test.go`)
  26. func init() {
  27. var commonInitialismsForReplacer []string
  28. for _, initialism := range commonInitialisms {
  29. commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism)))
  30. }
  31. commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...)
  32. }
  33. type safeMap struct {
  34. m map[string]string
  35. l *sync.RWMutex
  36. }
  37. func (s *safeMap) Set(key string, value string) {
  38. s.l.Lock()
  39. defer s.l.Unlock()
  40. s.m[key] = value
  41. }
  42. func (s *safeMap) Get(key string) string {
  43. s.l.RLock()
  44. defer s.l.RUnlock()
  45. return s.m[key]
  46. }
  47. func newSafeMap() *safeMap {
  48. return &safeMap{l: new(sync.RWMutex), m: make(map[string]string)}
  49. }
  50. // SQL expression
  51. type expr struct {
  52. expr string
  53. args []interface{}
  54. }
  55. // Expr generate raw SQL expression, for example:
  56. // DB.Model(&product).Update("price", gorm.Expr("price * ? + ?", 2, 100))
  57. func Expr(expression string, args ...interface{}) *expr {
  58. return &expr{expr: expression, args: args}
  59. }
  60. func indirect(reflectValue reflect.Value) reflect.Value {
  61. for reflectValue.Kind() == reflect.Ptr {
  62. reflectValue = reflectValue.Elem()
  63. }
  64. return reflectValue
  65. }
  66. func toQueryMarks(primaryValues [][]interface{}) string {
  67. var results []string
  68. for _, primaryValue := range primaryValues {
  69. var marks []string
  70. for range primaryValue {
  71. marks = append(marks, "?")
  72. }
  73. if len(marks) > 1 {
  74. results = append(results, fmt.Sprintf("(%v)", strings.Join(marks, ",")))
  75. } else {
  76. results = append(results, strings.Join(marks, ""))
  77. }
  78. }
  79. return strings.Join(results, ",")
  80. }
  81. func toQueryCondition(scope *Scope, columns []string) string {
  82. var newColumns []string
  83. for _, column := range columns {
  84. newColumns = append(newColumns, scope.Quote(column))
  85. }
  86. if len(columns) > 1 {
  87. return fmt.Sprintf("(%v)", strings.Join(newColumns, ","))
  88. }
  89. return strings.Join(newColumns, ",")
  90. }
  91. func toQueryValues(values [][]interface{}) (results []interface{}) {
  92. for _, value := range values {
  93. for _, v := range value {
  94. results = append(results, v)
  95. }
  96. }
  97. return
  98. }
  99. func fileWithLineNum() string {
  100. for i := 2; i < 15; i++ {
  101. _, file, line, ok := runtime.Caller(i)
  102. if ok && (!goSrcRegexp.MatchString(file) || goTestRegexp.MatchString(file)) {
  103. return fmt.Sprintf("%v:%v", file, line)
  104. }
  105. }
  106. return ""
  107. }
  108. func isBlank(value reflect.Value) bool {
  109. switch value.Kind() {
  110. case reflect.String:
  111. return value.Len() == 0
  112. case reflect.Bool:
  113. return !value.Bool()
  114. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  115. return value.Int() == 0
  116. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
  117. return value.Uint() == 0
  118. case reflect.Float32, reflect.Float64:
  119. return value.Float() == 0
  120. case reflect.Interface, reflect.Ptr:
  121. return value.IsNil()
  122. }
  123. return reflect.DeepEqual(value.Interface(), reflect.Zero(value.Type()).Interface())
  124. }
  125. func toSearchableMap(attrs ...interface{}) (result interface{}) {
  126. if len(attrs) > 1 {
  127. if str, ok := attrs[0].(string); ok {
  128. result = map[string]interface{}{str: attrs[1]}
  129. }
  130. } else if len(attrs) == 1 {
  131. if attr, ok := attrs[0].(map[string]interface{}); ok {
  132. result = attr
  133. }
  134. if attr, ok := attrs[0].(interface{}); ok {
  135. result = attr
  136. }
  137. }
  138. return
  139. }
  140. func equalAsString(a interface{}, b interface{}) bool {
  141. return toString(a) == toString(b)
  142. }
  143. func toString(str interface{}) string {
  144. if values, ok := str.([]interface{}); ok {
  145. var results []string
  146. for _, value := range values {
  147. results = append(results, toString(value))
  148. }
  149. return strings.Join(results, "_")
  150. } else if bytes, ok := str.([]byte); ok {
  151. return string(bytes)
  152. } else if reflectValue := reflect.Indirect(reflect.ValueOf(str)); reflectValue.IsValid() {
  153. return fmt.Sprintf("%v", reflectValue.Interface())
  154. }
  155. return ""
  156. }
  157. func makeSlice(elemType reflect.Type) interface{} {
  158. if elemType.Kind() == reflect.Slice {
  159. elemType = elemType.Elem()
  160. }
  161. sliceType := reflect.SliceOf(elemType)
  162. slice := reflect.New(sliceType)
  163. slice.Elem().Set(reflect.MakeSlice(sliceType, 0, 0))
  164. return slice.Interface()
  165. }
  166. func strInSlice(a string, list []string) bool {
  167. for _, b := range list {
  168. if b == a {
  169. return true
  170. }
  171. }
  172. return false
  173. }
  174. // getValueFromFields return given fields's value
  175. func getValueFromFields(value reflect.Value, fieldNames []string) (results []interface{}) {
  176. // If value is a nil pointer, Indirect returns a zero Value!
  177. // Therefor we need to check for a zero value,
  178. // as FieldByName could panic
  179. if indirectValue := reflect.Indirect(value); indirectValue.IsValid() {
  180. for _, fieldName := range fieldNames {
  181. if fieldValue := reflect.Indirect(indirectValue.FieldByName(fieldName)); fieldValue.IsValid() {
  182. result := fieldValue.Interface()
  183. if r, ok := result.(driver.Valuer); ok {
  184. result, _ = r.Value()
  185. }
  186. results = append(results, result)
  187. }
  188. }
  189. }
  190. return
  191. }
  192. func addExtraSpaceIfExist(str string) string {
  193. if str != "" {
  194. return " " + str
  195. }
  196. return ""
  197. }