query.go 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package DB
  2. import (
  3. "TsDB2/DB/core"
  4. "TsDB2/DB/core/types"
  5. "fmt"
  6. )
  7. // Query 泛型查询构建器
  8. type Query[T any] struct {
  9. table *Table[T]
  10. wheres []whereClause
  11. orders []orderClause
  12. limit int
  13. offset int
  14. }
  15. type whereClause struct {
  16. field string
  17. op string
  18. value interface{}
  19. }
  20. type orderClause struct {
  21. field string
  22. desc bool
  23. }
  24. func (q *Query[T]) addWhere(field, op string, value interface{}) *Query[T] {
  25. q.wheres = append(q.wheres, whereClause{field: field, op: op, value: value})
  26. return q
  27. }
  28. // Where 添加条件
  29. func (q *Query[T]) Where(field string, op string, value interface{}) *Query[T] {
  30. q.wheres = append(q.wheres, whereClause{field: field, op: op, value: value})
  31. return q
  32. }
  33. // OrderBy 排序
  34. func (q *Query[T]) OrderBy(field string, desc ...bool) *Query[T] {
  35. d := false
  36. if len(desc) > 0 && desc[0] {
  37. d = true
  38. }
  39. q.orders = append(q.orders, orderClause{field: field, desc: d})
  40. return q
  41. }
  42. // Limit 限制行数
  43. func (q *Query[T]) Limit(n int) *Query[T] {
  44. q.limit = n
  45. return q
  46. }
  47. // Offset 跳过行数
  48. func (q *Query[T]) Offset(n int) *Query[T] {
  49. q.offset = n
  50. return q
  51. }
  52. // Find 执行查询返回所有结果
  53. //
  54. // 用 ScanWithPKID 而不是 Find: 行号不在字段值里, 但它决定了返回的对象能不能被精确
  55. // 地改 / 删 —— 同一个时间戳下有多行时, 只有行号指得清"返回的是哪一行"。
  56. func (q *Query[T]) Find() ([]*T, error) {
  57. cq := q.buildCoreQuery()
  58. result := make([]*T, 0)
  59. err := cq.ScanWithPKID(func(pkID uint64, row []types.FieldValue) bool {
  60. obj := new(T)
  61. if err := fieldValuesToStruct(row, q.table.model, obj); err != nil {
  62. return true
  63. }
  64. setRowIDOf(obj, pkID)
  65. q.table.bindModel(obj)
  66. result = append(result, obj)
  67. return true
  68. })
  69. if err != nil {
  70. return nil, err
  71. }
  72. return result, nil
  73. }
  74. // First 返回第一条结果
  75. func (q *Query[T]) First() (*T, error) {
  76. q.limit = 1
  77. results, err := q.Find()
  78. if err != nil {
  79. return nil, err
  80. }
  81. if len(results) == 0 {
  82. return nil, fmt.Errorf("tsdb: record not found")
  83. }
  84. return results[0], nil
  85. }
  86. // Count 返回匹配行数
  87. func (q *Query[T]) Count() (int64, error) {
  88. cq := q.buildCoreQuery()
  89. return cq.Count()
  90. }
  91. // Scan 流式遍历
  92. func (q *Query[T]) Scan(callback func(*T) bool) error {
  93. cq := q.buildCoreQuery()
  94. return cq.ScanWithPKID(func(pkID uint64, row []types.FieldValue) bool {
  95. obj := new(T)
  96. if err := fieldValuesToStruct(row, q.table.model, obj); err != nil {
  97. return true
  98. }
  99. setRowIDOf(obj, pkID)
  100. q.table.bindModel(obj)
  101. return callback(obj)
  102. })
  103. }
  104. // buildCoreQuery 构建 core 层的 Query
  105. func (q *Query[T]) buildCoreQuery() *core.Query {
  106. cq := q.table.coreTable.Query()
  107. // 构建 WHERE 条件
  108. if len(q.wheres) > 0 {
  109. cond := q.buildCondition(q.wheres[0])
  110. for i := 1; i < len(q.wheres); i++ {
  111. cond = core.And(cond, q.buildCondition(q.wheres[i]))
  112. }
  113. cq = cq.Where(cond)
  114. }
  115. // ORDER BY
  116. for _, o := range q.orders {
  117. cq = cq.OrderBy(o.field, o.desc)
  118. }
  119. // LIMIT / OFFSET
  120. if q.limit > 0 {
  121. cq = cq.Limit(q.limit)
  122. }
  123. if q.offset > 0 {
  124. cq = cq.Offset(q.offset)
  125. }
  126. return cq
  127. }
  128. // buildCondition 将 whereClause 转换为 core.Condition
  129. func (q *Query[T]) buildCondition(w whereClause) core.Condition {
  130. // ft 只用来把条件值归一化成列期望的 Go 类型 (normalizeCondValue);
  131. // 条件构造函数的第三个参数已废弃 —— 比较一律按列的实际存储类型进行
  132. // (见 core.Table.compareTypeFor), 故统一传 types.FieldType(0)。
  133. ft := q.findFieldType(w.field)
  134. val := normalizeCondValue(w.value, ft)
  135. switch w.op {
  136. case "=", "==", "eq":
  137. return core.Eq(w.field, val, types.FieldType(0))
  138. case "!=", "<>":
  139. return core.Not(core.Eq(w.field, val, types.FieldType(0)))
  140. case ">", "gt":
  141. return core.Gt(w.field, val, types.FieldType(0))
  142. case ">=", "ge", "gte":
  143. return core.Ge(w.field, val, types.FieldType(0))
  144. case "<", "lt":
  145. return core.Lt(w.field, val, types.FieldType(0))
  146. case "<=", "le", "lte":
  147. return core.Le(w.field, val, types.FieldType(0))
  148. case "like":
  149. if s, ok := w.value.(string); ok {
  150. return core.Like(w.field, s)
  151. }
  152. return core.Eq(w.field, val, types.FieldType(0))
  153. default:
  154. return core.Eq(w.field, val, types.FieldType(0))
  155. }
  156. }
  157. // normalizeCondValue 将条件值转换为 core 期望的类型
  158. func normalizeCondValue(v interface{}, ft types.FieldType) interface{} {
  159. switch ft {
  160. case types.FieldType_8byte:
  161. return toUint64(v)
  162. case types.FieldType_4byte:
  163. return toInt32(v)
  164. case types.FieldType_2byte:
  165. return int16(toUint64(v))
  166. case types.FieldType_1byte:
  167. return uint8(toUint64(v))
  168. case types.FieldType_Int8:
  169. return toInt8(v)
  170. case types.FieldType_Int16:
  171. return toInt16(v)
  172. case types.FieldType_Int32:
  173. return toInt32(v)
  174. case types.FieldType_Int64:
  175. return toInt64(v)
  176. case types.FieldType_Float64:
  177. // 不能走 toUint64: 那会把条件值的小数先砍掉, 变成在浮点列上按整数匹配
  178. return toFloatVal(v)
  179. // ===== 扩展类型 =====
  180. //
  181. // 全部原样下传, 交给 core 的 types.EncodeValue / DecimalFromValue 解析与校验。
  182. // 尤其是 Decimal / UUID: 条件值常常是字符串 ("1.50" / "550e8400-..."), 一旦落进
  183. // 下面的 default 分支会被当定长串补零成定长字节, 比较和索引键就全错了。
  184. case types.FieldType_Bool,
  185. types.FieldType_Float32,
  186. types.FieldType_Decimal,
  187. types.FieldType_UUID,
  188. types.FieldType_Year,
  189. types.FieldType_Int128,
  190. types.FieldType_Blob:
  191. return v
  192. default:
  193. // 定长字符串类型: 原样下传, 由 core 按【列的实际宽度】编码
  194. // (types.EncodeValue 接受 string, 并顺带成为宽度闸门: 超宽报错而不是截断)。
  195. //
  196. // 不能在这里按 types.GetSize(ft) 自己补零: 那只是类型默认宽度, 对用宽度码声明的
  197. // 列 (maxlen:1000 → 1024 字节档) 会编出 256 字节——与行内字节不同源, 比较与索引键
  198. // 全错。而且这里只有 ft 没有列级参数, 本就拼不出正确的宽度。
  199. return v
  200. }
  201. }
  202. // findFieldType 查找字段的 FieldType
  203. // 优先从 DB schema 查找,回退到 struct model
  204. func (q *Query[T]) findFieldType(name string) types.FieldType {
  205. // 优先从 DB schema 查找
  206. if ft, ok := q.table.coreTable.GetActiveFieldType(name); ok {
  207. return ft
  208. }
  209. // 回退到 struct model
  210. for _, fd := range q.table.model.AllFields {
  211. if fd.ColName == name || fd.Name == name {
  212. return fd.FieldType
  213. }
  214. }
  215. return types.FieldType_8byte // 默认
  216. }