Files
go-utils/query_parser/filter.go

181 lines
6.0 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package query_parser
import (
"strings"
"github.com/go-kratos/kratos/v2/encoding"
_ "github.com/go-kratos/kratos/v2/encoding/json"
"github.com/tx7do/go-utils/stringcase"
)
type FilterOperator string
const (
FilterNot = "not" // 不等于
FilterIn = "in" // 检查值是否在列表中
FilterNotIn = "not_in" // 不在列表中
FilterGTE = "gte" // 大于或等于传递的值
FilterGT = "gt" // 大于传递值
FilterLTE = "lte" // 小于或等于传递值
FilterLT = "lt" // 小于传递值
FilterRange = "range" // 是否介于和给定的两个值之间
FilterIsNull = "isnull" // 是否为空
FilterNotIsNull = "not_isnull" // 是否不为空
FilterContains = "contains" // 是否包含指定的子字符串
FilterInsensitiveContains = "icontains" // 不区分大小写,是否包含指定的子字符串
FilterStartsWith = "startswith" // 以值开头
FilterInsensitiveStartsWith = "istartswith" // 不区分大小写,以值开头
FilterEndsWith = "endswith" // 以值结尾
FilterInsensitiveEndsWith = "iendswith" // 不区分大小写,以值结尾
FilterExact = "exact" // 精确匹配
FilterInsensitiveExact = "iexact" // 不区分大小写,精确匹配
FilterRegex = "regex" // 正则表达式
FilterInsensitiveRegex = "iregex" // 不区分大小写,正则表达式
FilterSearch = "search" // 全文搜索
)
const (
DatePartDate = "date" // 日期
DatePartYear = "year" // 年
DatePartISOYear = "iso_year" // ISO8601 一年中的周数
DatePartQuarter = "quarter" // 季度
DatePartMonth = "month" // 月
DatePartWeek = "week" // ISO8601 周编号 一年中的周数
DatePartWeekDay = "week_day" // 星期几
DatePartISOWeekDay = "iso_week_day" // ISO8601 星期几
DatePartDay = "day" // 日
DatePartTime = "time" // 小时:分钟:秒
DatePartHour = "hour" // 小时
DatePartMinute = "minute" // 分钟
DatePartSecond = "second" // 秒
DatePartMicrosecond = "microsecond" // 微秒
)
const (
JSONFilterFieldOperatorDelimiter = "__" // JSON过滤器 - 字段名和操作符的分隔符
QueryFilterFieldOperatorDelimiter = ":" // 自定义查询字符串过滤器 - 字段名和操作符的分隔符
QueryFilterQueriesDelimiter = "," // 自定义查询字符串过滤器 - 多个键值对的分隔符
QueryFilterValuesDelimiter = "|" // 自定义查询字符串过滤器 - 多个值的分隔符
JsonFieldDelimiter = "." // JSON字段分隔符
)
type FilterHandler func(field, operator, value string)
// ParseFilterJSONString 解析过滤条件的JSON字符串调用处理函数
func ParseFilterJSONString(query string, handler FilterHandler) error {
if query == "" {
return nil
}
codec := encoding.GetCodec("json")
var err error
queryMap := make(map[string]string)
if err = codec.Unmarshal([]byte(query), &queryMap); err == nil {
for k, v := range queryMap {
ParseFilterField(k, v, handler)
}
return nil
}
var queryMapArray []map[string]string
if err = codec.Unmarshal([]byte(query), &queryMapArray); err == nil {
for _, item := range queryMapArray {
for k, v := range item {
ParseFilterField(k, v, handler)
}
}
return nil
}
return err
}
// ParseFilterQueryString 解析过滤条件的查询字符串,调用处理函数
func ParseFilterQueryString(query string, handler FilterHandler) error {
if query == "" {
return nil // 如果查询字符串为空,直接返回
}
// 按逗号分割查询字符串,得到多个键值对
pairs := SplitQueryQueries(query)
for _, pair := range pairs {
// 按冒号分割键值对,提取字段名和值
parts := SplitQueryFieldAndOperator(pair)
if len(parts) != 2 {
continue // 跳过无效的键值对
}
// 解码字段名
key, err := DecodeSpecialCharacters(strings.TrimSpace(parts[0]))
if err != nil {
continue // 跳过解码失败的键值对
}
// 解码字段值
value, err := DecodeSpecialCharacters(strings.TrimSpace(parts[1]))
if err != nil {
continue // 跳过解码失败的键值对
}
// 调用 ParseFilterField 解析字段和操作符
ParseFilterField(key, value, handler)
}
return nil
}
// ParseFilterField 解析过滤条件字符串,调用处理函数
func ParseFilterField(key, value string, handler FilterHandler) {
if key == "" || value == "" {
return // 没有过滤条件
}
// 处理字段和操作符
parts := SplitJsonFieldAndOperator(key)
if len(parts) < 1 {
return // 无效的字段格式
}
field := strings.TrimSpace(parts[0])
if field == "" {
return
}
field = stringcase.ToSnakeCase(parts[0])
op := ""
if len(parts) > 1 {
op = parts[1]
}
handler(field, op, value)
}
// SplitJsonFieldAndOperator JSON过滤器 - 分割“字段名”和“操作符”
func SplitJsonFieldAndOperator(field string) []string {
return strings.Split(field, JSONFilterFieldOperatorDelimiter)
}
// SplitQueryFieldAndOperator 自定义查询字符串过滤器 - 分割“字段名”和“操作符”
func SplitQueryFieldAndOperator(field string) []string {
return strings.Split(field, QueryFilterFieldOperatorDelimiter)
}
// SplitQueryQueries 自定义查询字符串过滤器 - 分割多个键值对
func SplitQueryQueries(field string) []string {
return strings.Split(field, QueryFilterQueriesDelimiter)
}
// SplitQueryValues 自定义查询字符串过滤器 - 分割多个值
func SplitQueryValues(field string) []string {
return strings.Split(field, QueryFilterValuesDelimiter)
}
// SplitJSONField 将JSONB字段字符串按分隔符分割成多个字段
func SplitJSONField(field string) []string {
return strings.Split(field, JsonFieldDelimiter)
}