cache.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. package cache
  2. import (
  3. "encoding/json"
  4. "git.sxidc.com/go-tools/utils/reflectutils"
  5. "git.sxidc.com/go-tools/utils/strutils"
  6. "github.com/pkg/errors"
  7. "reflect"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. type Cache interface {
  13. Set(key string, value string, expireSec int64) error
  14. Get(key string) (string, error)
  15. GetMulti(keys []string) (map[string]string, error)
  16. GetAll() (map[string]string, error)
  17. Delete(key string) error
  18. Clear() error
  19. }
  20. func Set(cache Cache, key string, value any, expireSec int64) error {
  21. valueReflectValue := reflect.ValueOf(value)
  22. if !valueReflectValue.IsValid() {
  23. return errors.New("缓存值无效")
  24. }
  25. stringValue, err := toString(valueReflectValue)
  26. if err != nil {
  27. return err
  28. }
  29. return cache.Set(key, stringValue, expireSec)
  30. }
  31. func Get[T any](cache Cache, key string) (T, error) {
  32. var zero T
  33. stringValue, err := cache.Get(key)
  34. if err != nil {
  35. return zero, err
  36. }
  37. retValue := reflectutils.Zero[T]()
  38. retValueReflectType := reflect.TypeOf(retValue)
  39. if retValueReflectType.Kind() == reflect.Pointer {
  40. err := fromString(stringValue, retValue)
  41. if err != nil {
  42. return zero, err
  43. }
  44. } else {
  45. err := fromString(stringValue, &retValue)
  46. if err != nil {
  47. return zero, err
  48. }
  49. }
  50. return retValue, nil
  51. }
  52. func GetMulti(cache Cache, keys []string) (map[string]string, error) {
  53. return cache.GetMulti(keys)
  54. }
  55. func GetAll(cache Cache) (map[string]string, error) {
  56. return cache.GetAll()
  57. }
  58. func Delete(cache Cache, key string) error {
  59. return cache.Delete(key)
  60. }
  61. func Clear(cache Cache) error {
  62. return cache.Clear()
  63. }
  64. func toString(valueReflectValue reflect.Value) (string, error) {
  65. dataVal := reflect.Indirect(valueReflectValue)
  66. dataKind := reflectutils.GroupValueKind(dataVal)
  67. switch dataKind {
  68. case reflect.String:
  69. return dataVal.String(), nil
  70. case reflect.Bool:
  71. if dataVal.Bool() {
  72. return "true", nil
  73. } else {
  74. return "false", nil
  75. }
  76. case reflect.Int64:
  77. return strconv.FormatInt(dataVal.Int(), 10), nil
  78. case reflect.Uint64:
  79. return strconv.FormatUint(dataVal.Uint(), 10), nil
  80. case reflect.Float64:
  81. return strconv.FormatFloat(dataVal.Float(), 'f', -1, 64), nil
  82. case reflect.Slice, reflect.Array:
  83. dataElementType := reflectutils.PointerTypeElem(dataVal.Type().Elem())
  84. // []byte,直接转换为string
  85. if dataElementType.Kind() == reflect.Uint8 {
  86. if dataVal.Len() == 0 {
  87. return "", nil
  88. }
  89. uints := make([]uint8, dataVal.Len(), dataVal.Len())
  90. for i := 0; i < dataVal.Len(); i++ {
  91. uints[i] = dataVal.Index(i).Interface().(uint8)
  92. }
  93. return string(uints), nil
  94. } else {
  95. if dataVal.Len() == 0 {
  96. return "[]", nil
  97. }
  98. stringBuilder := strings.Builder{}
  99. stringBuilder.WriteString("[")
  100. for i := 0; i < dataVal.Len(); i++ {
  101. strValue, err := toString(dataVal.Index(i))
  102. if err != nil {
  103. return "", err
  104. }
  105. if i > 0 {
  106. stringBuilder.WriteString(",")
  107. }
  108. stringBuilder.WriteString(strValue)
  109. }
  110. stringBuilder.WriteString("]")
  111. return stringBuilder.String(), nil
  112. }
  113. case reflect.Map, reflect.Struct:
  114. if dataVal.Type().Name() == "time.Time" {
  115. return dataVal.Interface().(time.Time).Format(time.RFC3339Nano), nil
  116. } else {
  117. jsonBytes, err := json.Marshal(dataVal.Interface())
  118. if err != nil {
  119. return "", errors.New(err.Error())
  120. }
  121. return string(jsonBytes), nil
  122. }
  123. default:
  124. return "", errors.New("不支持的缓存值类型: " + dataVal.Type().Elem().String())
  125. }
  126. }
  127. func fromString(stringValue string, retValue any) error {
  128. retValueReflectValue := reflect.ValueOf(retValue)
  129. if retValueReflectValue.Kind() != reflect.Pointer {
  130. return errors.New("返回值不是指针类型")
  131. }
  132. dataVal := reflect.Indirect(retValueReflectValue)
  133. dataKind := reflectutils.GroupValueKind(dataVal)
  134. switch dataKind {
  135. case reflect.String:
  136. dataVal.SetString(stringValue)
  137. return nil
  138. case reflect.Bool:
  139. if strutils.IsStringEmpty(stringValue) {
  140. dataVal.SetBool(false)
  141. } else {
  142. if stringValue == "false" {
  143. dataVal.SetBool(false)
  144. } else {
  145. dataVal.SetBool(true)
  146. }
  147. }
  148. return nil
  149. case reflect.Int64:
  150. intValue, err := strconv.ParseInt(stringValue, 10, 64)
  151. if err != nil {
  152. return errors.New(err.Error())
  153. }
  154. dataVal.SetInt(intValue)
  155. return nil
  156. case reflect.Uint64:
  157. uintValue, err := strconv.ParseUint(stringValue, 10, 64)
  158. if err != nil {
  159. return err
  160. }
  161. dataVal.SetUint(uintValue)
  162. return nil
  163. case reflect.Float64:
  164. floatValue, err := strconv.ParseFloat(stringValue, 64)
  165. if err != nil {
  166. return err
  167. }
  168. dataVal.SetFloat(floatValue)
  169. return nil
  170. case reflect.Slice, reflect.Array:
  171. dataElementType := reflectutils.PointerTypeElem(dataVal.Type().Elem())
  172. // []byte直接用string赋值
  173. if dataElementType.Kind() == reflect.Uint8 {
  174. dataSliceVal := reflect.MakeSlice(dataVal.Type(), 0, 0)
  175. for _, b := range []byte(stringValue) {
  176. if dataVal.Type().Elem().Kind() == reflect.Pointer {
  177. dataSliceVal = reflect.Append(dataSliceVal, reflect.ValueOf(&b))
  178. } else {
  179. dataSliceVal = reflect.Append(dataSliceVal, reflect.ValueOf(b))
  180. }
  181. }
  182. dataVal.Set(dataSliceVal)
  183. return nil
  184. } else {
  185. if !strings.HasPrefix(stringValue, "[") || !strings.HasSuffix(stringValue, "]") {
  186. return errors.New("缓存值不是切片或数组形式")
  187. }
  188. dataSliceVal := reflect.MakeSlice(dataVal.Type(), 0, 0)
  189. stringValue = strings.TrimSuffix(strings.TrimPrefix(stringValue, "["), "]")
  190. stringValueParts := strings.Split(stringValue, ",")
  191. for _, strValuePart := range stringValueParts {
  192. dataSliceElementType := dataVal.Type().Elem()
  193. dataSliceElementVal := reflect.Indirect(reflect.New(dataSliceElementType))
  194. if dataSliceElementVal.Kind() == reflect.Pointer {
  195. dataSliceElementVal.Set(reflect.New(dataSliceElementVal.Type().Elem()))
  196. err := fromString(strValuePart, dataSliceElementVal.Interface())
  197. if err != nil {
  198. return err
  199. }
  200. } else {
  201. err := fromString(strValuePart, dataSliceElementVal.Addr().Interface())
  202. if err != nil {
  203. return err
  204. }
  205. }
  206. dataSliceVal = reflect.Append(dataSliceVal, dataSliceElementVal)
  207. }
  208. dataVal.Set(dataSliceVal)
  209. return nil
  210. }
  211. case reflect.Map, reflect.Struct:
  212. if dataVal.Type().Name() == "time.Time" {
  213. parsedTime, err := time.ParseInLocation(time.RFC3339Nano, stringValue, time.Local)
  214. if err != nil {
  215. return err
  216. }
  217. dataVal.Set(reflect.ValueOf(parsedTime))
  218. return nil
  219. } else {
  220. err := json.Unmarshal([]byte(stringValue), dataVal.Addr().Interface())
  221. if err != nil {
  222. return errors.New(err.Error())
  223. }
  224. return nil
  225. }
  226. default:
  227. return errors.New("不支持的缓存值类型: " + dataVal.Type().Elem().String())
  228. }
  229. }