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.

311 lines
6.3 KiB

  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 isStructZero(v reflect.Value) bool {
  149. if !v.IsValid() {
  150. return true
  151. }
  152. for i := 0; i < v.NumField(); i++ {
  153. field := v.Field(i)
  154. switch field.Kind() {
  155. case reflect.Ptr:
  156. field = field.Elem()
  157. fallthrough
  158. case reflect.Struct:
  159. if !isStructZero(field) {
  160. return false
  161. }
  162. default:
  163. if field.CanInterface() && !isZero(field.Interface()) {
  164. return false
  165. }
  166. }
  167. }
  168. return true
  169. }
  170. func isArrayValueZero(v reflect.Value) bool {
  171. if !v.IsValid() || v.Len() == 0 {
  172. return true
  173. }
  174. for i := 0; i < v.Len(); i++ {
  175. if !isZero(v.Index(i).Interface()) {
  176. return false
  177. }
  178. }
  179. return true
  180. }
  181. func int64ToIntValue(id int64, tp reflect.Type) reflect.Value {
  182. var v interface{}
  183. kind := tp.Kind()
  184. if kind == reflect.Ptr {
  185. kind = tp.Elem().Kind()
  186. }
  187. switch kind {
  188. case reflect.Int16:
  189. temp := int16(id)
  190. v = &temp
  191. case reflect.Int32:
  192. temp := int32(id)
  193. v = &temp
  194. case reflect.Int:
  195. temp := int(id)
  196. v = &temp
  197. case reflect.Int64:
  198. temp := id
  199. v = &temp
  200. case reflect.Uint16:
  201. temp := uint16(id)
  202. v = &temp
  203. case reflect.Uint32:
  204. temp := uint32(id)
  205. v = &temp
  206. case reflect.Uint64:
  207. temp := uint64(id)
  208. v = &temp
  209. case reflect.Uint:
  210. temp := uint(id)
  211. v = &temp
  212. }
  213. if tp.Kind() == reflect.Ptr {
  214. return reflect.ValueOf(v).Convert(tp)
  215. }
  216. return reflect.ValueOf(v).Elem().Convert(tp)
  217. }
  218. func int64ToInt(id int64, tp reflect.Type) interface{} {
  219. return int64ToIntValue(id, tp).Interface()
  220. }
  221. func isPKZero(pk core.PK) bool {
  222. for _, k := range pk {
  223. if isZero(k) {
  224. return true
  225. }
  226. }
  227. return false
  228. }
  229. func indexNoCase(s, sep string) int {
  230. return strings.Index(strings.ToLower(s), strings.ToLower(sep))
  231. }
  232. func splitNoCase(s, sep string) []string {
  233. idx := indexNoCase(s, sep)
  234. if idx < 0 {
  235. return []string{s}
  236. }
  237. return strings.Split(s, s[idx:idx+len(sep)])
  238. }
  239. func splitNNoCase(s, sep string, n int) []string {
  240. idx := indexNoCase(s, sep)
  241. if idx < 0 {
  242. return []string{s}
  243. }
  244. return strings.SplitN(s, s[idx:idx+len(sep)], n)
  245. }
  246. func makeArray(elem string, count int) []string {
  247. res := make([]string, count)
  248. for i := 0; i < count; i++ {
  249. res[i] = elem
  250. }
  251. return res
  252. }
  253. func rValue(bean interface{}) reflect.Value {
  254. return reflect.Indirect(reflect.ValueOf(bean))
  255. }
  256. func rType(bean interface{}) reflect.Type {
  257. sliceValue := reflect.Indirect(reflect.ValueOf(bean))
  258. //return reflect.TypeOf(sliceValue.Interface())
  259. return sliceValue.Type()
  260. }
  261. func structName(v reflect.Type) string {
  262. for v.Kind() == reflect.Ptr {
  263. v = v.Elem()
  264. }
  265. return v.Name()
  266. }
  267. func sliceEq(left, right []string) bool {
  268. if len(left) != len(right) {
  269. return false
  270. }
  271. sort.Sort(sort.StringSlice(left))
  272. sort.Sort(sort.StringSlice(right))
  273. for i := 0; i < len(left); i++ {
  274. if left[i] != right[i] {
  275. return false
  276. }
  277. }
  278. return true
  279. }
  280. func indexName(tableName, idxName string) string {
  281. return fmt.Sprintf("IDX_%v_%v", tableName, idxName)
  282. }