LikeCondition.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package core
  2. import (
  3. "TsDB2/DB/core/types"
  4. "strings"
  5. )
  6. type LikeCondition struct {
  7. Field string
  8. Pattern string
  9. CaseSensitive bool
  10. }
  11. func Like(field string, pattern string) Condition {
  12. return LikeCondition{Field: field, Pattern: pattern, CaseSensitive: true}
  13. }
  14. func ILike(field string, pattern string) Condition {
  15. return LikeCondition{Field: field, Pattern: pattern, CaseSensitive: false}
  16. }
  17. func (c LikeCondition) Fields() []string {
  18. return []string{c.Field}
  19. }
  20. func (c LikeCondition) Match(row []byte, table *Table) bool {
  21. fieldIdx := table.findFieldIndex(c.Field)
  22. if fieldIdx < 0 {
  23. return false
  24. }
  25. offset, ok := table.getVersionedOffset(row, fieldIdx)
  26. if !ok {
  27. return false
  28. }
  29. fieldInfo := table.Field[fieldIdx]
  30. // 读取字符串值
  31. size := int(types.GetSize(fieldInfo.FieldType))
  32. if size <= 0 || int(offset)+size > len(row) {
  33. return false
  34. }
  35. stored := strings.TrimRight(string(row[offset:int(offset)+size]), "\x00")
  36. // 模式匹配
  37. if !c.CaseSensitive {
  38. stored = strings.ToLower(stored)
  39. pattern := strings.ToLower(c.Pattern)
  40. return likeMatch(stored, pattern)
  41. }
  42. return likeMatch(stored, c.Pattern)
  43. }
  44. // likeMatch 简单的 LIKE 模式匹配(支持 % 和 _)
  45. func likeMatch(str, pattern string) bool {
  46. // 将 LIKE 模式转换为简单的通配符匹配
  47. // % 匹配任意字符序列(包括空序列)
  48. // _ 匹配任意单个字符
  49. // 简化实现:使用 strings.Contains 处理 %
  50. parts := strings.Split(pattern, "%")
  51. if len(parts) == 1 {
  52. // 没有 %,直接比较
  53. return str == pattern
  54. }
  55. // 检查前缀
  56. if parts[0] != "" && !strings.HasPrefix(str, parts[0]) {
  57. return false
  58. }
  59. // 检查后缀
  60. if parts[len(parts)-1] != "" && !strings.HasSuffix(str, parts[len(parts)-1]) {
  61. return false
  62. }
  63. // 检查中间部分
  64. current := str
  65. if parts[0] != "" {
  66. current = current[len(parts[0]):]
  67. }
  68. for i := 1; i < len(parts); i++ {
  69. idx := strings.Index(current, parts[i])
  70. if idx == -1 {
  71. return false
  72. }
  73. current = current[idx+len(parts[i]):]
  74. }
  75. return true
  76. }