updater.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. package core
  2. import (
  3. "TsDB2/DB/core/page"
  4. "TsDB2/DB/core/types"
  5. "TsDB2/DB/core/util"
  6. "encoding/binary"
  7. )
  8. // Updater 更新操作对象
  9. type Updater struct {
  10. table *Table
  11. updates map[string]interface{}
  12. where Condition
  13. }
  14. // Update 返回更新操作对象
  15. func (table *Table) Update() *Updater {
  16. return &Updater{
  17. table: table,
  18. updates: make(map[string]interface{}),
  19. }
  20. }
  21. // Set 设置更新字段
  22. func (u *Updater) Set(field string, value interface{}) *Updater {
  23. u.updates[field] = value
  24. return u
  25. }
  26. // Where 设置更新条件
  27. func (u *Updater) Where(cond Condition) *Updater {
  28. u.where = cond
  29. return u
  30. }
  31. // Exec 执行更新
  32. func (u *Updater) Exec() (int64, error) {
  33. // 扫描匹配行
  34. q := u.table.Query().Where(u.where)
  35. results, err := q.Find()
  36. if err != nil {
  37. return 0, err
  38. }
  39. // 找主键索引名
  40. var pkIdxName string
  41. for i := range u.table.indexMeta.metas {
  42. m := &u.table.indexMeta.metas[i]
  43. if m.Flag&0x80 != 0 {
  44. continue
  45. }
  46. if m.IndexType == page.IndexTypePrimary || m.IndexType == page.IndexTypeTime {
  47. pkIdxName = util.BytesToString(m.IndexName[:])
  48. break
  49. }
  50. }
  51. if pkIdxName == "" {
  52. return 0, nil
  53. }
  54. var count int64
  55. for _, row := range results {
  56. // 找主键字段 (第一个 uint64 字段作为 pkID)
  57. for _, fv := range row {
  58. if v, ok := fv.Value.(uint64); ok {
  59. key := make([]byte, 8)
  60. binary.BigEndian.PutUint64(key, v)
  61. // 构建新行值
  62. var values []types.FieldValue
  63. for field, val := range u.updates {
  64. values = append(values, types.FieldValue{
  65. FieldName: []byte(field),
  66. Value: val,
  67. })
  68. }
  69. if err := u.table.UpdateRow(pkIdxName, key, values); err == nil {
  70. count++
  71. }
  72. break
  73. }
  74. }
  75. }
  76. return count, nil
  77. }