Simple and Powerful ORM for Go, support mysql,postgres,tidb,sqlite3,mssql,oracle https://xorm.io
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

344 lines
7.0KB

  1. // Copyright 2015 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package xorm
  5. import (
  6. "errors"
  7. "fmt"
  8. "reflect"
  9. "sort"
  10. "strconv"
  11. "strings"
  12. "xorm.io/core"
  13. )
  14. // str2PK convert string value to primary key value according to tp
  15. func str2PKValue(s string, tp reflect.Type) (reflect.Value, error) {
  16. var err error
  17. var result interface{}
  18. var defReturn = reflect.Zero(tp)
  19. switch tp.Kind() {
  20. case reflect.Int:
  21. result, err = strconv.Atoi(s)
  22. if err != nil {
  23. return defReturn, fmt.Errorf("convert %s as int: %s", s, err.Error())
  24. }
  25. case reflect.Int8:
  26. x, err := strconv.Atoi(s)
  27. if err != nil {
  28. return defReturn, fmt.Errorf("convert %s as int8: %s", s, err.Error())
  29. }
  30. result = int8(x)
  31. case reflect.Int16:
  32. x, err := strconv.Atoi(s)
  33. if err != nil {
  34. return defReturn, fmt.Errorf("convert %s as int16: %s", s, err.Error())
  35. }
  36. result = int16(x)
  37. case reflect.Int32:
  38. x, err := strconv.Atoi(s)
  39. if err != nil {
  40. return defReturn, fmt.Errorf("convert %s as int32: %s", s, err.Error())
  41. }
  42. result = int32(x)
  43. case reflect.Int64:
  44. result, err = strconv.ParseInt(s, 10, 64)
  45. if err != nil {
  46. return defReturn, fmt.Errorf("convert %s as int64: %s", s, err.Error())
  47. }
  48. case reflect.Uint:
  49. x, err := strconv.ParseUint(s, 10, 64)
  50. if err != nil {
  51. return defReturn, fmt.Errorf("convert %s as uint: %s", s, err.Error())
  52. }
  53. result = uint(x)
  54. case reflect.Uint8:
  55. x, err := strconv.ParseUint(s, 10, 64)
  56. if err != nil {
  57. return defReturn, fmt.Errorf("convert %s as uint8: %s", s, err.Error())
  58. }
  59. result = uint8(x)
  60. case reflect.Uint16:
  61. x, err := strconv.ParseUint(s, 10, 64)
  62. if err != nil {
  63. return defReturn, fmt.Errorf("convert %s as uint16: %s", s, err.Error())
  64. }
  65. result = uint16(x)
  66. case reflect.Uint32:
  67. x, err := strconv.ParseUint(s, 10, 64)
  68. if err != nil {
  69. return defReturn, fmt.Errorf("convert %s as uint32: %s", s, err.Error())
  70. }
  71. result = uint32(x)
  72. case reflect.Uint64:
  73. result, err = strconv.ParseUint(s, 10, 64)
  74. if err != nil {
  75. return defReturn, fmt.Errorf("convert %s as uint64: %s", s, err.Error())
  76. }
  77. case reflect.String:
  78. result = s
  79. default:
  80. return defReturn, errors.New("unsupported convert type")
  81. }
  82. return reflect.ValueOf(result).Convert(tp), nil
  83. }
  84. func str2PK(s string, tp reflect.Type) (interface{}, error) {
  85. v, err := str2PKValue(s, tp)
  86. if err != nil {
  87. return nil, err
  88. }
  89. return v.Interface(), nil
  90. }
  91. func splitTag(tag string) (tags []string) {
  92. tag = strings.TrimSpace(tag)
  93. var hasQuote = false
  94. var lastIdx = 0
  95. for i, t := range tag {
  96. if t == '\'' {
  97. hasQuote = !hasQuote
  98. } else if t == ' ' {
  99. if lastIdx < i && !hasQuote {
  100. tags = append(tags, strings.TrimSpace(tag[lastIdx:i]))
  101. lastIdx = i + 1
  102. }
  103. }
  104. }
  105. if lastIdx < len(tag) {
  106. tags = append(tags, strings.TrimSpace(tag[lastIdx:]))
  107. }
  108. return
  109. }
  110. type zeroable interface {
  111. IsZero() bool
  112. }
  113. func isZero(k interface{}) bool {
  114. switch k.(type) {
  115. case int:
  116. return k.(int) == 0
  117. case int8:
  118. return k.(int8) == 0
  119. case int16:
  120. return k.(int16) == 0
  121. case int32:
  122. return k.(int32) == 0
  123. case int64:
  124. return k.(int64) == 0
  125. case uint:
  126. return k.(uint) == 0
  127. case uint8:
  128. return k.(uint8) == 0
  129. case uint16:
  130. return k.(uint16) == 0
  131. case uint32:
  132. return k.(uint32) == 0
  133. case uint64:
  134. return k.(uint64) == 0
  135. case float32:
  136. return k.(float32) == 0
  137. case float64:
  138. return k.(float64) == 0
  139. case bool:
  140. return k.(bool) == false
  141. case string:
  142. return k.(string) == ""
  143. case zeroable:
  144. return k.(zeroable).IsZero()
  145. }
  146. return false
  147. }
  148. func isZeroValue(v reflect.Value) bool {
  149. if isZero(v.Interface()) {
  150. return true
  151. }
  152. switch v.Kind() {
  153. case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
  154. return v.IsNil()
  155. }
  156. return false
  157. }
  158. func isStructZero(v reflect.Value) bool {
  159. if !v.IsValid() {
  160. return true
  161. }
  162. for i := 0; i < v.NumField(); i++ {
  163. field := v.Field(i)
  164. switch field.Kind() {
  165. case reflect.Ptr:
  166. field = field.Elem()
  167. fallthrough
  168. case reflect.Struct:
  169. if !isStructZero(field) {
  170. return false
  171. }
  172. default:
  173. if field.CanInterface() && !isZero(field.Interface()) {
  174. return false
  175. }
  176. }
  177. }
  178. return true
  179. }
  180. func isArrayValueZero(v reflect.Value) bool {
  181. if !v.IsValid() || v.Len() == 0 {
  182. return true
  183. }
  184. for i := 0; i < v.Len(); i++ {
  185. if !isZero(v.Index(i).Interface()) {
  186. return false
  187. }
  188. }
  189. return true
  190. }
  191. func int64ToIntValue(id int64, tp reflect.Type) reflect.Value {
  192. var v interface{}
  193. kind := tp.Kind()
  194. if kind == reflect.Ptr {
  195. kind = tp.Elem().Kind()
  196. }
  197. switch kind {
  198. case reflect.Int16:
  199. temp := int16(id)
  200. v = &temp
  201. case reflect.Int32:
  202. temp := int32(id)
  203. v = &temp
  204. case reflect.Int:
  205. temp := int(id)
  206. v = &temp
  207. case reflect.Int64:
  208. temp := id
  209. v = &temp
  210. case reflect.Uint16:
  211. temp := uint16(id)
  212. v = &temp
  213. case reflect.Uint32:
  214. temp := uint32(id)
  215. v = &temp
  216. case reflect.Uint64:
  217. temp := uint64(id)
  218. v = &temp
  219. case reflect.Uint:
  220. temp := uint(id)
  221. v = &temp
  222. }
  223. if tp.Kind() == reflect.Ptr {
  224. return reflect.ValueOf(v).Convert(tp)
  225. }
  226. return reflect.ValueOf(v).Elem().Convert(tp)
  227. }
  228. func int64ToInt(id int64, tp reflect.Type) interface{} {
  229. return int64ToIntValue(id, tp).Interface()
  230. }
  231. func isPKZero(pk core.PK) bool {
  232. for _, k := range pk {
  233. if isZero(k) {
  234. return true
  235. }
  236. }
  237. return false
  238. }
  239. func indexNoCase(s, sep string) int {
  240. return strings.Index(strings.ToLower(s), strings.ToLower(sep))
  241. }
  242. func splitNoCase(s, sep string) []string {
  243. idx := indexNoCase(s, sep)
  244. if idx < 0 {
  245. return []string{s}
  246. }
  247. return strings.Split(s, s[idx:idx+len(sep)])
  248. }
  249. func splitNNoCase(s, sep string, n int) []string {
  250. idx := indexNoCase(s, sep)
  251. if idx < 0 {
  252. return []string{s}
  253. }
  254. return strings.SplitN(s, s[idx:idx+len(sep)], n)
  255. }
  256. func makeArray(elem string, count int) []string {
  257. res := make([]string, count)
  258. for i := 0; i < count; i++ {
  259. res[i] = elem
  260. }
  261. return res
  262. }
  263. func rValue(bean interface{}) reflect.Value {
  264. return reflect.Indirect(reflect.ValueOf(bean))
  265. }
  266. func rType(bean interface{}) reflect.Type {
  267. sliceValue := reflect.Indirect(reflect.ValueOf(bean))
  268. // return reflect.TypeOf(sliceValue.Interface())
  269. return sliceValue.Type()
  270. }
  271. func structName(v reflect.Type) string {
  272. for v.Kind() == reflect.Ptr {
  273. v = v.Elem()
  274. }
  275. return v.Name()
  276. }
  277. func sliceEq(left, right []string) bool {
  278. if len(left) != len(right) {
  279. return false
  280. }
  281. sort.Sort(sort.StringSlice(left))
  282. sort.Sort(sort.StringSlice(right))
  283. for i := 0; i < len(left); i++ {
  284. if left[i] != right[i] {
  285. return false
  286. }
  287. }
  288. return true
  289. }
  290. func indexName(tableName, idxName string) string {
  291. return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
  292. }
  293. func eraseAny(value string, strToErase ...string) string {
  294. if len(strToErase) == 0 {
  295. return value
  296. }
  297. var replaceSeq []string
  298. for _, s := range strToErase {
  299. replaceSeq = append(replaceSeq, s, "")
  300. }
  301. replacer := strings.NewReplacer(replaceSeq...)
  302. return replacer.Replace(value)
  303. }
  304. func quoteColumns(cols []string, quoteFunc func(string) string, sep string) string {
  305. for i := range cols {
  306. cols[i] = quoteFunc(cols[i])
  307. }
  308. return strings.Join(cols, sep+" ")
  309. }