Compare commits
16 Commits
geoip/v1.1
...
v1.1.15
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ef08927a50 | ||
|
|
6d209d3612 | ||
|
|
8f957a7d29 | ||
|
|
c83b10ca22 | ||
|
|
15b6b012c2 | ||
|
|
fdcb900700 | ||
|
|
ce04468424 | ||
|
|
d1418caf84 | ||
|
|
f73f016ec5 | ||
|
|
d549d305ae | ||
|
|
23dcad60a3 | ||
|
|
fa7ae4f876 | ||
|
|
9f6a4eba80 | ||
|
|
801deb98cd | ||
|
|
c9a0909d46 | ||
|
|
9be498db69 |
@@ -3,8 +3,8 @@ module github.com/tx7do/go-utils/bank_card
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/mattn/go-sqlite3 v1.14.24
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/mattn/go-sqlite3 v1.14.25
|
||||
github.com/stretchr/testify v1.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
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/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
|
||||
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.25 h1:rszkIulEvxqZ8JfFG4yWEZh5u9qAKeSOdea67p8kk6s=
|
||||
github.com/mattn/go-sqlite3 v1.14.25/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
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/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
||||
@@ -15,16 +15,16 @@ import (
|
||||
entSql "entgo.io/ent/dialect/sql"
|
||||
)
|
||||
|
||||
type entClientInterface interface {
|
||||
type EntClientInterface interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
type EntClient[T entClientInterface] struct {
|
||||
type EntClient[T EntClientInterface] struct {
|
||||
db T
|
||||
drv *entSql.Driver
|
||||
}
|
||||
|
||||
func NewEntClient[T entClientInterface](db T, drv *entSql.Driver) *EntClient[T] {
|
||||
func NewEntClient[T EntClientInterface](db T, drv *entSql.Driver) *EntClient[T] {
|
||||
return &EntClient[T]{
|
||||
db: db,
|
||||
drv: drv,
|
||||
|
||||
38
entgo/go.mod
38
entgo/go.mod
@@ -6,17 +6,18 @@ toolchain go1.23.2
|
||||
|
||||
require (
|
||||
entgo.io/contrib v0.6.0
|
||||
entgo.io/ent v0.14.1
|
||||
github.com/XSAM/otelsql v0.35.0
|
||||
github.com/go-kratos/kratos/v2 v2.8.1
|
||||
entgo.io/ent v0.14.4
|
||||
github.com/XSAM/otelsql v0.38.0
|
||||
github.com/go-kratos/kratos/v2 v2.8.4
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/tx7do/go-utils v1.1.12
|
||||
go.opentelemetry.io/otel v1.31.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
github.com/tx7do/go-utils v1.1.14
|
||||
go.opentelemetry.io/otel v1.35.0
|
||||
google.golang.org/protobuf v1.36.6
|
||||
)
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.28.1 // indirect
|
||||
ariga.io/atlas v0.32.0 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||
@@ -24,24 +25,25 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/inflect v0.21.0 // indirect
|
||||
github.com/go-openapi/inflect v0.21.2 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.22.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.23.0 // indirect
|
||||
github.com/jhump/protoreflect v1.17.0 // 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/sony/sonyflake v1.2.0 // indirect
|
||||
github.com/zclconf/go-cty v1.15.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.31.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.31.0 // indirect
|
||||
github.com/zclconf/go-cty v1.16.2 // indirect
|
||||
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.35.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.35.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/mod v0.21.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
golang.org/x/tools v0.26.0 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/tools v0.31.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
|
||||
92
entgo/go.sum
92
entgo/go.sum
@@ -1,13 +1,13 @@
|
||||
ariga.io/atlas v0.28.1 h1:cNE0FYmoYs1u4KF+FGnp2on1srhM6FDpjaCgL7Rd8/c=
|
||||
ariga.io/atlas v0.28.1/go.mod h1:LOOp18LCL9r+VifvVlJqgYJwYl271rrXD9/wIyzJ8sw=
|
||||
ariga.io/atlas v0.32.0 h1:y+77nueMrExLiKlz1CcPKh/nU7VSlWfBbwCShsJyvCw=
|
||||
ariga.io/atlas v0.32.0/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w=
|
||||
entgo.io/contrib v0.6.0 h1:xfo4TbJE7sJZWx7BV7YrpSz7IPFvS8MzL3fnfzZjKvQ=
|
||||
entgo.io/contrib v0.6.0/go.mod h1:3qWIseJ/9Wx2Hu5zVh15FDzv7d/UvKNcYKdViywWCQg=
|
||||
entgo.io/ent v0.14.1 h1:fUERL506Pqr92EPHJqr8EYxbPioflJo6PudkrEA8a/s=
|
||||
entgo.io/ent v0.14.1/go.mod h1:MH6XLG0KXpkcDQhKiHfANZSzR55TJyPL5IGNpI8wpco=
|
||||
entgo.io/ent v0.14.4 h1:/DhDraSLXIkBhyiVoJeSshr4ZYi7femzhj6/TckzZuI=
|
||||
entgo.io/ent v0.14.4/go.mod h1:aDPE/OziPEu8+OWbzy4UlvWmD2/kbRuWfK2A40hcxJM=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/XSAM/otelsql v0.35.0 h1:nMdbU/XLmBIB6qZF61uDqy46E0LVA4ZgF/FCNw8Had4=
|
||||
github.com/XSAM/otelsql v0.35.0/go.mod h1:wO028mnLzmBpstK8XPsoeRLl/kgt417yjAwOGDIptTc=
|
||||
github.com/XSAM/otelsql v0.38.0 h1:zWU0/YM9cJhPE71zJcQ2EBHwQDp+G4AX2tPpljslaB8=
|
||||
github.com/XSAM/otelsql v0.38.0/go.mod h1:5ePOgcLEkWvZtN9H3GV4BUlPeM3p3pzLDCnRG73X8h8=
|
||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
@@ -18,25 +18,25 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/
|
||||
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
|
||||
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.8.1 h1:nK+NRp8C+wQk7tr55K9Er7nBjmBLYGbnyNz7UIy37qw=
|
||||
github.com/go-kratos/kratos/v2 v2.8.1/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
|
||||
github.com/go-kratos/kratos/v2 v2.8.4 h1:eIJLE9Qq9WSoKx+Buy2uPyrahtF/lPh+Xf4MTpxhmjs=
|
||||
github.com/go-kratos/kratos/v2 v2.8.4/go.mod h1:mq62W2101a5uYyRxe+7IdWubu7gZCGYqSNKwGFiiRcw=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/inflect v0.21.0 h1:FoBjBTQEcbg2cJUWX6uwL9OyIW8eqc9k4KhN4lfbeYk=
|
||||
github.com/go-openapi/inflect v0.21.0/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw=
|
||||
github.com/go-openapi/inflect v0.21.2 h1:0gClGlGcxifcJR56zwvhaOulnNgnhc4qTAkob5ObnSM=
|
||||
github.com/go-openapi/inflect v0.21.2/go.mod h1:INezMuUu7SJQc2AyR3WO0DqqYUJSj8Kb4hBd7WtjlAw=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M=
|
||||
github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
|
||||
github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos=
|
||||
github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
|
||||
github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94=
|
||||
github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -51,47 +51,51 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
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.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/sony/sonyflake v1.2.0 h1:Pfr3A+ejSg+0SPqpoAmQgEtNDAhc2G1SUYk205qVMLQ=
|
||||
github.com/sony/sonyflake v1.2.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=
|
||||
github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/zclconf/go-cty v1.16.2 h1:LAJSwc3v81IRBZyUVQDUdZ7hs3SYs9jv0eZJDWHD/70=
|
||||
github.com/zclconf/go-cty v1.16.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM=
|
||||
go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
|
||||
go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
|
||||
go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
|
||||
go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
|
||||
go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
|
||||
go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
|
||||
go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
|
||||
github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0=
|
||||
github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
|
||||
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
|
||||
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
|
||||
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
|
||||
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
|
||||
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
|
||||
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
|
||||
golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ=
|
||||
golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
google.golang.org/genproto v0.0.0-20231212172506-995d672761c0 h1:YJ5pD9rF8o9Qtta0Cmy9rdBwkSjrTCT6XTiUQVOtIos=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917 h1:6G8oQ016D88m1xAKljMlBOOGWDZkes4kMhgGFlf8WcQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240102182953-50ed04b92917/go.mod h1:xtjpI3tXFPP051KaWnhvxkiubL/6dJ18vLVf7q2pTOU=
|
||||
google.golang.org/grpc v1.61.1 h1:kLAiWrZs7YeDM6MumDe7m3y4aM6wacLzM1Y/wiLP9XY=
|
||||
google.golang.org/grpc v1.61.1/go.mod h1:VUbo7IFqmF1QtCAstipjG0GIoq49KvMe9+h1jFLBNJs=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
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=
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
| query | `string` | `json object` 或 `json object array` | AND过滤条件 | json字符串: `{"field1":"val1","field2":"val2"}` 或者`[{"field1":"val1"},{"field1":"val2"},{"field2":"val2"}]` | `map`和`array`都支持,当需要同字段名,不同值的情况下,请使用`array`。具体规则请见:[过滤规则](#过滤规则) |
|
||||
| or | `string` | `json object` 或 `json object array` | OR过滤条件 | 同 AND过滤条件 | |
|
||||
| orderBy | `string` | `json string array` | 排序条件 | json字符串:`["-create_time", "type"]` | json的`string array`,字段名前加`-`是为降序,不加为升序。具体规则请见:[排序规则](#排序规则) |
|
||||
| nopaging | `boolean` | | 是否不分页 | | 此字段为`true`时,`page`、`pageSize`字段的传入将无效用。 |
|
||||
| fieldMask | `string` | `json string array` | 字段掩码 | | 此字段是`SELECT`条件,为空的时候是为`*`。 |
|
||||
| noPaging | `boolean` | | 是否不分页 | | 此字段为`true`时,`page`、`pageSize`字段的传入将无效用。 |
|
||||
| fieldMask | `string` | 其语法为使用逗号分隔字段名 | 字段掩码 | 例如:id,realName,userName。 | 此字段是`SELECT`条件,为空的时候是为`*`。 |
|
||||
|
||||
## 排序规则
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
```text
|
||||
{字段名}__{查找类型} : {值}
|
||||
{字段名}.{JSON字段名}__{查找类型} : {值}
|
||||
```
|
||||
|
||||
| 查找类型 | 示例 | SQL | 备注 |
|
||||
|
||||
@@ -3,14 +3,13 @@ package entgo
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/tx7do/go-utils/stringcase"
|
||||
"strings"
|
||||
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
|
||||
"github.com/go-kratos/kratos/v2/encoding"
|
||||
|
||||
"github.com/tx7do/go-utils/stringcase"
|
||||
)
|
||||
|
||||
type FilterOp int
|
||||
@@ -63,16 +62,6 @@ var ops = [...]string{
|
||||
FilterSearch: "search",
|
||||
}
|
||||
|
||||
func hasOperations(str string) bool {
|
||||
str = strings.ToLower(str)
|
||||
for _, item := range ops {
|
||||
if str == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type DatePart int
|
||||
|
||||
const (
|
||||
@@ -109,6 +98,38 @@ var dateParts = [...]string{
|
||||
DatePartMicrosecond: "microsecond",
|
||||
}
|
||||
|
||||
const (
|
||||
QueryDelimiter = "__" // 分隔符
|
||||
JsonFieldDelimiter = "." // JSONB字段分隔符
|
||||
)
|
||||
|
||||
// splitQueryKey 分割查询键
|
||||
func splitQueryKey(key string) []string {
|
||||
return strings.Split(key, QueryDelimiter)
|
||||
}
|
||||
|
||||
// splitJsonFieldKey 分割JSON字段键
|
||||
func splitJsonFieldKey(key string) []string {
|
||||
return strings.Split(key, JsonFieldDelimiter)
|
||||
}
|
||||
|
||||
// isJsonFieldKey 是否为JSON字段键
|
||||
func isJsonFieldKey(key string) bool {
|
||||
return strings.Contains(key, JsonFieldDelimiter)
|
||||
}
|
||||
|
||||
// hasOperations 是否有操作
|
||||
func hasOperations(str string) bool {
|
||||
str = strings.ToLower(str)
|
||||
for _, item := range ops {
|
||||
if str == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// hasDatePart 是否有日期部分
|
||||
func hasDatePart(str string) bool {
|
||||
str = strings.ToLower(str)
|
||||
for _, item := range dateParts {
|
||||
@@ -119,6 +140,32 @@ func hasDatePart(str string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// BuildFilterSelector 构建过滤选择器
|
||||
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
|
||||
}
|
||||
|
||||
// QueryCommandToWhereConditions 查询命令转换为选择条件
|
||||
func QueryCommandToWhereConditions(strJson string, isOr bool) (error, func(s *sql.Selector)) {
|
||||
if len(strJson) == 0 {
|
||||
@@ -150,14 +197,13 @@ func QueryCommandToWhereConditions(strJson string, isOr bool) (error, func(s *sq
|
||||
}
|
||||
}
|
||||
|
||||
// processQueryMap 处理查询映射表
|
||||
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 := splitQueryKey(k)
|
||||
|
||||
keys := strings.Split(key, "__")
|
||||
|
||||
if cond := oneFieldFilter(s, keys, v); cond != nil {
|
||||
if cond := makeFieldFilter(s, keys, v); cond != nil {
|
||||
ps = append(ps, cond)
|
||||
}
|
||||
}
|
||||
@@ -165,32 +211,8 @@ func processQueryMap(s *sql.Selector, queryMap map[string]string) []*sql.Predica
|
||||
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 {
|
||||
// makeFieldFilter 构建一个字段过滤器
|
||||
func makeFieldFilter(s *sql.Selector, keys []string, value string) *sql.Predicate {
|
||||
if len(keys) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -207,6 +229,21 @@ func oneFieldFilter(s *sql.Selector, keys []string, value string) *sql.Predicate
|
||||
|
||||
switch len(keys) {
|
||||
case 1:
|
||||
if isJsonFieldKey(field) {
|
||||
jsonFields := splitJsonFieldKey(field)
|
||||
if len(jsonFields) != 2 {
|
||||
field = stringcase.ToSnakeCase(field)
|
||||
return filterEqual(s, p, field, value)
|
||||
}
|
||||
//value = "'" + value + "'"
|
||||
return filterJsonb(
|
||||
s, p,
|
||||
stringcase.ToSnakeCase(jsonFields[1]),
|
||||
stringcase.ToSnakeCase(jsonFields[0]),
|
||||
).
|
||||
EQ("", value)
|
||||
}
|
||||
field = stringcase.ToSnakeCase(field)
|
||||
return filterEqual(s, p, field, value)
|
||||
|
||||
case 2:
|
||||
@@ -215,6 +252,19 @@ func oneFieldFilter(s *sql.Selector, keys []string, value string) *sql.Predicate
|
||||
return nil
|
||||
}
|
||||
|
||||
if isJsonFieldKey(field) {
|
||||
jsonFields := splitJsonFieldKey(field)
|
||||
if len(jsonFields) == 2 {
|
||||
field = filterJsonbField(s,
|
||||
stringcase.ToSnakeCase(jsonFields[1]),
|
||||
stringcase.ToSnakeCase(jsonFields[0]),
|
||||
)
|
||||
//value = "'" + value + "'"
|
||||
}
|
||||
} else {
|
||||
field = stringcase.ToSnakeCase(field)
|
||||
}
|
||||
|
||||
var cond *sql.Predicate
|
||||
if hasOperations(op) {
|
||||
return processOp(s, p, op, field, value)
|
||||
@@ -241,10 +291,22 @@ func oneFieldFilter(s *sql.Selector, keys []string, value string) *sql.Predicate
|
||||
|
||||
//var cond *sql.Predicate
|
||||
if hasDatePart(op1) {
|
||||
if isJsonFieldKey(field) {
|
||||
jsonFields := splitJsonFieldKey(field)
|
||||
if len(jsonFields) == 2 {
|
||||
field = filterJsonbField(s, jsonFields[1], jsonFields[0])
|
||||
//value = "'" + value + "'"
|
||||
}
|
||||
} else {
|
||||
field = stringcase.ToSnakeCase(field)
|
||||
}
|
||||
|
||||
str := filterDatePartField(s, op1, field)
|
||||
|
||||
if hasOperations(op2) {
|
||||
return processOp(s, p, op2, str, value)
|
||||
}
|
||||
|
||||
return nil
|
||||
} else {
|
||||
str := filterJsonbField(s, op1, field)
|
||||
@@ -547,6 +609,7 @@ func filterDatePart(s *sql.Selector, p *sql.Predicate, datePart, field string) *
|
||||
return p
|
||||
}
|
||||
|
||||
// filterDatePartField 日期
|
||||
func filterDatePartField(s *sql.Selector, datePart, field string) string {
|
||||
p := sql.P()
|
||||
switch s.Builder.Dialect() {
|
||||
@@ -565,12 +628,14 @@ func filterDatePartField(s *sql.Selector, datePart, field string) string {
|
||||
}
|
||||
|
||||
// filterJsonb 提取JSONB字段
|
||||
// Postgresql: WHERE ("app_profile"."preferences" -> daily_email) = 'true'
|
||||
// Postgresql: WHERE ("app_profile"."preferences" ->> 'daily_email') = 'true'
|
||||
func filterJsonb(s *sql.Selector, p *sql.Predicate, jsonbField, field string) *sql.Predicate {
|
||||
field = stringcase.ToSnakeCase(field)
|
||||
|
||||
p.Append(func(b *sql.Builder) {
|
||||
switch s.Builder.Dialect() {
|
||||
case dialect.Postgres:
|
||||
b.Ident(s.C(field)).WriteString(" -> ").WriteString(jsonbField)
|
||||
b.Ident(s.C(field)).WriteString(" ->> ").WriteString("'" + jsonbField + "'")
|
||||
//b.Arg(strings.ToLower(value))
|
||||
break
|
||||
|
||||
@@ -584,11 +649,14 @@ func filterJsonb(s *sql.Selector, p *sql.Predicate, jsonbField, field string) *s
|
||||
return p
|
||||
}
|
||||
|
||||
// filterJsonbField JSONB字段
|
||||
func filterJsonbField(s *sql.Selector, jsonbField, field string) string {
|
||||
field = stringcase.ToSnakeCase(field)
|
||||
|
||||
p := sql.P()
|
||||
switch s.Builder.Dialect() {
|
||||
case dialect.Postgres:
|
||||
p.Ident(s.C(field)).WriteString(" -> ").WriteString(jsonbField)
|
||||
p.Ident(s.C(field)).WriteString(" ->> ").WriteString("'" + jsonbField + "'")
|
||||
//b.Arg(strings.ToLower(value))
|
||||
break
|
||||
|
||||
|
||||
@@ -681,14 +681,104 @@ func TestFilter(t *testing.T) {
|
||||
s.Where(p)
|
||||
|
||||
query, args := s.Query()
|
||||
require.Equal(t, "SELECT * FROM \"app_profile\" WHERE \"app_profile\".\"preferences\" -> daily_email = $1", query)
|
||||
require.Equal(t, "SELECT * FROM \"app_profile\" WHERE \"app_profile\".\"preferences\" ->> 'daily_email' = $1", query)
|
||||
require.NotEmpty(t, args)
|
||||
require.Equal(t, args[0], "true")
|
||||
})
|
||||
}
|
||||
|
||||
func TestFilterJsonbField(t *testing.T) {
|
||||
s := sql.Dialect(dialect.Postgres).Select("*").From(sql.Table("app_profile"))
|
||||
str := filterJsonbField(s, "daily_email", "preferences")
|
||||
fmt.Println(str)
|
||||
t.Run("filterJsonbField", func(t *testing.T) {
|
||||
s := sql.Dialect(dialect.Postgres).Select("*").From(sql.Table("app_profile"))
|
||||
str := filterJsonbField(s, "daily_email", "preferences")
|
||||
fmt.Println(str)
|
||||
require.Equal(t, str, "\"app_profile\".\"preferences\" ->> 'daily_email'")
|
||||
})
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
t.Run("MySQL_FilterEqual", func(t *testing.T) {
|
||||
s := sql.Dialect(dialect.MySQL).Select("*").From(sql.Table("menus"))
|
||||
|
||||
p := sql.P()
|
||||
|
||||
p = makeFieldFilter(s, []string{"meta.title"}, "tom")
|
||||
s.Where(p)
|
||||
|
||||
query, args := s.Query()
|
||||
require.Equal(t, "SELECT * FROM `menus` WHERE JSON_EXTRACT(`menus`.`meta`, '$.title') = ?", query)
|
||||
require.NotEmpty(t, args)
|
||||
require.Equal(t, args[0], "'tom'")
|
||||
})
|
||||
t.Run("PostgreSQL_FilterEqual", func(t *testing.T) {
|
||||
s := sql.Dialect(dialect.Postgres).Select("*").From(sql.Table("menus"))
|
||||
|
||||
p := sql.P()
|
||||
|
||||
p = makeFieldFilter(s, []string{"meta.title"}, "tom")
|
||||
s.Where(p)
|
||||
|
||||
query, args := s.Query()
|
||||
require.Equal(t, "SELECT * FROM \"menus\" WHERE \"menus\".\"meta\" ->> 'title' = $1", query)
|
||||
require.NotEmpty(t, args)
|
||||
require.Equal(t, args[0], "'tom'")
|
||||
})
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
t.Run("MySQL_FilterNot", func(t *testing.T) {
|
||||
s := sql.Dialect(dialect.MySQL).Select("*").From(sql.Table("users"))
|
||||
|
||||
p := sql.P()
|
||||
|
||||
p = makeFieldFilter(s, []string{"meta.title", "not"}, "tom")
|
||||
s.Where(p)
|
||||
|
||||
query, args := s.Query()
|
||||
require.Equal(t, "SELECT * FROM `users` WHERE NOT JSON_EXTRACT(`users`.`meta`, '$.title') = ?", query)
|
||||
require.NotEmpty(t, args)
|
||||
require.Equal(t, args[0], "'tom'")
|
||||
})
|
||||
t.Run("PostgreSQL_FilterNot", func(t *testing.T) {
|
||||
s := sql.Dialect(dialect.Postgres).Select("*").From(sql.Table("users"))
|
||||
|
||||
p := sql.P()
|
||||
|
||||
p = makeFieldFilter(s, []string{"meta.title", "not"}, "tom")
|
||||
s.Where(p)
|
||||
|
||||
query, args := s.Query()
|
||||
require.Equal(t, "SELECT * FROM \"users\" WHERE NOT \"users\".\"meta\" ->> 'title' = $1", query)
|
||||
require.NotEmpty(t, args)
|
||||
require.Equal(t, args[0], "'tom'")
|
||||
})
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
t.Run("MySQL_FilterNot_Date", func(t *testing.T) {
|
||||
s := sql.Dialect(dialect.MySQL).Select("*").From(sql.Table("users"))
|
||||
|
||||
p := sql.P()
|
||||
|
||||
p = makeFieldFilter(s, []string{"meta.title", "date", "not"}, "2023-01-01")
|
||||
s.Where(p)
|
||||
|
||||
query, args := s.Query()
|
||||
require.Equal(t, "SELECT * FROM `users` WHERE NOT DATE(JSON_EXTRACT(`users`.`meta`, '$.title')) = ?", query)
|
||||
require.NotEmpty(t, args)
|
||||
require.Equal(t, args[0], "'2023-01-01'")
|
||||
})
|
||||
t.Run("PostgreSQL_FilterNot_Date", func(t *testing.T) {
|
||||
s := sql.Dialect(dialect.Postgres).Select("*").From(sql.Table("users"))
|
||||
|
||||
p := sql.P()
|
||||
|
||||
p = makeFieldFilter(s, []string{"meta.title", "date", "not"}, "2023-01-01")
|
||||
s.Where(p)
|
||||
|
||||
query, args := s.Query()
|
||||
require.Equal(t, "SELECT * FROM \"users\" WHERE NOT EXTRACT('DATE' FROM \"users\".\"meta\" ->> 'title') = $1", query)
|
||||
require.NotEmpty(t, args)
|
||||
require.Equal(t, args[0], "'2023-01-01'")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package entgo
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"entgo.io/ent/dialect"
|
||||
@@ -85,11 +84,11 @@ func TestJsonCodec(t *testing.T) {
|
||||
func TestSplitQuery(t *testing.T) {
|
||||
var keys []string
|
||||
|
||||
keys = strings.Split("id", "__")
|
||||
keys = splitQueryKey("id")
|
||||
assert.Equal(t, len(keys), 1)
|
||||
assert.Equal(t, keys[0], "id")
|
||||
|
||||
keys = strings.Split("id__not", "__")
|
||||
keys = splitQueryKey("id__not")
|
||||
assert.Equal(t, len(keys), 2)
|
||||
assert.Equal(t, keys[0], "id")
|
||||
assert.Equal(t, keys[1], "not")
|
||||
@@ -111,19 +110,22 @@ func TestBuildQuerySelectorDefault(t *testing.T) {
|
||||
{"PostgreSQL_NoPagination", dialect.Postgres, "", "", true, "SELECT * FROM \"users\" ORDER BY \"users\".\"created_at\" DESC"},
|
||||
|
||||
{"MySQL_JsonbQuery", dialect.MySQL, "{\"preferences__daily_email\" : \"true\"}", "", true, "SELECT * FROM `users` WHERE JSON_EXTRACT(`users`.`preferences`, '$.daily_email') = ? ORDER BY `users`.`created_at` DESC"},
|
||||
{"PostgreSQL_JsonbQuery", dialect.Postgres, "{\"preferences__daily_email\" : \"true\"}", "", true, "SELECT * FROM \"users\" WHERE \"users\".\"preferences\" -> daily_email = $1 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
{"PostgreSQL_JsonbQuery", dialect.Postgres, "{\"preferences__daily_email\" : \"true\"}", "", true, "SELECT * FROM \"users\" WHERE \"users\".\"preferences\" ->> 'daily_email' = $1 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
|
||||
{"MySQL_DatePartQuery", dialect.MySQL, "{\"created_at__date\" : \"2023-01-01\"}", "", true, "SELECT * FROM `users` WHERE DATE(`users`.`created_at`) = ? ORDER BY `users`.`created_at` DESC"},
|
||||
{"PostgreSQL_DatePartQuery", dialect.Postgres, "{\"created_at__date\" : \"2023-01-01\"}", "", true, "SELECT * FROM \"users\" WHERE EXTRACT('DATE' FROM \"users\".\"created_at\") = $1 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
|
||||
{"MySQL_JsonbCombineQuery", dialect.MySQL, "{\"preferences__pub_date__not\" : \"true\"}", "", true, "SELECT * FROM `users` WHERE NOT JSON_EXTRACT(`users`.`preferences`, '$.pub_date') = ? ORDER BY `users`.`created_at` DESC"},
|
||||
{"PostgreSQL_JsonbCombineQuery", dialect.Postgres, "{\"preferences__pub_date__not\" : \"true\"}", "", true, "SELECT * FROM \"users\" WHERE NOT \"users\".\"preferences\" -> pub_date = $1 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
{"PostgreSQL_JsonbCombineQuery", dialect.Postgres, "{\"preferences__pub_date__not\" : \"true\"}", "", true, "SELECT * FROM \"users\" WHERE NOT \"users\".\"preferences\" ->> 'pub_date' = $1 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
|
||||
{"MySQL_DatePartCombineQuery", dialect.MySQL, "{\"pub_date__date__not\" : \"true\"}", "", true, "SELECT * FROM `users` WHERE NOT DATE(`users`.`pub_date`) = ? ORDER BY `users`.`created_at` DESC"},
|
||||
{"PostgreSQL_DatePartCombineQuery", dialect.Postgres, "{\"pub_date__date__not\" : \"true\"}", "", true, "SELECT * FROM \"users\" WHERE NOT EXTRACT('DATE' FROM \"users\".\"pub_date\") = $1 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
|
||||
{"MySQL_DatePartRangeQuery", dialect.MySQL, "{\"pub_date__date__range\" : \"[\\\"2023-10-25\\\", \\\"2024-10-25\\\"]\"}", "", true, "SELECT * FROM `users` WHERE DATE(`users`.`pub_date`) >= ? AND DATE(`users`.`pub_date`) <= ? ORDER BY `users`.`created_at` DESC"},
|
||||
{"PostgreSQL_DatePartRangeQuery", dialect.Postgres, "{\"pub_date__date__range\" : \"[\\\"2023-10-25\\\", \\\"2024-10-25\\\"]\"}", "", true, "SELECT * FROM \"users\" WHERE EXTRACT('DATE' FROM \"users\".\"pub_date\") >= $1 AND EXTRACT('DATE' FROM \"users\".\"pub_date\") <= $2 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
|
||||
{"MySQL_JsonQuery", dialect.MySQL, "{\"meta.title\" : \"preferences__daily_email\"}", "", true, "SELECT * FROM `users` WHERE JSON_EXTRACT(`users`.`meta`, '$.title') = ? ORDER BY `users`.`created_at` DESC"},
|
||||
{"PostgreSQL_JsonQuery", dialect.Postgres, "{\"meta.title\" : \"preferences__daily_email\"}", "", true, "SELECT * FROM \"users\" WHERE \"users\".\"meta\" ->> 'title' = $1 ORDER BY \"users\".\"created_at\" DESC"},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
package entgo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
|
||||
"github.com/tx7do/go-utils/fieldmaskutil"
|
||||
"github.com/tx7do/go-utils/stringcase"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/reflect/protoreflect"
|
||||
)
|
||||
|
||||
func BuildSetNullUpdate(u *sql.UpdateBuilder, fields []string) {
|
||||
@@ -14,12 +22,79 @@ func BuildSetNullUpdate(u *sql.UpdateBuilder, fields []string) {
|
||||
}
|
||||
}
|
||||
|
||||
func BuildSetNullUpdater(fields []string) (error, func(u *sql.UpdateBuilder)) {
|
||||
if len(fields) > 0 {
|
||||
return nil, func(u *sql.UpdateBuilder) {
|
||||
BuildSetNullUpdate(u, fields)
|
||||
}
|
||||
} else {
|
||||
return nil, nil
|
||||
// BuildSetNullUpdater 构建一个UpdateBuilder,用于清空字段的值
|
||||
func BuildSetNullUpdater(fields []string) func(u *sql.UpdateBuilder) {
|
||||
if len(fields) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return func(u *sql.UpdateBuilder) {
|
||||
BuildSetNullUpdate(u, fields)
|
||||
}
|
||||
}
|
||||
|
||||
// ExtractJsonFieldKeyValues 提取json字段的键值对
|
||||
func ExtractJsonFieldKeyValues(msg proto.Message, paths []string, needToSnakeCase bool) []string {
|
||||
var keyValues []string
|
||||
rft := msg.ProtoReflect()
|
||||
for _, path := range paths {
|
||||
fd := rft.Descriptor().Fields().ByName(protoreflect.Name(path))
|
||||
if fd == nil {
|
||||
continue
|
||||
}
|
||||
if !rft.Has(fd) {
|
||||
continue
|
||||
}
|
||||
|
||||
var k string
|
||||
if needToSnakeCase {
|
||||
k = stringcase.ToSnakeCase(path)
|
||||
} else {
|
||||
k = path
|
||||
}
|
||||
|
||||
keyValues = append(keyValues, fmt.Sprintf("'%s'", k))
|
||||
|
||||
v := rft.Get(fd)
|
||||
switch v.Interface().(type) {
|
||||
case int32, int64, uint32, uint64, float32, float64, bool:
|
||||
keyValues = append(keyValues, fmt.Sprintf("%d", v.Interface()))
|
||||
case string:
|
||||
keyValues = append(keyValues, fmt.Sprintf("'%s'", v.Interface()))
|
||||
}
|
||||
}
|
||||
|
||||
return keyValues
|
||||
}
|
||||
|
||||
// SetJsonNullFieldUpdateBuilder 设置json字段的空值
|
||||
func SetJsonNullFieldUpdateBuilder(fieldName string, msg proto.Message, paths []string) func(u *sql.UpdateBuilder) {
|
||||
nilPaths := fieldmaskutil.NilValuePaths(msg, paths)
|
||||
if len(nilPaths) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return func(u *sql.UpdateBuilder) {
|
||||
u.Set(fieldName,
|
||||
sql.Expr(
|
||||
fmt.Sprintf("\"%s\" - '{%s}'::text[]", fieldName, strings.Join(nilPaths, ",")),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// SetJsonFieldValueUpdateBuilder 设置json字段的值
|
||||
func SetJsonFieldValueUpdateBuilder(fieldName string, msg proto.Message, paths []string, needToSnakeCase bool) func(u *sql.UpdateBuilder) {
|
||||
keyValues := ExtractJsonFieldKeyValues(msg, paths, needToSnakeCase)
|
||||
if len(keyValues) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return func(u *sql.UpdateBuilder) {
|
||||
u.Set(fieldName,
|
||||
sql.Expr(
|
||||
fmt.Sprintf("\"%s\" || jsonb_build_object(%s)", fieldName, strings.Join(keyValues, ",")),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
12
geoip/go.mod
12
geoip/go.mod
@@ -1,14 +1,14 @@
|
||||
module github.com/tx7do/go-utils/geoip
|
||||
|
||||
go 1.21
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.2
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
github.com/go-kratos/kratos/v2 v2.8.1
|
||||
github.com/go-kratos/kratos/v2 v2.8.4
|
||||
github.com/oschwald/geoip2-golang v1.11.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/text v0.19.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/text v0.23.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -16,7 +16,7 @@ require (
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.13.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/sys v0.31.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
|
||||
20
geoip/go.sum
20
geoip/go.sum
@@ -1,8 +1,8 @@
|
||||
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.8.1 h1:nK+NRp8C+wQk7tr55K9Er7nBjmBLYGbnyNz7UIy37qw=
|
||||
github.com/go-kratos/kratos/v2 v2.8.1/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
|
||||
github.com/go-kratos/kratos/v2 v2.8.4 h1:eIJLE9Qq9WSoKx+Buy2uPyrahtF/lPh+Xf4MTpxhmjs=
|
||||
github.com/go-kratos/kratos/v2 v2.8.4/go.mod h1:mq62W2101a5uYyRxe+7IdWubu7gZCGYqSNKwGFiiRcw=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -15,14 +15,14 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
|
||||
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
|
||||
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo=
|
||||
golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
|
||||
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
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=
|
||||
|
||||
14
go.mod
14
go.mod
@@ -1,18 +1,18 @@
|
||||
module github.com/tx7do/go-utils
|
||||
|
||||
go 1.22.0
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.2
|
||||
toolchain go1.24.1
|
||||
|
||||
require (
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gosimple/slug v1.14.0
|
||||
github.com/gosimple/slug v1.15.0
|
||||
github.com/sony/sonyflake v1.2.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
golang.org/x/crypto v0.28.0
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
|
||||
google.golang.org/protobuf v1.35.1
|
||||
github.com/stretchr/testify v1.10.0
|
||||
golang.org/x/crypto v0.36.0
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394
|
||||
google.golang.org/protobuf v1.36.6
|
||||
)
|
||||
|
||||
require (
|
||||
|
||||
20
go.sum
20
go.sum
@@ -7,8 +7,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gosimple/slug v1.14.0 h1:RtTL/71mJNDfpUbCOmnf/XFkzKRtD6wL6Uy+3akm4Es=
|
||||
github.com/gosimple/slug v1.14.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=
|
||||
github.com/gosimple/slug v1.15.0 h1:wRZHsRrRcs6b0XnxMUBM6WK1U1Vg5B0R7VkIf1Xzobo=
|
||||
github.com/gosimple/slug v1.15.0/go.mod h1:UiRaFH+GEilHstLUmcBgWcI42viBN7mAb818JrYOeFQ=
|
||||
github.com/gosimple/unidecode v1.0.1 h1:hZzFTMMqSswvf0LBJZCZgThIZrpDHFXux9KeGmn6T/o=
|
||||
github.com/gosimple/unidecode v1.0.1/go.mod h1:CP0Cr1Y1kogOtx0bJblKzsVWrqYaqfNOnHzpgWw4Awc=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
@@ -26,14 +26,14 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/sony/sonyflake v1.2.0 h1:Pfr3A+ejSg+0SPqpoAmQgEtNDAhc2G1SUYk205qVMLQ=
|
||||
github.com/sony/sonyflake v1.2.0/go.mod h1:LORtCywH/cq10ZbyfhKrHYgAUGH7mOBa76enV9txy/Y=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
|
||||
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
|
||||
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
|
||||
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
|
||||
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
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=
|
||||
|
||||
10
tag.bat
10
tag.bat
@@ -1,9 +1,9 @@
|
||||
git tag v1.1.12
|
||||
git tag v1.1.15
|
||||
|
||||
git tag bank_card/v1.1.2
|
||||
git tag geoip/v1.1.2
|
||||
git tag bank_card/v1.1.4
|
||||
git tag geoip/v1.1.4
|
||||
|
||||
git tag entgo/v1.1.15
|
||||
git tag gorm/v1.1.2
|
||||
git tag entgo/v1.1.25
|
||||
git tag gorm/v1.1.4
|
||||
|
||||
git push origin --tags
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import "time"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import "time"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/tx7do/go-utils/trans"
|
||||
@@ -132,3 +133,50 @@ func TimeToTimestamppb(tm *time.Time) *timestamppb.Timestamp {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func FloatToDurationpb(duration *float64, timePrecision time.Duration) *durationpb.Duration {
|
||||
if duration == nil {
|
||||
return nil
|
||||
}
|
||||
return durationpb.New(time.Duration(*duration) * timePrecision)
|
||||
}
|
||||
|
||||
func DurationpbToFloat(duration *durationpb.Duration, timePrecision time.Duration) *float64 {
|
||||
if duration == nil {
|
||||
return nil
|
||||
}
|
||||
seconds := duration.AsDuration().Seconds()
|
||||
secondsWithPrecision := seconds / timePrecision.Seconds()
|
||||
return &secondsWithPrecision
|
||||
}
|
||||
|
||||
func NumberToDurationpb[T int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64](duration *T, timePrecision time.Duration) *durationpb.Duration {
|
||||
if duration == nil {
|
||||
return nil
|
||||
}
|
||||
return durationpb.New(time.Duration(*duration) * timePrecision)
|
||||
}
|
||||
|
||||
func DurationpbToNumber[T int | int8 | int16 | int32 | int64 | uint | uint8 | uint16 | uint32 | uint64 | float32 | float64](duration *durationpb.Duration, timePrecision time.Duration) *T {
|
||||
if duration == nil {
|
||||
return nil
|
||||
}
|
||||
seconds := duration.AsDuration().Seconds()
|
||||
secondsWithPrecision := T(seconds / timePrecision.Seconds())
|
||||
return &secondsWithPrecision
|
||||
}
|
||||
|
||||
func DurationToDurationpb(duration *time.Duration) *durationpb.Duration {
|
||||
if duration == nil {
|
||||
return nil
|
||||
}
|
||||
return durationpb.New(*duration)
|
||||
}
|
||||
|
||||
func DurationpbToDuration(duration *durationpb.Duration) *time.Duration {
|
||||
if duration == nil {
|
||||
return nil
|
||||
}
|
||||
d := duration.AsDuration()
|
||||
return &d
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package util
|
||||
package timeutil
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/tx7do/go-utils/trans"
|
||||
"google.golang.org/protobuf/types/known/durationpb"
|
||||
)
|
||||
|
||||
func TestUnixMilliToStringPtr(t *testing.T) {
|
||||
@@ -19,17 +20,39 @@ func TestUnixMilliToStringPtr(t *testing.T) {
|
||||
fmt.Println(*UnixMilliToStringPtr(trans.Int64(1677647946234)))
|
||||
fmt.Println(*UnixMilliToStringPtr(trans.Int64(1678245350773)))
|
||||
|
||||
fmt.Println("START: ", *StringToUnixMilliInt64Ptr(trans.String("2023-03-09 00:00:00")))
|
||||
fmt.Println("END: ", *StringToUnixMilliInt64Ptr(trans.String("2023-03-09 23:59:59")))
|
||||
fmt.Println("START: ", *StringToUnixMilliInt64Ptr(trans.Ptr("2023-03-09 00:00:00")))
|
||||
fmt.Println("END: ", *StringToUnixMilliInt64Ptr(trans.Ptr("2023-03-09 23:59:59")))
|
||||
|
||||
fmt.Println(StringTimeToTime(trans.String("2023-03-01 00:00:00")))
|
||||
fmt.Println(*StringDateToTime(trans.String("2023-03-01")))
|
||||
fmt.Println(StringTimeToTime(trans.Ptr("2023-03-01 00:00:00")))
|
||||
fmt.Println(*StringDateToTime(trans.Ptr("2023-03-01")))
|
||||
|
||||
fmt.Println(StringTimeToTime(trans.String("2023-03-08 00:00:00")).UnixMilli())
|
||||
fmt.Println(StringDateToTime(trans.String("2023-03-07")).UnixMilli())
|
||||
fmt.Println(StringTimeToTime(trans.Ptr("2023-03-08 00:00:00")).UnixMilli())
|
||||
fmt.Println(StringDateToTime(trans.Ptr("2023-03-07")).UnixMilli())
|
||||
}
|
||||
|
||||
func TestTimeToDateString(t *testing.T) {
|
||||
fmt.Println(*TimeToTimeString(trans.Time(time.Now())))
|
||||
fmt.Println(*TimeToDateString(trans.Time(time.Now())))
|
||||
}
|
||||
|
||||
func TestDurationpb(t *testing.T) {
|
||||
fmt.Println(FloatToDurationpb(trans.Ptr(100.0), time.Nanosecond).String())
|
||||
fmt.Println(*DurationpbToFloat(durationpb.New(100*time.Nanosecond), time.Nanosecond))
|
||||
|
||||
fmt.Println(FloatToDurationpb(trans.Ptr(100.0), time.Second).String())
|
||||
fmt.Println(*DurationpbToFloat(durationpb.New(100*time.Second), time.Second))
|
||||
|
||||
fmt.Println(FloatToDurationpb(trans.Ptr(100.0), time.Minute).String())
|
||||
fmt.Println(*DurationpbToFloat(durationpb.New(100*time.Minute), time.Minute))
|
||||
|
||||
//
|
||||
|
||||
fmt.Println(NumberToDurationpb(trans.Ptr(100.0), time.Nanosecond).String())
|
||||
fmt.Println(*DurationpbToNumber[float64](durationpb.New(100*time.Nanosecond), time.Nanosecond))
|
||||
|
||||
fmt.Println(NumberToDurationpb(trans.Ptr(100.0), time.Second).String())
|
||||
fmt.Println(*DurationpbToNumber[float64](durationpb.New(100*time.Second), time.Second))
|
||||
|
||||
fmt.Println(NumberToDurationpb(trans.Ptr(100.0), time.Minute).String())
|
||||
fmt.Println(*DurationpbToNumber[float64](durationpb.New(100*time.Minute), time.Minute))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user