diff --git a/entgo/filter.go b/entgo/filter.go new file mode 100644 index 0000000..b38a7e9 --- /dev/null +++ b/entgo/filter.go @@ -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 +} diff --git a/entgo/order.go b/entgo/order.go new file mode 100644 index 0000000..c5c30e6 --- /dev/null +++ b/entgo/order.go @@ -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) + } +} diff --git a/entgo/pagination.go b/entgo/pagination.go new file mode 100644 index 0000000..25383ee --- /dev/null +++ b/entgo/pagination.go @@ -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)) + } +} diff --git a/entgo/query.go b/entgo/query.go new file mode 100644 index 0000000..b9c6fe0 --- /dev/null +++ b/entgo/query.go @@ -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 +} diff --git a/entgo/query_test.go b/entgo/query_test.go new file mode 100644 index 0000000..bc9cb35 --- /dev/null +++ b/entgo/query_test.go @@ -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") +} diff --git a/entgo/util.go b/entgo/util.go deleted file mode 100644 index 6e78480..0000000 --- a/entgo/util.go +++ /dev/null @@ -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 -} diff --git a/go.mod b/go.mod index 65a1ee1..4eeeadf 100644 --- a/go.mod +++ b/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 ) diff --git a/go.sum b/go.sum index d7f7a66..9bba71b 100644 --- a/go.sum +++ b/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=