convert.go 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. package DB
  2. import (
  3. "TsDB2/DB/core/types"
  4. "encoding/binary"
  5. "fmt"
  6. "reflect"
  7. )
  8. // structToFieldValues 将结构体转换为 core.InsertRow 所需的 FieldValue 切片
  9. // activeColumns 为当前 DB schema 活跃列集合,只发送交集内的字段
  10. func structToFieldValues(obj interface{}, model *ModelInfo, activeColumns map[string]bool) ([]types.FieldValue, error) {
  11. v := reflect.ValueOf(obj)
  12. if v.Kind() == reflect.Ptr {
  13. v = v.Elem()
  14. }
  15. if v.Kind() != reflect.Struct {
  16. return nil, fmt.Errorf("tsdb: expected struct, got %s", v.Kind())
  17. }
  18. result := make([]types.FieldValue, 0, len(model.AllFields))
  19. for _, fd := range model.AllFields {
  20. // 跳过不在当前 DB schema 中的字段 (如已删除列、或 struct 有但 DB 没有)
  21. if activeColumns != nil && !activeColumns[fd.ColName] {
  22. continue
  23. }
  24. fv := findField(v, fd.Name, model.StructType)
  25. if !fv.IsValid() {
  26. // 字段不在结构体中 (如自动添加的 _id),用零值填充
  27. result = append(result, types.FieldValue{
  28. FieldName: []byte(fd.ColName),
  29. Value: zeroValue(fd),
  30. })
  31. continue
  32. }
  33. val := normalizeValue(fv, fd)
  34. result = append(result, types.FieldValue{
  35. FieldName: []byte(fd.ColName),
  36. Value: val,
  37. })
  38. }
  39. return result, nil
  40. }
  41. // fieldValuesToStruct 将 core 查询结果的 FieldValue 切片反序列化到结构体
  42. func fieldValuesToStruct(fvs []types.FieldValue, model *ModelInfo, obj interface{}) error {
  43. v := reflect.ValueOf(obj)
  44. if v.Kind() != reflect.Ptr || v.Elem().Kind() != reflect.Struct {
  45. return fmt.Errorf("tsdb: obj must be a pointer to struct")
  46. }
  47. v = v.Elem()
  48. // 建立列名 → FieldValue 映射
  49. colMap := make(map[string]types.FieldValue, len(fvs))
  50. for _, fv := range fvs {
  51. colMap[string(fv.FieldName)] = fv
  52. }
  53. for _, fd := range model.AllFields {
  54. fv, ok := colMap[fd.ColName]
  55. if !ok {
  56. continue
  57. }
  58. target := findSettableField(v, fd.Name, model.StructType)
  59. if !target.IsValid() || !target.CanSet() {
  60. continue
  61. }
  62. if err := setFieldFromValue(target, fv.Value, fd); err != nil {
  63. return fmt.Errorf("tsdb: set field %s: %w", fd.Name, err)
  64. }
  65. }
  66. return nil
  67. }
  68. // findField 在结构体中查找字段 (支持嵌入结构体)
  69. func findField(v reflect.Value, name string, t reflect.Type) reflect.Value {
  70. // 直接查找
  71. if f := v.FieldByName(name); f.IsValid() {
  72. return f
  73. }
  74. // 在嵌入结构体中查找
  75. for i := 0; i < t.NumField(); i++ {
  76. sf := t.Field(i)
  77. if sf.Anonymous {
  78. fv := v.Field(i)
  79. if sf.Type == baseModelType || sf.Type == timeSeriesModelType {
  80. if inner := fv.FieldByName(name); inner.IsValid() {
  81. return inner
  82. }
  83. } else if sf.Type.Kind() == reflect.Struct {
  84. if inner := findField(fv, name, sf.Type); inner.IsValid() {
  85. return inner
  86. }
  87. }
  88. }
  89. }
  90. return reflect.Value{}
  91. }
  92. // findSettableField 同 findField 但确保返回可设置的字段
  93. func findSettableField(v reflect.Value, name string, t reflect.Type) reflect.Value {
  94. return findField(v, name, t)
  95. }
  96. // normalizeValue 将反射字段值转换为 core 可接受的值
  97. func normalizeValue(fv reflect.Value, fd FieldDef) interface{} {
  98. iface := fv.Interface()
  99. switch fd.FieldType {
  100. case types.FieldType_1byte:
  101. return toInt8(iface)
  102. case types.FieldType_2byte:
  103. return toInt16(iface)
  104. case types.FieldType_4byte:
  105. return toInt32(iface)
  106. case types.FieldType_8byte:
  107. return toUint64(iface)
  108. case types.FieldType_16byte, types.FieldType_32byte,
  109. types.FieldType_64byte, types.FieldType_128byte, types.FieldType_256byte:
  110. return toFixedBytes(iface, int(types.GetSize(fd.FieldType)))
  111. case types.FieldType_Dynamicbyte:
  112. return toBytes(iface)
  113. default:
  114. return iface
  115. }
  116. }
  117. // setFieldFromValue 将 core 返回值设置到结构体字段
  118. func setFieldFromValue(target reflect.Value, val interface{}, fd FieldDef) error {
  119. if val == nil {
  120. return nil
  121. }
  122. switch v := val.(type) {
  123. case uint64:
  124. setIntField(target, int64(v))
  125. case int64:
  126. setIntField(target, v)
  127. case int32:
  128. setIntField(target, int64(v))
  129. case int16:
  130. setIntField(target, int64(v))
  131. case int8:
  132. setIntField(target, int64(v))
  133. case float64:
  134. setFloatField(target, v)
  135. case float32:
  136. setFloatField(target, float64(v))
  137. case []byte:
  138. setBytesField(target, v, fd)
  139. default:
  140. // 尝试直接设置
  141. rv := reflect.ValueOf(val)
  142. if rv.Type().AssignableTo(target.Type()) {
  143. target.Set(rv)
  144. }
  145. }
  146. return nil
  147. }
  148. func setIntField(target reflect.Value, val int64) {
  149. switch target.Kind() {
  150. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  151. target.SetInt(val)
  152. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  153. target.SetUint(uint64(val))
  154. case reflect.Float32, reflect.Float64:
  155. target.SetFloat(float64(val))
  156. }
  157. }
  158. func setFloatField(target reflect.Value, val float64) {
  159. switch target.Kind() {
  160. case reflect.Float32, reflect.Float64:
  161. target.SetFloat(val)
  162. case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
  163. target.SetInt(int64(val))
  164. case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
  165. target.SetUint(uint64(val))
  166. }
  167. }
  168. func setBytesField(target reflect.Value, val []byte, fd FieldDef) {
  169. switch target.Kind() {
  170. case reflect.String:
  171. // 截断到第一个 null 字节
  172. s := string(val)
  173. for i, c := range s {
  174. if c == 0 {
  175. s = s[:i]
  176. break
  177. }
  178. }
  179. target.SetString(s)
  180. case reflect.Slice:
  181. if target.Type().Elem().Kind() == reflect.Uint8 {
  182. target.SetBytes(val)
  183. }
  184. }
  185. }
  186. // ===== 类型转换辅助函数 =====
  187. func toUint64(v interface{}) uint64 {
  188. switch val := v.(type) {
  189. case uint64:
  190. return val
  191. case int64:
  192. return uint64(val)
  193. case int:
  194. return uint64(val)
  195. case int32:
  196. return uint64(val)
  197. case uint32:
  198. return uint64(val)
  199. case int16:
  200. return uint64(val)
  201. case uint16:
  202. return uint64(val)
  203. case int8:
  204. return uint64(val)
  205. case uint8:
  206. return uint64(val)
  207. case float64:
  208. return uint64(val)
  209. case float32:
  210. return uint64(val)
  211. default:
  212. rv := reflect.ValueOf(v)
  213. if rv.CanUint() {
  214. return rv.Uint()
  215. }
  216. if rv.CanInt() {
  217. return uint64(rv.Int())
  218. }
  219. return 0
  220. }
  221. }
  222. func toInt8(v interface{}) int8 { return int8(toUint64(v)) }
  223. func toInt16(v interface{}) int16 { return int16(toUint64(v)) }
  224. func toInt32(v interface{}) int32 { return int32(toUint64(v)) }
  225. func toFixedBytes(v interface{}, size int) []byte {
  226. buf := make([]byte, size)
  227. switch val := v.(type) {
  228. case string:
  229. copy(buf, val)
  230. case []byte:
  231. copy(buf, val)
  232. default:
  233. // 数值类型: BigEndian 编码
  234. rv := reflect.ValueOf(v)
  235. if rv.CanUint() {
  236. binary.BigEndian.PutUint64(buf, rv.Uint())
  237. } else if rv.CanInt() {
  238. binary.BigEndian.PutUint64(buf, uint64(rv.Int()))
  239. }
  240. }
  241. return buf
  242. }
  243. func toBytes(v interface{}) []byte {
  244. switch val := v.(type) {
  245. case []byte:
  246. return val
  247. case string:
  248. return []byte(val)
  249. default:
  250. return nil
  251. }
  252. }
  253. // getPKValue 从结构体中提取主键值
  254. func getPKValue(obj interface{}, model *ModelInfo) uint64 {
  255. if !model.PKInStruct {
  256. return 0 // PK 不在结构体中,返回 0 让 core 自动分配
  257. }
  258. v := reflect.ValueOf(obj)
  259. if v.Kind() == reflect.Ptr {
  260. v = v.Elem()
  261. }
  262. pkDef := model.AllFields[model.PKIndex]
  263. fv := findField(v, pkDef.Name, model.StructType)
  264. if !fv.IsValid() {
  265. return 0
  266. }
  267. return toUint64(fv.Interface())
  268. }
  269. // setPKValue 设置结构体的主键值
  270. func setPKValue(obj interface{}, model *ModelInfo, pk uint64) {
  271. if !model.PKInStruct {
  272. return // PK 不在结构体中,无法回写
  273. }
  274. v := reflect.ValueOf(obj)
  275. if v.Kind() == reflect.Ptr {
  276. v = v.Elem()
  277. }
  278. pkDef := model.AllFields[model.PKIndex]
  279. fv := findField(v, pkDef.Name, model.StructType)
  280. if fv.IsValid() && fv.CanSet() {
  281. fv.SetUint(pk)
  282. }
  283. }
  284. // zeroValue 返回字段类型的零值
  285. func zeroValue(fd FieldDef) interface{} {
  286. switch fd.FieldType {
  287. case types.FieldType_1byte:
  288. return int8(0)
  289. case types.FieldType_2byte:
  290. return int16(0)
  291. case types.FieldType_4byte:
  292. return int32(0)
  293. case types.FieldType_8byte:
  294. return uint64(0)
  295. default:
  296. size := int(types.GetSize(fd.FieldType))
  297. if size > 0 {
  298. return make([]byte, size)
  299. }
  300. return make([]byte, 12) // dynamic
  301. }
  302. }