feat: entgo query .
This commit is contained in:
322
entgo/filter.go
Normal file
322
entgo/filter.go
Normal file
@@ -0,0 +1,322 @@
|
||||
package entgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
"github.com/tx7do/kratos-utils/stringcase"
|
||||
)
|
||||
|
||||
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" // 不区分大小写等于
|
||||
FilterSearch = "search" // 全文搜索
|
||||
)
|
||||
|
||||
const (
|
||||
FilterDatePartYear = "year" // 年
|
||||
FilterDatePartQuarter = "quarter" // 季度
|
||||
FilterDatePartMonth = "month" // 月
|
||||
FilterDatePartWeek = "week" // 星期
|
||||
FilterDatePartDay = "day" // 日
|
||||
FilterDatePartHour = "hour" // 小时
|
||||
FilterDatePartMinute = "minute" // 分钟
|
||||
FilterDatePartSecond = "second" // 秒
|
||||
FilterDatePartMicrosecond = "microsecond" // 微秒
|
||||
)
|
||||
|
||||
// QueryCommandToWhereConditions 查询命令转换为选择条件
|
||||
func QueryCommandToWhereConditions(strJson string, isOr bool) (error, func(s *sql.Selector)) {
|
||||
if len(strJson) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
codec := encoding.GetCodec("json")
|
||||
|
||||
queryMap := make(map[string]string)
|
||||
var queryMapArray []map[string]string
|
||||
if err1 := codec.Unmarshal([]byte(strJson), &queryMap); err1 != nil {
|
||||
if err2 := codec.Unmarshal([]byte(strJson), &queryMapArray); err2 != nil {
|
||||
return err2, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, func(s *sql.Selector) {
|
||||
var ps []*sql.Predicate
|
||||
ps = append(ps, processQueryMap(s, queryMap)...)
|
||||
for _, v := range queryMapArray {
|
||||
ps = append(ps, processQueryMap(s, v)...)
|
||||
}
|
||||
|
||||
if isOr {
|
||||
s.Where(sql.Or(ps...))
|
||||
} else {
|
||||
s.Where(sql.And(ps...))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func processQueryMap(s *sql.Selector, queryMap map[string]string) []*sql.Predicate {
|
||||
var ps []*sql.Predicate
|
||||
for k, v := range queryMap {
|
||||
key := stringcase.ToSnakeCase(k)
|
||||
|
||||
keys := strings.Split(key, "__")
|
||||
|
||||
if cond := oneFieldFilter(s, keys, v); cond != nil {
|
||||
ps = append(ps, cond)
|
||||
}
|
||||
}
|
||||
|
||||
return ps
|
||||
}
|
||||
|
||||
func BuildFilterSelector(andFilterJsonString, orFilterJsonString string) (error, []func(s *sql.Selector)) {
|
||||
var err error
|
||||
var queryConditions []func(s *sql.Selector)
|
||||
|
||||
var andSelector func(s *sql.Selector)
|
||||
err, andSelector = QueryCommandToWhereConditions(andFilterJsonString, false)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
if andSelector != nil {
|
||||
queryConditions = append(queryConditions, andSelector)
|
||||
}
|
||||
|
||||
var orSelector func(s *sql.Selector)
|
||||
err, orSelector = QueryCommandToWhereConditions(orFilterJsonString, true)
|
||||
if err != nil {
|
||||
return err, nil
|
||||
}
|
||||
if orSelector != nil {
|
||||
queryConditions = append(queryConditions, orSelector)
|
||||
}
|
||||
|
||||
return nil, queryConditions
|
||||
}
|
||||
|
||||
func oneFieldFilter(s *sql.Selector, keys []string, value string) *sql.Predicate {
|
||||
var cond *sql.Predicate
|
||||
|
||||
if len(keys) == 1 {
|
||||
field := keys[0]
|
||||
cond = filterEqual(s, field, value)
|
||||
} else if len(keys) == 2 {
|
||||
if len(keys[0]) == 0 {
|
||||
return nil
|
||||
}
|
||||
field := keys[0]
|
||||
op := strings.ToLower(keys[1])
|
||||
switch op {
|
||||
case FilterNot:
|
||||
cond = filterNot(s, field, value)
|
||||
case FilterIn:
|
||||
cond = filterIn(s, field, value)
|
||||
case FilterNotIn:
|
||||
cond = filterNotIn(s, field, value)
|
||||
case FilterGTE:
|
||||
cond = filterGTE(s, field, value)
|
||||
case FilterGT:
|
||||
cond = filterGT(s, field, value)
|
||||
case FilterLTE:
|
||||
cond = filterLTE(s, field, value)
|
||||
case FilterLT:
|
||||
cond = filterLT(s, field, value)
|
||||
case FilterRange:
|
||||
cond = filterRange(s, field, value)
|
||||
case FilterIsNull:
|
||||
cond = filterIsNull(s, field, value)
|
||||
case FilterNotIsNull:
|
||||
cond = filterNotIsNull(s, field, value)
|
||||
case FilterContains:
|
||||
cond = filterContains(s, field, value)
|
||||
case FilterInsensitiveContains:
|
||||
cond = filterInsensitiveContains(s, field, value)
|
||||
case FilterStartsWith:
|
||||
cond = filterStartsWith(s, field, value)
|
||||
case FilterInsensitiveStartsWith:
|
||||
cond = filterInsensitiveStartsWith(s, field, value)
|
||||
case FilterEndsWith:
|
||||
cond = filterEndsWith(s, field, value)
|
||||
case FilterInsensitiveEndsWith:
|
||||
cond = filterInsensitiveEndsWith(s, field, value)
|
||||
case FilterInsensitiveExact:
|
||||
cond = filterInsensitiveExact(s, field, value)
|
||||
case FilterExact:
|
||||
cond = filterExact(s, field, value)
|
||||
case FilterSearch:
|
||||
cond = filterSearch(s, field, value)
|
||||
default:
|
||||
cond = filterDatePart(s, op, field, value)
|
||||
}
|
||||
}
|
||||
return cond
|
||||
}
|
||||
|
||||
// filterEqual 相等 WHERE "name" = $1
|
||||
func filterEqual(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.EQ(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterNot NOT操作 WHERE NOT ("name" = $1 AND "age" = $2)
|
||||
func filterNot(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.Not(sql.EQ(s.C(field), value))
|
||||
}
|
||||
|
||||
// filterIn IN操作
|
||||
func filterIn(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
var strs []string
|
||||
if err := json.Unmarshal([]byte(value), &strs); err == nil {
|
||||
return sql.In(s.C(field), strs)
|
||||
}
|
||||
|
||||
var float64s []float64
|
||||
if err := json.Unmarshal([]byte(value), &float64s); err == nil {
|
||||
return sql.In(s.C(field), strs)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// filterNotIn 操作
|
||||
func filterNotIn(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
var strs []string
|
||||
if err := json.Unmarshal([]byte(value), &strs); err == nil {
|
||||
return sql.NotIn(s.C(field), strs)
|
||||
}
|
||||
|
||||
var float64s []float64
|
||||
if err := json.Unmarshal([]byte(value), &float64s); err == nil {
|
||||
return sql.NotIn(s.C(field), strs)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// filterGTE 操作
|
||||
func filterGTE(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.GTE(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterGT 操作
|
||||
func filterGT(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.GT(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterLTE 操作
|
||||
func filterLTE(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.LTE(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterLT 操作
|
||||
func filterLT(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.LT(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterRange 操作
|
||||
func filterRange(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
var strs []string
|
||||
if err := json.Unmarshal([]byte(value), &strs); err == nil {
|
||||
if len(strs) != 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return sql.And(
|
||||
sql.GTE(s.C(field), strs[0]),
|
||||
sql.LTE(s.C(field), strs[1]),
|
||||
)
|
||||
}
|
||||
|
||||
var float64s []float64
|
||||
if err := json.Unmarshal([]byte(value), &float64s); err == nil {
|
||||
if len(float64s) != 2 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return sql.And(
|
||||
sql.GTE(s.C(field), float64s[0]),
|
||||
sql.LTE(s.C(field), float64s[1]),
|
||||
)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// filterIsNull 操作
|
||||
func filterIsNull(s *sql.Selector, field, _ string) *sql.Predicate {
|
||||
return sql.IsNull(s.C(field))
|
||||
}
|
||||
|
||||
// filterNotIsNull 操作
|
||||
func filterNotIsNull(s *sql.Selector, field, _ string) *sql.Predicate {
|
||||
return sql.Not(sql.IsNull(s.C(field)))
|
||||
}
|
||||
|
||||
// filterContains 前后模糊查询 WHERE city LIKE '%L%';
|
||||
func filterContains(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.Contains(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterInsensitiveContains 前后模糊查询 WHERE city ILIKE '%L%';
|
||||
func filterInsensitiveContains(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.ContainsFold(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterStartsWith 前缀+模糊查询 WHERE CustomerName LIKE 'La%';
|
||||
func filterStartsWith(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.HasPrefix(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterInsensitiveStartsWith 前缀+模糊查询 WHERE CustomerName ILIKE 'La%';
|
||||
func filterInsensitiveStartsWith(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.EqualFold(s.C(field), value+"%")
|
||||
}
|
||||
|
||||
// filterEndsWith 后缀+模糊查询 WHERE CustomerName LIKE '%a';
|
||||
func filterEndsWith(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.HasSuffix(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterInsensitiveEndsWith 后缀+模糊查询 WHERE CustomerName ILIKE '%a';
|
||||
func filterInsensitiveEndsWith(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.EqualFold(s.C(field), "%"+value)
|
||||
}
|
||||
|
||||
// filterInsensitiveExact 操作 WHERE CustomerName ILIKE 'a';
|
||||
func filterInsensitiveExact(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.EqualFold(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterInsensitiveExact 操作 WHERE CustomerName LIKE 'a';
|
||||
func filterExact(s *sql.Selector, field, value string) *sql.Predicate {
|
||||
return sql.Like(s.C(field), value)
|
||||
}
|
||||
|
||||
// filterSearch 全文搜索
|
||||
func filterSearch(s *sql.Selector, _, _ string) *sql.Predicate {
|
||||
return nil
|
||||
}
|
||||
|
||||
// filterDatePart 时间戳提取日期 select extract(quarter from timestamp '2018-08-15 12:10:10');
|
||||
func filterDatePart(s *sql.Selector, datePart, field, value string) *sql.Predicate {
|
||||
return nil
|
||||
}
|
||||
45
entgo/order.go
Normal file
45
entgo/order.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package entgo
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
)
|
||||
|
||||
// QueryCommandToOrderConditions 查询命令转换为排序条件
|
||||
func QueryCommandToOrderConditions(orderBys []string) (error, func(s *sql.Selector)) {
|
||||
if len(orderBys) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return nil, func(s *sql.Selector) {
|
||||
for _, v := range orderBys {
|
||||
if strings.HasPrefix(v, "-") {
|
||||
// 降序
|
||||
key := v[1:]
|
||||
if len(key) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
s.OrderBy(sql.Desc(s.C(key)))
|
||||
} else {
|
||||
// 升序
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
s.OrderBy(sql.Asc(s.C(v)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BuildOrderSelector(orderBys []string, defaultOrderField string) (error, func(s *sql.Selector)) {
|
||||
if len(orderBys) == 0 {
|
||||
return nil, func(s *sql.Selector) {
|
||||
s.OrderBy(sql.Desc(s.C(defaultOrderField)))
|
||||
}
|
||||
} else {
|
||||
return QueryCommandToOrderConditions(orderBys)
|
||||
}
|
||||
}
|
||||
26
entgo/pagination.go
Normal file
26
entgo/pagination.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package entgo
|
||||
|
||||
import (
|
||||
"entgo.io/ent/dialect/sql"
|
||||
|
||||
"github.com/tx7do/kratos-utils/pagination"
|
||||
)
|
||||
|
||||
func BuildPaginationSelector(page, pageSize int32, noPaging bool) func(*sql.Selector) {
|
||||
if noPaging {
|
||||
return nil
|
||||
}
|
||||
|
||||
if page == 0 {
|
||||
page = DefaultPage
|
||||
}
|
||||
|
||||
if pageSize == 0 {
|
||||
pageSize = DefaultPageSize
|
||||
}
|
||||
|
||||
return func(s *sql.Selector) {
|
||||
s.Offset(pagination.GetPageOffset(page, pageSize)).
|
||||
Limit(int(pageSize))
|
||||
}
|
||||
}
|
||||
64
entgo/query.go
Normal file
64
entgo/query.go
Normal file
@@ -0,0 +1,64 @@
|
||||
package entgo
|
||||
|
||||
import (
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
_ "github.com/go-kratos/kratos/v2/encoding/json"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultPage = 1
|
||||
DefaultPageSize = 10
|
||||
)
|
||||
|
||||
// parseJsonMap 解析JSON字符串里面的MAP,包含Array形式的Map
|
||||
func parseJsonMap(strJson []byte, retMap *map[string]string) error {
|
||||
codec := encoding.GetCodec("json")
|
||||
|
||||
var err error
|
||||
if err = codec.Unmarshal(strJson, retMap); err != nil {
|
||||
var retArray []map[string]string
|
||||
if err1 := codec.Unmarshal(strJson, &retArray); err1 == nil {
|
||||
for _, itemA := range retArray {
|
||||
for k, v := range itemA {
|
||||
(*retMap)[k] = v
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BuildQuerySelector 构建分页查询选择器
|
||||
func BuildQuerySelector(andFilterJsonString, orFilterJsonString string,
|
||||
page, pageSize int32, noPaging bool,
|
||||
orderBys []string, defaultOrderField string) (err error, whereSelectors []func(s *sql.Selector), querySelectors []func(s *sql.Selector)) {
|
||||
err, whereSelectors = BuildFilterSelector(andFilterJsonString, orFilterJsonString)
|
||||
if err != nil {
|
||||
return err, nil, nil
|
||||
}
|
||||
|
||||
var orderSelector func(s *sql.Selector)
|
||||
err, orderSelector = BuildOrderSelector(orderBys, defaultOrderField)
|
||||
if err != nil {
|
||||
return err, nil, nil
|
||||
}
|
||||
|
||||
pageSelector := BuildPaginationSelector(page, pageSize, noPaging)
|
||||
|
||||
if len(whereSelectors) > 0 {
|
||||
querySelectors = append(querySelectors, whereSelectors...)
|
||||
}
|
||||
|
||||
if orderSelector != nil {
|
||||
querySelectors = append(querySelectors, orderSelector)
|
||||
}
|
||||
if pageSelector != nil {
|
||||
querySelectors = append(querySelectors, pageSelector)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
110
entgo/query_test.go
Normal file
110
entgo/query_test.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package entgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
_ "github.com/go-kratos/kratos/v2/encoding/json"
|
||||
)
|
||||
|
||||
func TestKratosJsonCodec(t *testing.T) {
|
||||
var req struct {
|
||||
Query map[string]string `json:"query,omitempty"`
|
||||
}
|
||||
req.Query = make(map[string]string)
|
||||
req.Query["key1"] = "val1"
|
||||
req.Query["key2"] = "val2"
|
||||
|
||||
codec := encoding.GetCodec("json")
|
||||
|
||||
var err error
|
||||
var data []byte
|
||||
data, err = codec.Marshal(req)
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(string(data))
|
||||
|
||||
err = codec.Unmarshal(data, &req)
|
||||
assert.Nil(t, err)
|
||||
|
||||
data1 := `{"query":{"key1":"val1","key2":"val2"}}`
|
||||
err = codec.Unmarshal([]byte(data1), &req)
|
||||
assert.Nil(t, err)
|
||||
|
||||
//data2 := `{"query":[{"key1":"val1"},{"key2":"val2"}]}`
|
||||
//err = codec.Unmarshal([]byte(data2), &req)
|
||||
//assert.Nil(t, err)
|
||||
}
|
||||
|
||||
func TestJsonCodec(t *testing.T) {
|
||||
var req struct {
|
||||
Query map[string]string `json:"query,omitempty"`
|
||||
}
|
||||
req.Query = make(map[string]string)
|
||||
req.Query["key1"] = "val1"
|
||||
req.Query["key2"] = "val2"
|
||||
|
||||
var err error
|
||||
var data []byte
|
||||
data, err = json.Marshal(req)
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(string(data))
|
||||
|
||||
err = json.Unmarshal(data, &req)
|
||||
assert.Nil(t, err)
|
||||
|
||||
data1 := `{"query":{"key1":"val1","key2":"val2"}}`
|
||||
err = json.Unmarshal([]byte(data1), &req)
|
||||
assert.Nil(t, err)
|
||||
|
||||
data2 := `[1.0,2,3]`
|
||||
var float64s []float64
|
||||
err = json.Unmarshal([]byte(data2), &float64s)
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(float64s)
|
||||
|
||||
data3 := `["1.0","2","3"]`
|
||||
var strs []string
|
||||
err = json.Unmarshal([]byte(data3), &strs)
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(strs)
|
||||
|
||||
data4 := `{"key1":"val1", "key1":"val2", "key2":"val2"}`
|
||||
var mapstrs map[string]string
|
||||
err = json.Unmarshal([]byte(data4), &mapstrs)
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(mapstrs)
|
||||
}
|
||||
|
||||
func TestParseJsonMap(t *testing.T) {
|
||||
var err error
|
||||
|
||||
req1 := make(map[string]string)
|
||||
data1 := `{"key1":"val1", "key1":"val2", "key2":"val2"}`
|
||||
err = parseJsonMap([]byte(data1), &req1)
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(req1)
|
||||
|
||||
req2 := make(map[string]string)
|
||||
data2 := `[{"key1":"val1"},{"key2":"val2"}]`
|
||||
err = parseJsonMap([]byte(data2), &req2)
|
||||
assert.Nil(t, err)
|
||||
fmt.Println(req1)
|
||||
}
|
||||
|
||||
func TestSplitQuery(t *testing.T) {
|
||||
var keys []string
|
||||
|
||||
keys = strings.Split("id", "__")
|
||||
assert.Equal(t, len(keys), 1)
|
||||
assert.Equal(t, keys[0], "id")
|
||||
|
||||
keys = strings.Split("id__not", "__")
|
||||
assert.Equal(t, len(keys), 2)
|
||||
assert.Equal(t, keys[0], "id")
|
||||
assert.Equal(t, keys[1], "not")
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
package entgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
|
||||
"github.com/tx7do/kratos-utils/stringcase"
|
||||
)
|
||||
|
||||
type WhereConditions []func(s *sql.Selector)
|
||||
type OrderConditions []func(*sql.Selector)
|
||||
|
||||
// QueryCommandToSelector 查询命令转换为选择器
|
||||
func QueryCommandToSelector(queryCmd, orderByCmd map[string]string) (WhereConditions, OrderConditions) {
|
||||
var whereCond WhereConditions
|
||||
var orderCond OrderConditions
|
||||
|
||||
if queryCmd != nil {
|
||||
queryStr, ok := queryCmd["query"]
|
||||
if ok {
|
||||
var queryMap map[string]string
|
||||
err := json.Unmarshal([]byte(queryStr), &queryMap)
|
||||
if err == nil {
|
||||
for k, v := range queryMap {
|
||||
key := stringcase.ToSnakeCase(k)
|
||||
value := v
|
||||
whereCond = append(whereCond, func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(key), value))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if orderByCmd != nil {
|
||||
orderByStr, ok := orderByCmd["orderBy"]
|
||||
if ok {
|
||||
var orderByMap map[string]string
|
||||
err := json.Unmarshal([]byte(orderByStr), &orderByMap)
|
||||
if err == nil {
|
||||
for k, v := range orderByMap {
|
||||
key := stringcase.ToSnakeCase(k)
|
||||
switch strings.ToLower(v) {
|
||||
case "desc", "descending", "descend":
|
||||
orderCond = append(orderCond, func(s *sql.Selector) {
|
||||
s.OrderBy(sql.Desc(s.C(key)))
|
||||
})
|
||||
case "asc", "ascending", "ascend":
|
||||
orderCond = append(orderCond, func(s *sql.Selector) {
|
||||
s.OrderBy(sql.Asc(s.C(key)))
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return whereCond, orderCond
|
||||
}
|
||||
5
go.mod
5
go.mod
@@ -5,6 +5,7 @@ go 1.20
|
||||
require (
|
||||
entgo.io/contrib v0.4.5
|
||||
entgo.io/ent v0.12.4
|
||||
github.com/go-kratos/kratos/v2 v2.7.1
|
||||
github.com/google/uuid v1.3.1
|
||||
github.com/sony/sonyflake v1.2.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
@@ -22,19 +23,15 @@ require (
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.18.0 // indirect
|
||||
github.com/jhump/protoreflect v1.15.2 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.10.0 // indirect
|
||||
github.com/zclconf/go-cty v1.14.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/mod v0.12.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
golang.org/x/text v0.13.0 // indirect
|
||||
golang.org/x/tools v0.13.0 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 // indirect
|
||||
google.golang.org/protobuf v1.31.0 // indirect
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
13
go.sum
13
go.sum
@@ -11,9 +11,10 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY=
|
||||
github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/go-kratos/kratos/v2 v2.7.1 h1:PNMUaWxS5ZGDp1EyID5ZosJb1OA/YiHnBxB0yUmocnc=
|
||||
github.com/go-kratos/kratos/v2 v2.7.1/go.mod h1:CPn82O93OLHjtnbuyOKhAG5TkSvw+mFnL32c4lZFDwU=
|
||||
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
|
||||
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
@@ -29,25 +30,17 @@ github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHL
|
||||
github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
|
||||
github.com/jhump/protoreflect v1.15.2 h1:7YppbATX94jEt9KLAc5hICx4h6Yt3SaavhQRsIUEHP0=
|
||||
github.com/jhump/protoreflect v1.15.2/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/sony/sonyflake v1.2.0 h1:Pfr3A+ejSg+0SPqpoAmQgEtNDAhc2G1SUYk205qVMLQ=
|
||||
github.com/sony/sonyflake v1.2.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y=
|
||||
@@ -71,7 +64,6 @@ golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529 h1:DEH99RbiLZhMxrpEJCZ0A+wdTe0EOgou/poSLx9vWf4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
|
||||
google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
@@ -79,6 +71,5 @@ google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
Reference in New Issue
Block a user