utils.go 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. package exchange
  2. import (
  3. "errors"
  4. "fmt"
  5. "math"
  6. "reflect"
  7. "strconv"
  8. "strings"
  9. "gorm.io/gorm"
  10. )
  11. func setValueFromString(v reflect.Value, strVal string) error {
  12. if strVal == "" {
  13. v.Set(reflect.Zero(v.Type()))
  14. return nil
  15. }
  16. switch v.Kind() {
  17. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  18. val, err := strconv.ParseInt(strVal, 0, 64)
  19. if err != nil {
  20. return err
  21. }
  22. if v.OverflowInt(val) {
  23. return errors.New("Int value too big: " + strVal)
  24. }
  25. v.SetInt(val)
  26. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  27. val, err := strconv.ParseUint(strVal, 0, 64)
  28. if err != nil {
  29. return err
  30. }
  31. if v.OverflowUint(val) {
  32. return errors.New("UInt value too big: " + strVal)
  33. }
  34. v.SetUint(val)
  35. case reflect.Float32:
  36. val, err := strconv.ParseFloat(strVal, 32)
  37. if err != nil {
  38. return err
  39. }
  40. v.SetFloat(val)
  41. case reflect.Float64:
  42. val, err := strconv.ParseFloat(strVal, 64)
  43. if err != nil {
  44. return err
  45. }
  46. v.SetFloat(val)
  47. case reflect.String:
  48. v.SetString(strVal)
  49. case reflect.Bool:
  50. val, err := strconv.ParseBool(strVal)
  51. if err != nil {
  52. return err
  53. }
  54. v.SetBool(val)
  55. case reflect.Ptr:
  56. v.Set(reflect.New(v.Type().Elem()))
  57. return setValueFromString(v.Elem(), strVal)
  58. default:
  59. return errors.New("Unsupported kind: " + v.Kind().String())
  60. }
  61. return nil
  62. }
  63. func validateResourceAndMetas(r interface{}, metas []*Meta) error {
  64. if r == nil {
  65. return errors.New("resource is nil")
  66. }
  67. rt := reflect.TypeOf(r)
  68. if rt.Kind() != reflect.Ptr || rt.Elem().Kind() != reflect.Struct {
  69. return errors.New("resource is not ptr to struct")
  70. }
  71. if len(metas) == 0 {
  72. return errors.New("no metas")
  73. }
  74. ret := rt.Elem()
  75. for i, _ := range metas {
  76. m := metas[i]
  77. if m.field == "" {
  78. return errors.New("field name is empty")
  79. }
  80. if m.setter == nil && m.valuer == nil {
  81. _, ok := ret.FieldByName(m.field)
  82. if !ok {
  83. return fmt.Errorf("field %s not found", m.field)
  84. }
  85. }
  86. if m.columnHeader == "" {
  87. return errors.New("header is empty")
  88. }
  89. if m.primaryKey && (m.setter != nil || m.valuer != nil) {
  90. return fmt.Errorf("can not set setter/valuer on primaryKey meta")
  91. }
  92. }
  93. return nil
  94. }
  95. func preloadDB(db *gorm.DB, associations []string) *gorm.DB {
  96. if len(associations) == 0 {
  97. return db
  98. }
  99. ndb := db.Preload(associations[0])
  100. for i := 1; i < len(associations); i++ {
  101. ndb = ndb.Preload(associations[i])
  102. }
  103. return ndb
  104. }
  105. func getIndirect(v reflect.Value) reflect.Value {
  106. if v.Kind() != reflect.Ptr {
  107. return v
  108. }
  109. return getIndirect(reflect.Indirect(v))
  110. }
  111. func getIndirectStruct(t reflect.Type) reflect.Type {
  112. if t.Kind() == reflect.Struct {
  113. return t
  114. }
  115. return getIndirectStruct(t.Elem())
  116. }
  117. func clearPrimaryKeyValue(v reflect.Value) {
  118. t := v.Type()
  119. if idf, ok := t.FieldByName("ID"); ok {
  120. if strings.Contains(idf.Tag.Get("gorm"), "primarykey") {
  121. v.FieldByName("ID").SetUint(0)
  122. }
  123. }
  124. for i := 0; i < t.NumField(); i++ {
  125. ft := t.Field(i)
  126. if !strings.Contains(ft.Tag.Get("gorm"), "primarykey") {
  127. continue
  128. }
  129. v.Field(i).Set(reflect.New(ft.Type).Elem())
  130. }
  131. }
  132. func getParamsNumbers(n *int, t reflect.Type, associations []string) {
  133. for i := 0; i < t.NumField(); i++ {
  134. ft := t.Field(i)
  135. isAssociation := false
  136. for _, a := range associations {
  137. if ft.Name == a {
  138. isAssociation = true
  139. break
  140. }
  141. }
  142. if isAssociation {
  143. continue
  144. }
  145. if ft.Type.Kind() == reflect.Struct && ft.Anonymous {
  146. getParamsNumbers(n, ft.Type, nil)
  147. continue
  148. }
  149. *n++
  150. }
  151. }
  152. func splitStringSliceSlice(s [][]string, size int) [][][]string {
  153. groupsLen := int(math.Ceil(float64(len(s)) / float64(size)))
  154. groups := make([][][]string, groupsLen)
  155. idx := 0
  156. for i := 0; i < groupsLen; i++ {
  157. idx = i * size
  158. if i != groupsLen-1 {
  159. groups[i] = s[idx : idx+size]
  160. } else {
  161. groups[i] = s[idx:]
  162. }
  163. }
  164. return groups
  165. }
  166. func splitInterfaceSlice(s []interface{}, size int) [][]interface{} {
  167. groupsLen := int(math.Ceil(float64(len(s)) / float64(size)))
  168. groups := make([][]interface{}, groupsLen)
  169. idx := 0
  170. for i := 0; i < groupsLen; i++ {
  171. idx = i * size
  172. if i != groupsLen-1 {
  173. groups[i] = s[idx : idx+size]
  174. } else {
  175. groups[i] = s[idx:]
  176. }
  177. }
  178. return groups
  179. }
  180. func splitReflectSliceValue(s reflect.Value, size int) []reflect.Value {
  181. groupsLen := int(math.Ceil(float64(s.Len()) / float64(size)))
  182. groups := make([]reflect.Value, 0, groupsLen)
  183. idx := 0
  184. for i := 0; i < groupsLen; i++ {
  185. idx = i * size
  186. endIdx := idx + size
  187. if i == groupsLen-1 {
  188. endIdx = s.Len()
  189. }
  190. vs := reflect.New(reflect.SliceOf(s.Type().Elem())).Elem()
  191. for j := idx; j < endIdx; j++ {
  192. vs = reflect.Append(vs, s.Index(j))
  193. }
  194. groups = append(groups, vs)
  195. }
  196. return groups
  197. }