| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- package DB
- import (
- "TsDB2/DB/core"
- "TsDB2/DB/core/types"
- "fmt"
- )
- // Query 泛型查询构建器
- type Query[T any] struct {
- table *Table[T]
- wheres []whereClause
- orders []orderClause
- limit int
- offset int
- }
- type whereClause struct {
- field string
- op string
- value interface{}
- }
- type orderClause struct {
- field string
- desc bool
- }
- func (q *Query[T]) addWhere(field, op string, value interface{}) *Query[T] {
- q.wheres = append(q.wheres, whereClause{field: field, op: op, value: value})
- return q
- }
- // Where 添加条件
- func (q *Query[T]) Where(field string, op string, value interface{}) *Query[T] {
- q.wheres = append(q.wheres, whereClause{field: field, op: op, value: value})
- return q
- }
- // OrderBy 排序
- func (q *Query[T]) OrderBy(field string, desc ...bool) *Query[T] {
- d := false
- if len(desc) > 0 && desc[0] {
- d = true
- }
- q.orders = append(q.orders, orderClause{field: field, desc: d})
- return q
- }
- // Limit 限制行数
- func (q *Query[T]) Limit(n int) *Query[T] {
- q.limit = n
- return q
- }
- // Offset 跳过行数
- func (q *Query[T]) Offset(n int) *Query[T] {
- q.offset = n
- return q
- }
- // Find 执行查询返回所有结果
- func (q *Query[T]) Find() ([]*T, error) {
- cq := q.buildCoreQuery()
- rows, err := cq.Find()
- if err != nil {
- return nil, err
- }
- result := make([]*T, 0, len(rows))
- for _, row := range rows {
- obj := new(T)
- if err := fieldValuesToStruct(row, q.table.model, obj); err != nil {
- continue
- }
- result = append(result, obj)
- }
- return result, nil
- }
- // First 返回第一条结果
- func (q *Query[T]) First() (*T, error) {
- q.limit = 1
- results, err := q.Find()
- if err != nil {
- return nil, err
- }
- if len(results) == 0 {
- return nil, fmt.Errorf("tsdb: record not found")
- }
- return results[0], nil
- }
- // Count 返回匹配行数
- func (q *Query[T]) Count() (int64, error) {
- cq := q.buildCoreQuery()
- return cq.Count()
- }
- // Scan 流式遍历
- func (q *Query[T]) Scan(callback func(*T) bool) error {
- cq := q.buildCoreQuery()
- return cq.Scan(func(row []types.FieldValue) bool {
- obj := new(T)
- if err := fieldValuesToStruct(row, q.table.model, obj); err != nil {
- return true
- }
- return callback(obj)
- })
- }
- // buildCoreQuery 构建 core 层的 Query
- func (q *Query[T]) buildCoreQuery() *core.Query {
- cq := q.table.coreTable.Query()
- // 构建 WHERE 条件
- if len(q.wheres) > 0 {
- cond := q.buildCondition(q.wheres[0])
- for i := 1; i < len(q.wheres); i++ {
- cond = core.And(cond, q.buildCondition(q.wheres[i]))
- }
- cq = cq.Where(cond)
- }
- // ORDER BY
- for _, o := range q.orders {
- cq = cq.OrderBy(o.field, o.desc)
- }
- // LIMIT / OFFSET
- if q.limit > 0 {
- cq = cq.Limit(q.limit)
- }
- if q.offset > 0 {
- cq = cq.Offset(q.offset)
- }
- return cq
- }
- // buildCondition 将 whereClause 转换为 core.Condition
- func (q *Query[T]) buildCondition(w whereClause) core.Condition {
- ft := q.findFieldType(w.field)
- val := normalizeCondValue(w.value, ft)
- switch w.op {
- case "=", "==", "eq":
- return core.Eq(w.field, val, ft)
- case "!=", "<>":
- return core.Not(core.Eq(w.field, val, ft))
- case ">", "gt":
- return core.Gt(w.field, val, ft)
- case ">=", "ge", "gte":
- return core.Ge(w.field, val, ft)
- case "<", "lt":
- return core.Lt(w.field, val, ft)
- case "<=", "le", "lte":
- return core.Le(w.field, val, ft)
- case "like":
- if s, ok := w.value.(string); ok {
- return core.Like(w.field, s)
- }
- return core.Eq(w.field, val, ft)
- default:
- return core.Eq(w.field, val, ft)
- }
- }
- // normalizeCondValue 将条件值转换为 core 期望的类型
- func normalizeCondValue(v interface{}, ft types.FieldType) interface{} {
- switch ft {
- case types.FieldType_8byte:
- return toUint64(v)
- case types.FieldType_4byte:
- return toInt32(v)
- case types.FieldType_2byte:
- return int16(toUint64(v))
- case types.FieldType_1byte:
- return int8(toUint64(v))
- default:
- // 定长字符串类型: 转换为 []byte (core 的 encodeIndexKey 需要)
- if s, ok := v.(string); ok {
- return toFixedBytes(s, int(types.GetSize(ft)))
- }
- return v
- }
- }
- // findFieldType 查找字段的 FieldType
- // 优先从 DB schema 查找,回退到 struct model
- func (q *Query[T]) findFieldType(name string) types.FieldType {
- // 优先从 DB schema 查找
- if ft, ok := q.table.coreTable.GetActiveFieldType(name); ok {
- return ft
- }
- // 回退到 struct model
- for _, fd := range q.table.model.AllFields {
- if fd.ColName == name || fd.Name == name {
- return fd.FieldType
- }
- }
- return types.FieldType_8byte // 默认
- }
|