Compare commits

...

71 Commits

Author SHA1 Message Date
dtapps 5f70e83104 - update mod
3 weeks ago
dtapps 8dbbff4a27 - update vendor
1 month ago
dtapps 0ed080ee44 - redis增加url连接
1 month ago
dtapps b99cbca10a - update
2 months ago
dtapps 8238616ab5 - update
2 months ago
dtapps b4cf941dd9 - update vendor
2 months ago
dtapps 1f3831a39c - add vendor
2 months ago
dtapps bb1ce11d98 - update gorm sql
3 months ago
dtapps 0799a47c4d - update mongo
3 months ago
dtapps 986c3d81aa update
5 months ago
李光春 ce71070f19 - update
1 year ago
李光春 2480a2f0fb - delete beego
2 years ago
李光春 7bd2d5fea4 - update
2 years ago
李光春 002b617947 - update redis
2 years ago
李光春 093c682a11 - update type
2 years ago
李光春 a92d63c3fa - update mongo
2 years ago
李光春 fbb0a0ef38 - add type
2 years ago
李光春 cda216ae0e - update mongo
2 years ago
李光春 5cf7e80176 - update mongo
2 years ago
李光春 0b0d3b35ad - update
2 years ago
李光春 3b662a2351 - update
2 years ago
李光春 a383dc98c2 - update BsonTime
2 years ago
李光春 dbcb880465 - update mongo
2 years ago
李光春 284e13594a - update mongo
2 years ago
李光春 f1530064e9 - update mongo
2 years ago
李光春 54ca833aa5 - update mongo
2 years ago
李光春 a184e64f15 - update fun
2 years ago
李光春 37f574b436 - add fun
2 years ago
李光春 c65de2d85b - update mongo
2 years ago
李光春 aa56a7a4eb - update mongo
2 years ago
李光春 f420131a37 - update mongo
2 years ago
李光春 7c835284e1 - update vendor
2 years ago
李光春 83ef4742cb - update gorm
2 years ago
李光春 64404d1295 - update config
2 years ago
李光春 3aa6b9c942 - update json
2 years ago
李光春 bbf1a72f89 - update
2 years ago
李光春 c6f0cf2554 - add beego
2 years ago
李光春 184ce91506 - add redis ReadTimeout
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 36cb324abe - update redis keys
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 38bdd453c7 - update redis
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 e8c2b726bf - update redis lock
continuous-integration/drone/tag Build is failing Details
continuous-integration/drone/push Build was killed Details
2 years ago
李光春 2f71ce5847 - update redis lock
continuous-integration/drone/tag Build is failing Details
continuous-integration/drone/push Build was killed Details
2 years ago
李光春 981bb39993 - add error
continuous-integration/drone/push Build is failing Details
2 years ago
李光春 30eff780b1 - add error
2 years ago
李光春 841f55a29a - update redis lock
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 389bd8e65c - update redis
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 8e27344f05 - update redis
continuous-integration/drone/tag Build is failing Details
continuous-integration/drone/push Build was killed Details
2 years ago
李光春 75a6f160b9 - update redis
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build was killed Details
2 years ago
李光春 6a2d8ffdae - update redis cache
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build was killed Details
2 years ago
李光春 26a28acf7b - update
2 years ago
李光春 3035cd19ef - add redis cache
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 981768b7b0 - update redis
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 c58e6fe761 - update redis
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 388310c804 - update redis
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 6559dff6e2 - update
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 bd8d1252d1 - update get db
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 903ce4cbb2 - update zorm
continuous-integration/drone/push Build was killed Details
continuous-integration/drone/tag Build was killed Details
2 years ago
李光春 3186fe56c6 - update bun
continuous-integration/drone/tag Build is passing Details
continuous-integration/drone/push Build is passing Details
2 years ago
李光春 1a428bfa15 - update gorm
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 82edf1cf60 - update
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 59f6113ff8 - update gorm
continuous-integration/drone/push Build is failing Details
2 years ago
李光春 3c88276d5b - update
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 fb721835aa - update
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 fc26802071 - update
continuous-integration/drone/push Build is failing Details
2 years ago
李光春 d6fc929d57 - update redis
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 0de8f4e2ca - update redis
continuous-integration/drone/push Build is passing Details
2 years ago
李光春 e5a9651aec - update redis
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 04b4ddfcbe - update
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details
2 years ago
李光春 c2996cb66b - update vendor
continuous-integration/drone/push Build is passing Details
2 years ago
李光春 1fae943055 - update vendor
continuous-integration/drone/push Build is failing Details
continuous-integration/drone/tag Build is failing Details
2 years ago
李光春 787f4d8280 - update
continuous-integration/drone/push Build is failing Details
2 years ago

7
.gitignore vendored

@ -4,5 +4,8 @@
.idea
.vscode
*.log
gomod.sh
/vendor/
*_test.go
*.txt
*.text
go_mod.sh
/vendor/

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 李光春
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,25 +1,17 @@
<h1>
<a href="https://www.dtapp.net/">Golang Dorm</a>
<a href="https://www.dtapp.net/">Golang</a>
</h1>
📦 Golang Dorm
📦 Golang 数据库
[comment]: <> (go)
[![godoc](https://pkg.go.dev/badge/go.dtapp.net/dorm?status.svg)](https://pkg.go.dev/go.dtapp.net/dorm)
[![goproxy.cn](https://goproxy.cn/stats/go.dtapp.net/dorm/badges/download-count.svg)](https://goproxy.cn/stats/go.dtapp.net/dorm)
[![goreportcard.com](https://goreportcard.com/badge/go.dtapp.net/dorm)](https://goreportcard.com/report/go.dtapp.net/dorm)
[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/go.dtapp.net/dorm)
[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/go.dtapp.net%2Fdorm)
#### 安装使用
#### 安装
```shell
go get -v -u go.dtapp.net/dorm
go get -v -u go.dtapp.net/dorm@v1.0.59
```
#### 导入
```go
import (
"go.dtapp.net/dorm"
)
```

@ -1,37 +1,57 @@
module go.dtapp.net/dorm
go 1.18
go 1.22.1
require (
github.com/sirupsen/logrus v1.8.1
go.mongodb.org/mongo-driver v1.9.1
gorm.io/driver/mysql v1.3.4
gorm.io/driver/postgres v1.3.7
gorm.io/gorm v1.23.6
github.com/redis/go-redis/v9 v9.5.1
github.com/sirupsen/logrus v1.9.3
go.dtapp.net/gojson v1.0.4
go.dtapp.net/gotime v1.0.8
go.mongodb.org/mongo-driver v1.15.0
gorm.io/driver/mysql v1.5.6
gorm.io/driver/postgres v1.5.7
gorm.io/gen v0.3.26
gorm.io/gorm v1.25.10
)
require (
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/basgys/goxml2json v1.1.0 // indirect
github.com/bytedance/sonic v1.11.6 // indirect
github.com/bytedance/sonic/loader v0.1.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/jackc/chunkreader/v2 v2.0.1 // indirect
github.com/jackc/pgconn v1.12.1 // indirect
github.com/jackc/pgio v1.0.0 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgproto3/v2 v2.3.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect
github.com/jackc/pgtype v1.11.0 // indirect
github.com/jackc/pgx/v4 v4.16.1 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgx/v5 v5.5.5 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/compress v1.15.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.8 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c // indirect
golang.org/x/text v0.3.7 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 // indirect
golang.org/x/arch v0.7.0 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.20.0 // indirect
gorm.io/datatypes v1.2.0 // indirect
gorm.io/hints v1.1.2 // indirect
gorm.io/plugin/dbresolver v1.5.1 // indirect
)

337
go.sum

@ -1,236 +1,179 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw=
github.com/basgys/goxml2json v1.1.0/go.mod h1:wH7a5Np/Q4QoECFIU8zTQlZwZkrilY0itPfecMw41Dw=
github.com/bitly/go-simplejson v0.5.1 h1:xgwPbetQScXt1gh9BmoJ6j9JMr3TElvuIyjR8pgdoow=
github.com/bitly/go-simplejson v0.5.1/go.mod h1:YOPVLzCfwK14b4Sff3oP1AmGhI9T9Vsg84etUnlyp+Q=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0=
github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4=
github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM=
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0=
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA=
github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE=
github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s=
github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o=
github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY=
github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI=
github.com/jackc/pgconn v1.12.1 h1:rsDFzIpRk7xT4B8FufgpCCeyjdNpKyghZeSefViE5W8=
github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono=
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE=
github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c=
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc=
github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A=
github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA=
github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg=
github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM=
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y=
github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg=
github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg=
github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc=
github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw=
github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM=
github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs=
github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y=
github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM=
github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc=
github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs=
github.com/jackc/pgx/v4 v4.16.1 h1:JzTglcal01DrghUqt+PmzWsZx/Yh7SC/CTQmSBMTd0Y=
github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.6 h1:6D9PcO8QWu0JyaQ2zUMmu16T1T+zjjEpP91guRsvDfY=
github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU=
github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE=
github.com/microsoft/go-mssqldb v0.17.0/go.mod h1:OkoNGhGEs8EZqchVTtochlXruEhEOaO4S0d2sB5aeGQ=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
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.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/redis/go-redis/v9 v9.5.1 h1:H1X4D3yHPaYrkL5X06Wh6xNVM/pX0Ft4RV0vMGvLBh8=
github.com/redis/go-redis/v9 v9.5.1/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/scram v1.1.1 h1:VOMT+81stJgXW3CpHyqHN3AXDYIMsx56mEFrB37Mb/E=
github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
github.com/xdg-go/stringprep v1.0.3 h1:kdwGpVNwPFtjs98xCGkHjQtGKh86rDcRZN17QEMCOIs=
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c=
go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76 h1:tBiBTKHnIjovYoLX/TPkcf+OjqqKGQrPtGT3Foz+Pgo=
github.com/youmark/pkcs8 v0.0.0-20240424034433-3c2c7870ae76/go.mod h1:SQliXeA7Dhkt//vS29v3zpbEwoa+zb2Cn5xj5uO4K5U=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.dtapp.net/gojson v1.0.4 h1:9en9iyOOLWoEIo2eKhqt3/Djh/3HhwsTpXxgI9efPRo=
go.dtapp.net/gojson v1.0.4/go.mod h1:G9CMVzNSRkbNzIic/vJqHCOyKtw6BW2YM8Vyn64zfM0=
go.dtapp.net/gotime v1.0.8 h1:ngKBp7j3Ime1t2jU94gUeshPX1StV5E2x4STlzDMmLU=
go.dtapp.net/gotime v1.0.8/go.mod h1:BQT911XSfaJDBYPiEKGFwMjvgnZtx1F3nWu4GTg5ISY=
go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc=
go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c h1:aFV+BgZ4svzjfabn8ERpuB4JI4N6/rdy1iusx77G3oU=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY=
golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/mysql v1.3.4 h1:/KoBMgsUHC3bExsekDcmNYaBnfH2WNeFuXqqrqMc98Q=
gorm.io/driver/mysql v1.3.4/go.mod h1:s4Tq0KmD0yhPGHbZEwg1VPlH0vT/GBHJZorPzhcxBUE=
gorm.io/driver/postgres v1.3.7 h1:FKF6sIMDHDEvvMF/XJvbnCl0nu6KSKUaPXevJ4r+VYQ=
gorm.io/driver/postgres v1.3.7/go.mod h1:f02ympjIcgtHEGFMZvdgTxODZ9snAHDb4hXfigBVuNI=
gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.6 h1:KFLdNgri4ExFFGTRGGFWON2P1ZN28+9SJRN8voOoYe0=
gorm.io/gorm v1.23.6/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/datatypes v1.2.0 h1:5YT+eokWdIxhJgWHdrb2zYUimyk0+TaFth+7a0ybzco=
gorm.io/datatypes v1.2.0/go.mod h1:o1dh0ZvjIjhH/bngTpypG6lVRJ5chTBxE09FH/71k04=
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
gorm.io/driver/sqlite v1.5.0 h1:zKYbzRCpBrT1bNijRnxLDJWPjVfImGEn0lSnUY5gZ+c=
gorm.io/driver/sqlite v1.5.0/go.mod h1:kDMDfntV9u/vuMmz8APHtHF0b4nyBB7sfCieC6G8k8I=
gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0=
gorm.io/driver/sqlserver v1.4.1/go.mod h1:DJ4P+MeZbc5rvY58PnmN1Lnyvb5gw5NPzGshHDnJLig=
gorm.io/gen v0.3.26 h1:sFf1j7vNStimPRRAtH4zz5NiHM+1dr6eA9aaRdplyhY=
gorm.io/gen v0.3.26/go.mod h1:a5lq5y3w4g5LMxBcw0wnO6tYUCdNutWODq5LrIt75LE=
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.0/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s=
gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/hints v1.1.2 h1:b5j0kwk5p4+3BtDtYqqfY+ATSxjj+6ptPgVveuynn9o=
gorm.io/hints v1.1.2/go.mod h1:/ARdpUHAtyEMCh5NNi3tI7FsGh+Cj/MIUlvNxCNCFWg=
gorm.io/plugin/dbresolver v1.5.1 h1:s9Dj9f7r+1rE3nx/Ywzc85nXptUEaeOO0pt27xdopM8=
gorm.io/plugin/dbresolver v1.5.1/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0=
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

@ -0,0 +1,18 @@
package dorm
import "database/sql"
// Ping ping
func (c *GormClient) Ping() error {
return c.sqlDd.Ping()
}
// Close 关闭
func (c *GormClient) Close() error {
return c.sqlDd.Close()
}
// Stats 返回数据库统计信息
func (c *GormClient) Stats() sql.DBStats {
return c.sqlDd.Stats()
}

@ -1,128 +1,54 @@
package dorm
import (
"errors"
"database/sql"
"fmt"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"os"
"path"
"time"
)
type ConfigGormClient struct {
Dns string // 地址
Log bool // 日志
LogUrl string // 日志路径
// GormClientFun *GormClient 驱动
type GormClientFun func() *GormClient
// GormClientTableFun
// *GormClient 驱动
// string 表名
type GormClientTableFun func() (*GormClient, string)
// GormClientConfig 配置
type GormClientConfig struct {
Dns string // 地址
LogStatus bool // 日志 - 状态
LogPath string // 日志 - 路径
LogSlow int64 // 日志 - 慢SQL阈值
LogLevel string // 日志 - 级别
ConnSetMaxIdle int // 连接 - 设置空闲连接池中连接的最大数量
ConnSetMaxOpen int // 连接 - 设置打开数据库连接的最大数量
ConnSetConnMaxLifetime int64 // 连接 - 设置了连接可复用的最大时间
}
// GormClient
// https://gorm.io/zh_CN/docs/index.html
type GormClient struct {
Db *gorm.DB // 驱动
config *ConfigGormClient
}
func NewGormMysqlClient(config *ConfigGormClient) (*GormClient, error) {
c := &GormClient{}
c.config = config
// 判断路径
if c.config.LogUrl == "" {
logsUrl = "/logs/mysql"
}
var err error
if c.config.Log == true {
c.Db, err = gorm.Open(mysql.Open(c.config.Dns), &gorm.Config{
Logger: logger.New(
writer{},
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: false, // 禁用彩色打印
},
),
})
} else {
c.Db, err = gorm.Open(mysql.Open(c.config.Dns), &gorm.Config{})
}
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
sqlDB, err := c.Db.DB()
if err != nil {
return nil, errors.New(fmt.Sprintf("检查连接失败:%v", err))
}
sqlDB.SetMaxIdleConns(10) // 设置空闲连接池中连接的最大数量
sqlDB.SetMaxOpenConns(100) // 设置打开数据库连接的最大数量。
sqlDB.SetConnMaxLifetime(time.Second * 600) // 设置了连接可复用的最大时间。
return c, nil
}
func NewGormPostgresClient(config *ConfigGormClient) (*GormClient, error) {
c := &GormClient{}
c.config = config
// 判断路径
if c.config.LogUrl == "" {
logsUrl = "/logs/postgresql"
}
var err error
if c.config.Log == true {
c.Db, err = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{
Logger: logger.New(
writer{},
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: logger.Info, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: false, // 禁用彩色打印
},
),
})
} else {
c.Db, err = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{})
}
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
sqlDB, err := c.Db.DB()
if err != nil {
return nil, errors.New(fmt.Sprintf("检查连接失败:%v", err))
}
sqlDB.SetMaxIdleConns(10) // 设置空闲连接池中连接的最大数量
sqlDB.SetMaxOpenConns(100) // 设置打开数据库连接的最大数量。
sqlDB.SetConnMaxLifetime(time.Second * 600) // 设置了连接可复用的最大时间。
return c, nil
db *gorm.DB // 驱动
config *GormClientConfig // 配置
sqlDd *sql.DB
}
type writer struct{}
// 日志路径
var logsUrl = ""
var logsURL = ""
func (w writer) Printf(format string, args ...interface{}) {
now := time.Now()
logFilePath := ""
if dir, err := os.Getwd(); err == nil {
logFilePath = dir + logsUrl
logFilePath = dir + logsURL
}
if err := os.MkdirAll(logFilePath, 0777); err != nil {
fmt.Println(err.Error())

@ -0,0 +1,8 @@
package dorm
import "gorm.io/gorm"
var (
// GormNotFound 没有数据
GormNotFound = gorm.ErrRecordNotFound
)

@ -0,0 +1,29 @@
package dorm
import (
"gorm.io/gen"
"gorm.io/gorm"
)
// GormGenClientFun *GormClient 驱动
type GormGenClientFun func() *GormGenClient
// GormGenClientTableFun
// *GormClient 驱动
// string 表名
type GormGenClientTableFun func() (*GormGenClient, string)
// GormGenClientConfig 配置
type GormGenClientConfig struct {
Dns string // dns地址
Db *gorm.DB // db驱动
Config gen.Config // gen配置
}
// GormGenClient
// https://gorm.io/zh_CN/gen/index.html
type GormGenClient struct {
db *gorm.DB // 驱动
generator *gen.Generator // 驱动
config *GormGenClientConfig // 配置
}

@ -0,0 +1,16 @@
package dorm
import (
"gorm.io/gen"
"gorm.io/gorm"
)
// GetDb 获取驱动
func (c *GormGenClient) GetDb() *gorm.DB {
return c.db
}
// GetGenerator 获取驱动
func (c *GormGenClient) GetGenerator() *gen.Generator {
return c.generator
}

@ -0,0 +1,25 @@
package dorm
import (
"context"
"gorm.io/driver/mysql"
"gorm.io/gen"
"gorm.io/gorm"
)
// NewGormGenMysqlClient 创建GormGenClient实例 mysql
func NewGormGenMysqlClient(ctx context.Context, config *GormGenClientConfig) (*GormGenClient, error) {
c := &GormGenClient{config: config}
c.generator = gen.NewGenerator(config.Config)
if c.config.Dns != "" {
c.db, _ = gorm.Open(mysql.Open(c.config.Dns), &gorm.Config{})
c.generator.UseDB(c.db)
} else {
c.generator.UseDB(c.config.Db)
}
return c, nil
}

@ -0,0 +1,25 @@
package dorm
import (
"context"
"gorm.io/driver/postgres"
"gorm.io/gen"
"gorm.io/gorm"
)
// NewGormGenPostgresClient 创建GormGenClient实例 postgres
func NewGormGenPostgresClient(ctx context.Context, config *GormGenClientConfig) (*GormGenClient, error) {
c := &GormGenClient{config: config}
c.generator = gen.NewGenerator(config.Config)
if c.config.Dns != "" {
c.db, _ = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{})
c.generator.UseDB(c.db)
} else {
c.generator.UseDB(c.config.Db)
}
return c, nil
}

@ -0,0 +1,25 @@
package dorm
import (
"context"
"gorm.io/driver/postgres"
"gorm.io/gen"
"gorm.io/gorm"
)
// NewGormGenPostgresqlClient 创建GormGenClient实例 postgresql
func NewGormGenPostgresqlClient(ctx context.Context, config *GormGenClientConfig) (*GormGenClient, error) {
c := &GormGenClient{config: config}
c.generator = gen.NewGenerator(config.Config)
if c.config.Dns != "" {
c.db, _ = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{})
c.generator.UseDB(c.db)
} else {
c.generator.UseDB(c.config.Db)
}
return c, nil
}

@ -0,0 +1,16 @@
package dorm
import (
"database/sql"
"gorm.io/gorm"
)
// GetDb 获取驱动
func (c *GormClient) GetDb() *gorm.DB {
return c.db
}
// GetSqlDb 获取驱动
func (c *GormClient) GetSqlDb() *sql.DB {
return c.sqlDd
}

@ -0,0 +1,91 @@
package dorm
import (
"context"
"errors"
"fmt"
"go.dtapp.net/gotime"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"time"
)
// NewGormMysqlClient 创建GormClient实例 mysql
func NewGormMysqlClient(ctx context.Context, config *GormClientConfig) (*GormClient, error) {
var err error
c := &GormClient{config: config}
// 判断路径
if c.config.LogPath == "" {
logsURL = "/logs/mysql"
} else {
logsURL = c.config.LogPath
}
if c.config.LogStatus {
var slowThreshold time.Duration
var logLevel logger.LogLevel
if c.config.LogSlow == 0 {
slowThreshold = 100 * time.Millisecond
} else {
slowThreshold = time.Duration(c.config.LogSlow)
}
if c.config.LogLevel == "Error" {
logLevel = logger.Error
} else if c.config.LogLevel == "Warn" {
logLevel = logger.Warn
} else {
logLevel = logger.Info
}
c.db, err = gorm.Open(mysql.Open(c.config.Dns), &gorm.Config{
Logger: logger.New(
writer{},
logger.Config{
SlowThreshold: slowThreshold, // 慢SQL阈值
LogLevel: logLevel, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: true, // 禁用彩色打印
},
),
NowFunc: func() time.Time {
return gotime.Current().Now().Local()
},
})
} else {
c.db, err = gorm.Open(mysql.Open(c.config.Dns), &gorm.Config{})
}
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
c.sqlDd, err = c.db.DB()
if err != nil {
return nil, errors.New(fmt.Sprintf("获取通用数据库对象失败:%v", err))
}
// 设置空闲连接池中连接的最大数量
if c.config.ConnSetMaxIdle == 0 {
c.sqlDd.SetMaxIdleConns(10)
} else {
c.sqlDd.SetMaxIdleConns(c.config.ConnSetMaxIdle)
}
// 设置打开数据库连接的最大数量
if c.config.ConnSetMaxOpen == 0 {
c.sqlDd.SetMaxOpenConns(100)
} else {
c.sqlDd.SetMaxOpenConns(c.config.ConnSetMaxOpen)
}
// 设置了连接可复用的最大时间
if c.config.ConnSetConnMaxLifetime == 0 {
c.sqlDd.SetConnMaxLifetime(time.Second * 600)
} else {
c.sqlDd.SetConnMaxLifetime(time.Duration(c.config.ConnSetConnMaxLifetime))
}
return c, nil
}

@ -0,0 +1,92 @@
package dorm
import (
"context"
"errors"
"fmt"
"go.dtapp.net/gotime"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"time"
)
// NewGormPostgresClient 创建GormClient实例 postgres
func NewGormPostgresClient(ctx context.Context, config *GormClientConfig) (*GormClient, error) {
var err error
c := &GormClient{}
c.config = config
// 判断路径
if c.config.LogPath == "" {
logsURL = "/logs/postgresql"
} else {
logsURL = c.config.LogPath
}
if c.config.LogStatus {
var slowThreshold time.Duration
var logLevel logger.LogLevel
if c.config.LogSlow == 0 {
slowThreshold = 100 * time.Millisecond
} else {
slowThreshold = time.Duration(c.config.LogSlow)
}
if c.config.LogLevel == "Error" {
logLevel = logger.Error
} else if c.config.LogLevel == "Warn" {
logLevel = logger.Warn
} else {
logLevel = logger.Info
}
c.db, err = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{
Logger: logger.New(
writer{},
logger.Config{
SlowThreshold: slowThreshold, // 慢SQL阈值
LogLevel: logLevel, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: true, // 禁用彩色打印
},
),
NowFunc: func() time.Time {
return gotime.Current().Now().Local()
},
})
} else {
c.db, err = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{})
}
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
c.sqlDd, err = c.db.DB()
if err != nil {
return nil, errors.New(fmt.Sprintf("获取通用数据库对象失败:%v", err))
}
// 设置空闲连接池中连接的最大数量
if c.config.ConnSetMaxIdle == 0 {
c.sqlDd.SetMaxIdleConns(10)
} else {
c.sqlDd.SetMaxIdleConns(c.config.ConnSetMaxIdle)
}
// 设置打开数据库连接的最大数量
if c.config.ConnSetMaxOpen == 0 {
c.sqlDd.SetMaxOpenConns(100)
} else {
c.sqlDd.SetMaxOpenConns(c.config.ConnSetMaxOpen)
}
// 设置了连接可复用的最大时间
if c.config.ConnSetConnMaxLifetime == 0 {
c.sqlDd.SetConnMaxLifetime(time.Hour)
} else {
c.sqlDd.SetConnMaxLifetime(time.Duration(c.config.ConnSetConnMaxLifetime))
}
return c, nil
}

@ -0,0 +1,92 @@
package dorm
import (
"context"
"errors"
"fmt"
"go.dtapp.net/gotime"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"time"
)
// NewGormPostgresqlClient 创建GormClient实例 postgresql
func NewGormPostgresqlClient(ctx context.Context, config *GormClientConfig) (*GormClient, error) {
var err error
c := &GormClient{}
c.config = config
// 判断路径
if c.config.LogPath == "" {
logsURL = "/logs/postgresql"
} else {
logsURL = c.config.LogPath
}
if c.config.LogStatus {
var slowThreshold time.Duration
var logLevel logger.LogLevel
if c.config.LogSlow == 0 {
slowThreshold = 100 * time.Millisecond
} else {
slowThreshold = time.Duration(c.config.LogSlow)
}
if c.config.LogLevel == "Error" {
logLevel = logger.Error
} else if c.config.LogLevel == "Warn" {
logLevel = logger.Warn
} else {
logLevel = logger.Info
}
c.db, err = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{
Logger: logger.New(
writer{},
logger.Config{
SlowThreshold: slowThreshold, // 慢SQL阈值
LogLevel: logLevel, // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: true, // 禁用彩色打印
},
),
NowFunc: func() time.Time {
return gotime.Current().Now().Local()
},
})
} else {
c.db, err = gorm.Open(postgres.Open(c.config.Dns), &gorm.Config{})
}
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
c.sqlDd, err = c.db.DB()
if err != nil {
return nil, errors.New(fmt.Sprintf("获取通用数据库对象失败:%v", err))
}
// 设置空闲连接池中连接的最大数量
if c.config.ConnSetMaxIdle == 0 {
c.sqlDd.SetMaxIdleConns(10)
} else {
c.sqlDd.SetMaxIdleConns(c.config.ConnSetMaxIdle)
}
// 设置打开数据库连接的最大数量
if c.config.ConnSetMaxOpen == 0 {
c.sqlDd.SetMaxOpenConns(100)
} else {
c.sqlDd.SetMaxOpenConns(c.config.ConnSetMaxOpen)
}
// 设置了连接可复用的最大时间
if c.config.ConnSetConnMaxLifetime == 0 {
c.sqlDd.SetConnMaxLifetime(time.Hour)
} else {
c.sqlDd.SetConnMaxLifetime(time.Duration(c.config.ConnSetConnMaxLifetime))
}
return c, nil
}

@ -0,0 +1,18 @@
package dorm
import "gorm.io/gorm"
// Begin 开始事务,不需要创建 Session 对象
func (c *GormClient) Begin() *gorm.DB {
return c.db.Begin()
}
// Rollback 回滚事务
func (c *GormClient) Rollback() *gorm.DB {
return c.db.Rollback()
}
// Commit 提交事务
func (c *GormClient) Commit() *gorm.DB {
return c.db.Commit()
}

@ -8,28 +8,52 @@ import (
"go.mongodb.org/mongo-driver/mongo/options"
)
type ConfigMongoClient struct {
Dns string // 地址
// MongoClientFun *MongoClient 驱动
// string 库名
type MongoClientFun func() (*MongoClient, string)
// MongoClientCollectionFun
// *MongoClient 驱动
// string 库名
// string 集合
type MongoClientCollectionFun func() (*MongoClient, string, string)
// MongoClientConfig 实例配置
type MongoClientConfig struct {
Dns string // 地址
Opts *options.ClientOptions
DatabaseName string // 库名
}
// MongoClient 实例
type MongoClient struct {
Db *mongo.Client // MongoDB驱动
config *ConfigMongoClient
db *mongo.Client // 驱动
configDatabaseName string // 库名
}
func NewMongoClient(config *ConfigMongoClient) (*MongoClient, error) {
// NewMongoClient 创建实例
func NewMongoClient(ctx context.Context, config *MongoClientConfig) (*MongoClient, error) {
var err error
c := &MongoClient{}
c.config = config
c.configDatabaseName = config.DatabaseName
// 连接到MongoDB
db, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(c.config.Dns))
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
if config.Dns != "" {
c.db, err = mongo.Connect(ctx, options.Client().ApplyURI(config.Dns))
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
} else {
c.db, err = mongo.Connect(ctx, config.Opts)
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
}
// 检查连接
err = db.Ping(context.TODO(), nil)
err = c.db.Ping(ctx, nil)
if err != nil {
return nil, errors.New(fmt.Sprintf("检查连接失败:%v", err))
}
@ -38,10 +62,6 @@ func NewMongoClient(config *ConfigMongoClient) (*MongoClient, error) {
}
// Close 关闭
func (c *MongoClient) Close() error {
err := c.Db.Disconnect(context.TODO())
if err != nil {
return errors.New(fmt.Sprintf("关闭失败:%v", err))
}
return nil
func (c *MongoClient) Close(ctx context.Context) error {
return c.db.Disconnect(ctx)
}

@ -0,0 +1,60 @@
package dorm
import (
"context"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type MongoCollectionOptions struct {
db *mongo.Client // 驱动
configDatabaseName string // 库名
dbCollection *mongo.Collection // 集合
}
// Collection 选择集合
func (cd *MongoDatabaseOptions) Collection(name string, opts ...*options.CollectionOptions) *MongoCollectionOptions {
return &MongoCollectionOptions{
db: cd.db, // 驱动
configDatabaseName: cd.configDatabaseName, // 库名
dbCollection: cd.dbDatabase.Collection(name, opts...), // 集合
}
}
// CreateOneIndexes 创建一个索引
func (cc *MongoCollectionOptions) CreateOneIndexes(ctx context.Context, key string, value string) (string, error) {
return cc.dbCollection.Indexes().CreateOne(ctx, mongo.IndexModel{
Keys: bson.D{{
Key: key,
Value: value,
}},
})
}
// CreateOneUniqueIndexes 创建一个唯一索引
func (cc *MongoCollectionOptions) CreateOneUniqueIndexes(ctx context.Context, key string, value string) (string, error) {
return cc.dbCollection.Indexes().CreateOne(ctx, mongo.IndexModel{
Keys: bson.D{{
Key: key,
Value: value,
}},
Options: options.Index().SetUnique(true),
})
}
// CreateOneUniqueIndexesOpts 创建一个索引
func (cc *MongoCollectionOptions) CreateOneUniqueIndexesOpts(ctx context.Context, key string, value string, opts *options.IndexOptions) (string, error) {
return cc.dbCollection.Indexes().CreateOne(ctx, mongo.IndexModel{
Keys: bson.D{{
Key: key,
Value: value,
}},
Options: opts,
})
}
// CreateManyIndexes 创建多个索引
func (cc *MongoCollectionOptions) CreateManyIndexes(ctx context.Context, models []mongo.IndexModel) ([]string, error) {
return cc.dbCollection.Indexes().CreateMany(ctx, models)
}

@ -0,0 +1,100 @@
package dorm
import (
"context"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// InsertOne 插入一个文档
func (cc *MongoCollectionOptions) InsertOne(ctx context.Context, document interface{}, opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {
return cc.dbCollection.InsertOne(ctx, document, opts...)
}
// InsertMany 插入多个文档
func (cc *MongoCollectionOptions) InsertMany(ctx context.Context, document []interface{}, opts ...*options.InsertManyOptions) (*mongo.InsertManyResult, error) {
return cc.dbCollection.InsertMany(ctx, document, opts...)
}
// DeleteOne 删除一个文档
func (cc *MongoCollectionOptions) DeleteOne(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
return cc.dbCollection.DeleteOne(ctx, filter, opts...)
}
// DeleteMany 删除多个文档
func (cc *MongoCollectionOptions) DeleteMany(ctx context.Context, filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
return cc.dbCollection.DeleteMany(ctx, filter, opts...)
}
// UpdateByID 按ID更新
func (cc *MongoCollectionOptions) UpdateByID(ctx context.Context, id interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
return cc.dbCollection.UpdateByID(ctx, id, update, opts...)
}
// UpdateOne 更新一个文档
func (cc *MongoCollectionOptions) UpdateOne(ctx context.Context, filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
return cc.dbCollection.UpdateOne(ctx, filter, update, opts...)
}
// UpdateMany 更新多个文档
func (cc *MongoCollectionOptions) UpdateMany(ctx context.Context, filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
return cc.dbCollection.UpdateMany(ctx, filter, update, opts...)
}
// ReplaceOne 替换一个文档
func (cc *MongoCollectionOptions) ReplaceOne(ctx context.Context, filter interface{}, update interface{}, opts ...*options.ReplaceOptions) (*mongo.UpdateResult, error) {
return cc.dbCollection.ReplaceOne(ctx, filter, update, opts...)
}
// Aggregate 统计分析
func (cc *MongoCollectionOptions) Aggregate(ctx context.Context, pipeline interface{}, opts ...*options.AggregateOptions) (*mongo.Cursor, error) {
return cc.dbCollection.Aggregate(ctx, pipeline, opts...)
}
// CountDocuments 计数文档
func (cc *MongoCollectionOptions) CountDocuments(ctx context.Context, filter interface{}, opts ...*options.CountOptions) (int64, error) {
return cc.dbCollection.CountDocuments(ctx, filter, opts...)
}
// EstimatedDocumentCount 估计文档计数
func (cc *MongoCollectionOptions) EstimatedDocumentCount(ctx context.Context, opts ...*options.EstimatedDocumentCountOptions) (int64, error) {
return cc.dbCollection.EstimatedDocumentCount(ctx, opts...)
}
func (cc *MongoCollectionOptions) Distinct(ctx context.Context, fieldName string, filter interface{}, opts ...*options.DistinctOptions) ([]interface{}, error) {
return cc.dbCollection.Distinct(ctx, fieldName, filter, opts...)
}
// Find 查询多个文档
func (cc *MongoCollectionOptions) Find(ctx context.Context, filter interface{}, opts ...*options.FindOptions) (*mongo.Cursor, error) {
return cc.dbCollection.Find(ctx, filter, opts...)
}
// FindOne 查询一个文档
func (cc *MongoCollectionOptions) FindOne(ctx context.Context, filter interface{}, opts ...*options.FindOneOptions) *mongo.SingleResult {
return cc.dbCollection.FindOne(ctx, filter, opts...)
}
func (cc *MongoCollectionOptions) FindOneAndDelete(ctx context.Context, filter interface{}, opts ...*options.FindOneAndDeleteOptions) *mongo.SingleResult {
return cc.dbCollection.FindOneAndDelete(ctx, filter, opts...)
}
func (cc *MongoCollectionOptions) FindOneAndReplace(ctx context.Context, filter interface{}, replacement interface{}, opts ...*options.FindOneAndReplaceOptions) *mongo.SingleResult {
return cc.dbCollection.FindOneAndReplace(ctx, filter, replacement, opts...)
}
func (cc *MongoCollectionOptions) FindOneAndUpdate(ctx context.Context, filter interface{}, replacement interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult {
return cc.dbCollection.FindOneAndUpdate(ctx, filter, replacement, opts...)
}
func (cc *MongoCollectionOptions) Watch(ctx context.Context, pipeline interface{}, opts ...*options.ChangeStreamOptions) (*mongo.ChangeStream, error) {
return cc.dbCollection.Watch(ctx, pipeline, opts...)
}
func (cc *MongoCollectionOptions) Indexes(ctx context.Context) mongo.IndexView {
return cc.dbCollection.Indexes()
}
func (cc *MongoCollectionOptions) Drop(ctx context.Context) error {
return cc.dbCollection.Drop(ctx)
}

@ -0,0 +1,69 @@
package dorm
import (
"context"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"reflect"
)
type MongoDatabaseOptions struct {
db *mongo.Client // 驱动
configDatabaseName string // 库名
dbDatabase *mongo.Database // 数据库
}
// Database 选择数据库
func (c *MongoClient) Database(name string, opts ...*options.DatabaseOptions) *MongoDatabaseOptions {
return &MongoDatabaseOptions{
db: c.db, // 驱动
configDatabaseName: c.configDatabaseName, // 库名
dbDatabase: c.db.Database(name, opts...), // 数据库
}
}
// CreateCollection 创建集合
func (cd *MongoDatabaseOptions) CreateCollection(ctx context.Context, name string, opts ...*options.CreateCollectionOptions) error {
return cd.dbDatabase.CreateCollection(ctx, name, opts...)
}
// CreateTimeSeriesCollection 创建时间序列集合
func (cd *MongoDatabaseOptions) CreateTimeSeriesCollection(ctx context.Context, name string, timeField string) error {
return cd.dbDatabase.CreateCollection(ctx, name, options.CreateCollection().SetTimeSeriesOptions(options.TimeSeries().SetTimeField(timeField)))
}
// Model 传入模型自动获取库名和表名
// https://studygolang.com/articles/896
// DatabaseName 库名
// CollectionName 集合名
func (c *MongoClient) Model(value interface{}) *MongoCollectionOptions {
var databaseOptions *MongoDatabaseOptions
var collectionOptions *MongoCollectionOptions
val := reflect.ValueOf(value)
methodDatabaseNameValue := val.MethodByName("DatabaseName")
if methodDatabaseNameValue.IsValid() {
databaseName := methodDatabaseNameValue.Call(nil)[0].String()
databaseOptions = c.Database(databaseName)
} else {
databaseOptions = c.Database(c.configDatabaseName)
}
methodCollectionNameValue := val.MethodByName("CollectionName")
if methodCollectionNameValue.IsValid() {
collectionName := methodCollectionNameValue.Call(nil)[0].String()
collectionOptions = databaseOptions.Collection(collectionName)
} else {
methodTableNameValue := val.MethodByName("TableName")
if methodTableNameValue.IsValid() {
collectionName := methodTableNameValue.Call(nil)[0].String()
collectionOptions = databaseOptions.Collection(collectionName)
} else {
panic(NoConfigCollectionName)
}
}
return collectionOptions
}

@ -0,0 +1,8 @@
package dorm
import "errors"
var (
NoConfigDatabaseName = errors.New("没有配置库名")
NoConfigCollectionName = errors.New("没有配置集合名")
)

@ -0,0 +1,8 @@
package dorm
import "go.mongodb.org/mongo-driver/mongo"
// GetDb 获取驱动
func (c *MongoClient) GetDb() *mongo.Client {
return c.db
}

@ -0,0 +1,59 @@
package dorm
import (
"context"
"go.mongodb.org/mongo-driver/mongo"
"log"
)
type MongoSessionOptions struct {
db *mongo.Client // 驱动
configDatabaseName string // 库名
session mongo.Session // 会话
sessionContext mongo.SessionContext // 会话上下文
}
// Begin 开始事务,会同时创建开始会话需要在退出时关闭会话
func (c *MongoClient) Begin() *MongoSessionOptions {
var ctx = context.TODO()
var err error
ms := &MongoSessionOptions{}
ms.db = c.GetDb()
ms.configDatabaseName = c.configDatabaseName
// 开始会话
ms.session, err = ms.db.StartSession()
if err != nil {
log.Println("开始会话异常:", err)
}
// 会话上下文
ms.sessionContext = mongo.NewSessionContext(ctx, ms.session)
// 会话开启事务
err = ms.session.StartTransaction()
return ms
}
// Rollback 回滚事务
func (cs *MongoSessionOptions) Rollback() {
var ctx = context.TODO()
err := cs.session.AbortTransaction(ctx)
if err != nil {
log.Println("回滚事务异常:", err)
}
cs.session.EndSession(ctx)
}
// Commit 提交事务
func (cs *MongoSessionOptions) Commit() {
var ctx = context.TODO()
err := cs.session.CommitTransaction(ctx)
if err != nil {
log.Println("提交事务异常:", err)
}
cs.session.EndSession(ctx)
}

@ -0,0 +1,25 @@
package dorm
import (
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type MongoSessionCollectionOptions struct {
db *mongo.Client // 驱动
configDatabaseName string // 库名
session mongo.Session // 会话
sessionContext mongo.SessionContext // 会话上下文
dbCollection *mongo.Collection // 集合
}
// Collection 选择集合
func (csd *MongoSessionDatabaseOptions) Collection(name string, opts ...*options.CollectionOptions) *MongoSessionCollectionOptions {
return &MongoSessionCollectionOptions{
db: csd.db, // 驱动
configDatabaseName: csd.configDatabaseName, // 库名
session: csd.session, // 会话
sessionContext: csd.sessionContext, // 会话上下文
dbCollection: csd.dbDatabase.Collection(name, opts...), // 集合
}
}

@ -0,0 +1,99 @@
package dorm
import (
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
// InsertOne 插入一个文档
func (csc *MongoSessionCollectionOptions) InsertOne(document interface{}, opts ...*options.InsertOneOptions) (*mongo.InsertOneResult, error) {
return csc.dbCollection.InsertOne(csc.sessionContext, document, opts...)
}
// InsertMany 插入多个文档
func (csc *MongoSessionCollectionOptions) InsertMany(document []interface{}, opts ...*options.InsertManyOptions) (*mongo.InsertManyResult, error) {
return csc.dbCollection.InsertMany(csc.sessionContext, document, opts...)
}
// DeleteOne 删除一个文档
func (csc *MongoSessionCollectionOptions) DeleteOne(filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
return csc.dbCollection.DeleteOne(csc.sessionContext, filter, opts...)
}
// DeleteMany 删除多个文档
func (csc *MongoSessionCollectionOptions) DeleteMany(filter interface{}, opts ...*options.DeleteOptions) (*mongo.DeleteResult, error) {
return csc.dbCollection.DeleteMany(csc.sessionContext, filter, opts...)
}
// UpdateByID 按ID更新
func (csc *MongoSessionCollectionOptions) UpdateByID(id interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
return csc.dbCollection.UpdateByID(csc.sessionContext, id, update, opts...)
}
// UpdateOne 更新一个文档
func (csc *MongoSessionCollectionOptions) UpdateOne(filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
return csc.dbCollection.UpdateOne(csc.sessionContext, filter, update, opts...)
}
// UpdateMany 更新多个文档
func (csc *MongoSessionCollectionOptions) UpdateMany(filter interface{}, update interface{}, opts ...*options.UpdateOptions) (*mongo.UpdateResult, error) {
return csc.dbCollection.UpdateMany(csc.sessionContext, filter, update, opts...)
}
// ReplaceOne 替换一个文档
func (csc *MongoSessionCollectionOptions) ReplaceOne(filter interface{}, update interface{}, opts ...*options.ReplaceOptions) (*mongo.UpdateResult, error) {
return csc.dbCollection.ReplaceOne(csc.sessionContext, filter, update, opts...)
}
// Aggregate 统计分析
func (csc *MongoSessionCollectionOptions) Aggregate(pipeline interface{}, opts ...*options.AggregateOptions) (*mongo.Cursor, error) {
return csc.dbCollection.Aggregate(csc.sessionContext, pipeline, opts...)
}
// CountDocuments 计数文档
func (csc *MongoSessionCollectionOptions) CountDocuments(filter interface{}, opts ...*options.CountOptions) (int64, error) {
return csc.dbCollection.CountDocuments(csc.sessionContext, filter, opts...)
}
// EstimatedDocumentCount 估计文档计数
func (csc *MongoSessionCollectionOptions) EstimatedDocumentCount(opts ...*options.EstimatedDocumentCountOptions) (int64, error) {
return csc.dbCollection.EstimatedDocumentCount(csc.sessionContext, opts...)
}
func (csc *MongoSessionCollectionOptions) Distinct(fieldName string, filter interface{}, opts ...*options.DistinctOptions) ([]interface{}, error) {
return csc.dbCollection.Distinct(csc.sessionContext, fieldName, filter, opts...)
}
// Find 查询多个文档
func (csc *MongoSessionCollectionOptions) Find(filter interface{}, opts ...*options.FindOptions) (*mongo.Cursor, error) {
return csc.dbCollection.Find(csc.sessionContext, filter, opts...)
}
// FindOne 查询一个文档
func (csc *MongoSessionCollectionOptions) FindOne(filter interface{}, opts ...*options.FindOneOptions) *mongo.SingleResult {
return csc.dbCollection.FindOne(csc.sessionContext, filter, opts...)
}
func (csc *MongoSessionCollectionOptions) FindOneAndDelete(filter interface{}, opts ...*options.FindOneAndDeleteOptions) *mongo.SingleResult {
return csc.dbCollection.FindOneAndDelete(csc.sessionContext, filter, opts...)
}
func (csc *MongoSessionCollectionOptions) FindOneAndReplace(filter interface{}, replacement interface{}, opts ...*options.FindOneAndReplaceOptions) *mongo.SingleResult {
return csc.dbCollection.FindOneAndReplace(csc.sessionContext, filter, replacement, opts...)
}
func (csc *MongoSessionCollectionOptions) FindOneAndUpdate(filter interface{}, replacement interface{}, opts ...*options.FindOneAndUpdateOptions) *mongo.SingleResult {
return csc.dbCollection.FindOneAndUpdate(csc.sessionContext, filter, replacement, opts...)
}
func (csc *MongoSessionCollectionOptions) Watch(pipeline interface{}, opts ...*options.ChangeStreamOptions) (*mongo.ChangeStream, error) {
return csc.dbCollection.Watch(csc.sessionContext, pipeline, opts...)
}
func (csc *MongoSessionCollectionOptions) Indexes() mongo.IndexView {
return csc.dbCollection.Indexes()
}
func (csc *MongoSessionCollectionOptions) Drop() error {
return csc.dbCollection.Drop(csc.sessionContext)
}

@ -0,0 +1,62 @@
package dorm
import (
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"reflect"
)
type MongoSessionDatabaseOptions struct {
db *mongo.Client // 驱动
configDatabaseName string // 库名
session mongo.Session // 会话
sessionContext mongo.SessionContext // 会话上下文
dbDatabase *mongo.Database // 数据库
}
// Database 选择数据库
func (cs *MongoSessionOptions) Database(name string, opts ...*options.DatabaseOptions) *MongoSessionDatabaseOptions {
return &MongoSessionDatabaseOptions{
db: cs.db, // 驱动
configDatabaseName: cs.configDatabaseName, // 库名
session: cs.session, // 会话
sessionContext: cs.sessionContext, // 会话上下文
dbDatabase: cs.db.Database(name, opts...), // 数据库
}
}
// Model 传入模型自动获取库名和表名
// https://studygolang.com/articles/896
// DatabaseName 库名
// CollectionName 集合名
func (cs *MongoSessionOptions) Model(value interface{}) *MongoSessionCollectionOptions {
var sessionDatabaseOptions *MongoSessionDatabaseOptions
var sessionCollectionOptions *MongoSessionCollectionOptions
val := reflect.ValueOf(value)
methodDatabaseNameValue := val.MethodByName("DatabaseName")
if methodDatabaseNameValue.IsValid() {
databaseName := methodDatabaseNameValue.Call(nil)[0].String()
sessionDatabaseOptions = cs.Database(databaseName)
} else {
sessionDatabaseOptions = cs.Database(cs.configDatabaseName)
}
methodCollectionNameValue := val.MethodByName("CollectionName")
if methodCollectionNameValue.IsValid() {
collectionName := methodCollectionNameValue.Call(nil)[0].String()
sessionCollectionOptions = sessionDatabaseOptions.Collection(collectionName)
} else {
methodTableNameValue := val.MethodByName("TableName")
if methodTableNameValue.IsValid() {
collectionName := methodTableNameValue.Call(nil)[0].String()
sessionCollectionOptions = sessionDatabaseOptions.Collection(collectionName)
} else {
panic(NoConfigCollectionName)
}
}
return sessionCollectionOptions
}

@ -0,0 +1,18 @@
package dorm
import "go.mongodb.org/mongo-driver/mongo"
// GetDb 获取驱动
func (cs *MongoSessionOptions) GetDb() *mongo.Client {
return cs.db
}
// GetSession 获取会话
func (cs *MongoSessionOptions) GetSession() mongo.Session {
return cs.session
}
// GetSessionContext 获取会话上下文
func (cs *MongoSessionOptions) GetSessionContext() mongo.SessionContext {
return cs.sessionContext
}

@ -0,0 +1,85 @@
package dorm
import (
"go.dtapp.net/gotime"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/bsontype"
"time"
)
// BsonTime 时间类型
type BsonTime time.Time
// MarshalJSON 实现json序列化
func (bt BsonTime) MarshalJSON() ([]byte, error) {
b := make([]byte, 0)
b = append(b, '"')
b = append(b, gotime.SetCurrent(time.Time(bt)).Bson()...)
b = append(b, '"')
return b, nil
}
// UnmarshalJSON 实现json反序列化
func (bt *BsonTime) UnmarshalJSON(data []byte) (err error) {
if string(data) == "null" {
return nil
}
bsonTime := gotime.SetCurrentParse(string(data))
*bt = BsonTime(bsonTime.Time)
return nil
}
// Time 转时间
func (bt BsonTime) Time() time.Time {
return gotime.SetCurrent(time.Time(bt)).Time
}
// Format 转时间字符串
func (bt BsonTime) Format() string {
return gotime.SetCurrent(time.Time(bt)).Format()
}
// TimePro 转时间操作
func (bt BsonTime) TimePro() gotime.Pro {
return gotime.SetCurrent(time.Time(bt))
}
// NewBsonTimeCurrent 创建当前时间
func NewBsonTimeCurrent() BsonTime {
return BsonTime(gotime.Current().Time)
}
// NewBsonTimeFromTime 创建某个时间
func NewBsonTimeFromTime(t time.Time) BsonTime {
return BsonTime(t)
}
// NewBsonTimeFromString 创建某个时间 字符串
func NewBsonTimeFromString(t string) BsonTime {
return BsonTime(gotime.SetCurrentParse(t).Time)
}
// Value 时间类型
func (bt BsonTime) Value() string {
return gotime.SetCurrent(time.Time(bt)).Bson()
}
// MarshalBSONValue 实现bson序列化
func (bt BsonTime) MarshalBSONValue() (bsontype.Type, []byte, error) {
return bson.MarshalValue(gotime.SetCurrent(time.Time(bt)).Bson())
}
// UnmarshalBSONValue 实现bson反序列化
func (bt *BsonTime) UnmarshalBSONValue(t bsontype.Type, data []byte) error {
t1 := gotime.SetCurrentParse(string(data))
//if string(data) == "" {
// return errors.New(fmt.Sprintf("%s, %s, %s", "读取数据失败:", t, data))
//}
*bt = BsonTime(t1.Time)
return nil
}

@ -0,0 +1,79 @@
package dorm
import (
"context"
"errors"
"fmt"
"github.com/redis/go-redis/v9"
"time"
)
// RedisClientFun *RedisClient 驱动
type RedisClientFun func() *RedisClient
type RedisClientConfig struct {
Addr string // 地址
Password string // 密码
DB int // 数据库
PoolSize int // 连接池大小
ReadTimeout time.Duration // 读取超时
}
// RedisClient
// https://redis.uptrace.dev/
type RedisClient struct {
db *redis.Client // 驱动
}
// NewRedisClient 创建实例
func NewRedisClient(config *RedisClientConfig) (*RedisClient, error) {
c := &RedisClient{}
if config.PoolSize == 0 {
config.PoolSize = 100
}
c.db = redis.NewClient(&redis.Options{
Addr: config.Addr, // 地址
Password: config.Password, // 密码
DB: config.DB, // 数据库
PoolSize: config.PoolSize, // 连接池大小
ReadTimeout: config.ReadTimeout, // 读取超时
})
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 检测 Redis 连接是否正常连接
_, err := c.db.Ping(ctx).Result()
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
return c, nil
}
// NewRedisClientURL 创建实例
func NewRedisClientURL(redisURL string) (*RedisClient, error) {
c := &RedisClient{}
opt, err := redis.ParseURL(redisURL)
if err != nil {
return c, nil
}
// 创建 Redis 客户端
c.db = redis.NewClient(opt)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
// 检测 Redis 连接是否正常连接
_, err = c.db.Ping(ctx).Result()
if err != nil {
return nil, errors.New(fmt.Sprintf("连接失败:%v", err))
}
return c, nil
}

@ -0,0 +1,26 @@
package dorm
type Iterator struct {
data []interface{}
index int
}
// NewIterator 构造函数
func NewIterator(data []interface{}) *Iterator {
return &Iterator{data: data}
}
// HasNext 是否有下一个
func (i *Iterator) HasNext() bool {
if i.data == nil || len(i.data) == 0 {
return false
}
return i.index < len(i.data)
}
// Next 循环下一个
func (i *Iterator) Next() (Ret interface{}) {
Ret = i.data[i.index]
i.index = i.index + 1
return
}

@ -0,0 +1,96 @@
package dorm
import (
"context"
"go.dtapp.net/gojson"
"time"
)
// GttStringFunc String缓存结构
type GttStringFunc func() string
// GttInterfaceFunc Interface缓存结构
type GttInterfaceFunc func() interface{}
// RedisCacheConfig 配置
type RedisCacheConfig struct {
Expiration time.Duration // 过期时间
}
// RedisClientCache https://github.com/go-redis/redis
type RedisClientCache struct {
defaultExpiration time.Duration // 过期时间
operation *RedisClient // 操作
GetterString GttStringFunc // 不存在的操作
GetterInterface GttInterfaceFunc // 不存在的操作
}
// NewCache 实例化
func (r *RedisClient) NewCache(config *RedisCacheConfig) *RedisClientCache {
return &RedisClientCache{
defaultExpiration: config.Expiration,
operation: r,
}
}
// NewCacheDefaultExpiration 实例化
func (r *RedisClient) NewCacheDefaultExpiration() *RedisClientCache {
return &RedisClientCache{
defaultExpiration: time.Minute * 30,
operation: r,
}
}
// GetString 缓存操作
func (rc *RedisClientCache) GetString(ctx context.Context, key string) (ret string) {
f := func() string {
return rc.GetterString()
}
// 如果不存在则调用GetterString
ret, err := rc.operation.Get(ctx, key).Result()
if err != nil {
rc.operation.Set(ctx, key, f(), rc.defaultExpiration)
ret, _ = rc.operation.Get(ctx, key).Result()
}
return
}
// GetInterface 缓存操作
func (rc *RedisClientCache) GetInterface(ctx context.Context, key string, result interface{}) {
f := func() string {
marshal, _ := gojson.Marshal(rc.GetterInterface())
return string(marshal)
}
// 如果不存在则调用GetterInterface
ret, err := rc.operation.Get(ctx, key).Result()
if err != nil {
rc.operation.Set(ctx, key, f(), rc.defaultExpiration)
ret, _ = rc.operation.Get(ctx, key).Result()
}
err = gojson.Unmarshal([]byte(ret), result)
return
}
// GetInterfaceKey 获取key值
func (rc *RedisClientCache) GetInterfaceKey(ctx context.Context, key string, result interface{}) error {
ret, err := rc.operation.Get(ctx, key).Result()
if err != nil {
return err
}
err = gojson.Unmarshal([]byte(ret), result)
return nil
}
// SetInterfaceKey 设置key值
func (rc *RedisClientCache) SetInterfaceKey(ctx context.Context, key string, value interface{}) (string, error) {
marshal, _ := gojson.Marshal(value)
return rc.operation.Set(ctx, key, marshal, rc.defaultExpiration).Result()
}

@ -0,0 +1,158 @@
package dorm
import (
"context"
"github.com/redis/go-redis/v9"
"time"
)
// Set 设置一个key的值
func (r *RedisClient) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.StatusCmd {
return r.db.Set(ctx, key, value, expiration)
}
// Get 查询key的值
func (r *RedisClient) Get(ctx context.Context, key string) *redis.StringCmd {
return r.db.Get(ctx, key)
}
// GetSet 设置一个key的值并返回这个key的旧值
func (r *RedisClient) GetSet(ctx context.Context, key string, value interface{}) *redis.StringCmd {
return r.db.GetSet(ctx, key, value)
}
// SetNX 如果key不存在则设置这个key的值
func (r *RedisClient) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd {
return r.db.SetNX(ctx, key, value, expiration)
}
// MGet 批量查询key的值
func (r *RedisClient) MGet(ctx context.Context, keys ...string) *redis.SliceCmd {
return r.db.MGet(ctx, keys...)
}
// MSet 批量设置key的值
// MSet(map[string]interface{}{"key1": "value1", "key2": "value2"})
func (r *RedisClient) MSet(ctx context.Context, values map[string]interface{}) *redis.StatusCmd {
return r.db.MSet(ctx, values)
}
// Incr 针对一个key的数值进行递增操作
func (r *RedisClient) Incr(ctx context.Context, key string) *redis.IntCmd {
return r.db.Incr(ctx, key)
}
// IncrBy 针对一个key的数值进行递增操作指定每次递增多少
func (r *RedisClient) IncrBy(ctx context.Context, key string, value int64) *redis.IntCmd {
return r.db.IncrBy(ctx, key, value)
}
// Decr 针对一个key的数值进行递减操作
func (r *RedisClient) Decr(ctx context.Context, key string) *redis.IntCmd {
return r.db.Decr(ctx, key)
}
// DecrBy 针对一个key的数值进行递减操作指定每次递减多少
func (r *RedisClient) DecrBy(ctx context.Context, key string, value int64) *redis.IntCmd {
return r.db.DecrBy(ctx, key, value)
}
// Del 删除key操作支持批量删除
func (r *RedisClient) Del(ctx context.Context, keys ...string) *redis.IntCmd {
return r.db.Del(ctx, keys...)
}
// Keys 按前缀获取所有key名
func (r *RedisClient) Keys(ctx context.Context, prefix string) []string {
values, _ := r.db.Keys(ctx, prefix).Result()
keys := make([]string, 0, len(values))
if len(values) <= 0 {
return keys
}
for _, value := range values {
keys = append(keys, value)
}
return keys
}
// KeysValue 按前缀获取所有key值
func (r *RedisClient) KeysValue(ctx context.Context, prefix string) *redis.SliceCmd {
values, _ := r.db.Keys(ctx, prefix).Result()
if len(values) <= 0 {
return &redis.SliceCmd{}
}
keys := make([]string, 0, len(values))
for _, value := range values {
keys = append(keys, value)
}
return r.MGet(ctx, keys...)
}
// AddKeyToSet 将值添加到集合
func (r *RedisClient) AddKeyToSet(ctx context.Context, setKey string, value interface{}) error {
return r.db.SAdd(ctx, setKey, value).Err()
}
// GetAllKeysInSet 获取集合的所有元素
func (r *RedisClient) GetAllKeysInSet(ctx context.Context, setKey string) ([]string, error) {
return r.db.SMembers(ctx, setKey).Result()
}
// DoesKeyExistInSet 检查值是否存在于集合中
func (r *RedisClient) DoesKeyExistInSet(ctx context.Context, setKey string, targetKey interface{}) (bool, error) {
return r.db.SIsMember(ctx, setKey, targetKey).Result()
}
// RemoveKeyFromSet 从集合中删除指定的元素
func (r *RedisClient) RemoveKeyFromSet(ctx context.Context, setKey string, targetKey interface{}) error {
return r.db.SRem(ctx, setKey, targetKey).Err()
}
// DeleteKeysWithPrefix 根据前缀删除key
func (r *RedisClient) DeleteKeysWithPrefix(ctx context.Context, prefix string) error {
// 获取所有符合给定模式的键
keys, err := r.db.Keys(ctx, prefix+"*").Result()
if err != nil {
return err
}
// 删除所有匹配的键
if len(keys) > 0 {
_, err := r.db.Del(ctx, keys...).Result()
if err != nil {
return err
}
}
return nil
}
// DeleteScanWithPrefix 根据前缀删除key
func (r *RedisClient) DeleteScanWithPrefix(ctx context.Context, prefix string) error {
var cursor uint64
for {
// 使用 SCAN 迭代获取匹配模式的键
keys, nextCursor, err := r.db.Scan(ctx, cursor, prefix+"*", 10).Result()
if err != nil {
return err
}
// 删除当前迭代返回的键
if len(keys) > 0 {
_, err := r.db.Del(ctx, keys...).Result()
if err != nil {
return err
}
}
// 更新游标,继续迭代
cursor = nextCursor
// 如果迭代结束,退出循环
if cursor == 0 {
break
}
}
return nil
}

@ -0,0 +1,31 @@
package dorm
import (
"context"
"github.com/redis/go-redis/v9"
)
// Subscribe 订阅channel
func (r *RedisClient) Subscribe(ctx context.Context, channels ...string) *redis.PubSub {
return r.db.Subscribe(ctx, channels...)
}
// PSubscribe 订阅channel支持通配符匹配
func (r *RedisClient) PSubscribe(ctx context.Context, channels ...string) *redis.PubSub {
return r.db.PSubscribe(ctx, channels...)
}
// Publish 将信息发送到指定的channel
func (r *RedisClient) Publish(ctx context.Context, channel string, message interface{}) *redis.IntCmd {
return r.db.Publish(ctx, channel, message)
}
// PubSubChannels 查询活跃的channel
func (r *RedisClient) PubSubChannels(ctx context.Context, pattern string) *redis.StringSliceCmd {
return r.db.PubSubChannels(ctx, pattern)
}
// PubSubNumSub 查询指定的channel有多少个订阅者
func (r *RedisClient) PubSubNumSub(ctx context.Context, channels ...string) *redis.MapStringIntCmd {
return r.db.PubSubNumSub(ctx, channels...)
}

@ -0,0 +1,8 @@
package dorm
import "errors"
var (
// RedisKeysNotFound keys没有数据
RedisKeysNotFound = errors.New("ERR wrong number of arguments for 'mget' command")
)

@ -0,0 +1,8 @@
package dorm
import "github.com/redis/go-redis/v9"
// GetDb 获取驱动
func (r *RedisClient) GetDb() *redis.Client {
return r.db
}

@ -0,0 +1,26 @@
package dorm
import (
"context"
"github.com/redis/go-redis/v9"
)
// HashOperation Hash类型数据操作
type HashOperation struct {
db *redis.Client
}
// NewHashOperation hash类型数据操作 https://www.tizi365.com/archives/296.html
func NewHashOperation(db *redis.Client) *HashOperation {
return &HashOperation{db: db}
}
// Set 根据key和field字段设置field字段的值
func (cl *HashOperation) Set(ctx context.Context, key string, value interface{}) *redis.IntCmd {
return cl.db.HSet(ctx, key, value)
}
// Get 根据key和field字段设置field字段的值
func (cl *HashOperation) Get(ctx context.Context, key, field string) *redis.StringCmd {
return cl.db.HGet(ctx, key, field)
}

@ -0,0 +1,77 @@
package dorm
import (
"context"
"github.com/redis/go-redis/v9"
)
// ListOperation 列表(list)类型数据操作
type ListOperation struct {
db *redis.Client
ctx context.Context
}
// NewListOperation 列表(list)类型数据操作 https://www.tizi365.com/archives/299.html
func (r *RedisClient) NewListOperation() *ListOperation {
return &ListOperation{db: r.db, ctx: context.Background()}
}
// LPush 从列表左边插入数据
func (cl *ListOperation) LPush(key string, value interface{}) *redis.IntCmd {
return cl.db.LPush(cl.ctx, key, value)
}
// LPushX 跟LPush的区别是仅当列表存在的时候才插入数据
func (cl *ListOperation) LPushX(key string, value interface{}) *redis.IntCmd {
return cl.db.LPushX(cl.ctx, key, value)
}
// RPop 从列表的右边删除第一个数据,并返回删除的数据
func (cl *ListOperation) RPop(key string) *redis.StringCmd {
return cl.db.RPop(cl.ctx, key)
}
// RPush 从列表右边插入数据
func (cl *ListOperation) RPush(key string, value interface{}) *redis.IntCmd {
return cl.db.RPush(cl.ctx, key, value)
}
// RPushX 跟RPush的区别是仅当列表存在的时候才插入数据
func (cl *ListOperation) RPushX(key string, value interface{}) *redis.IntCmd {
return cl.db.RPushX(cl.ctx, key, value)
}
// LPop 从列表左边删除第一个数据,并返回删除的数据
func (cl *ListOperation) LPop(key string) *redis.StringCmd {
return cl.db.LPop(cl.ctx, key)
}
// Len 返回列表的大小
func (cl *ListOperation) Len(key string) *redis.IntCmd {
return cl.db.LLen(cl.ctx, key)
}
// Range 返回列表的一个范围内的数据,也可以返回全部数据
func (cl *ListOperation) Range(key string, start, stop int64) *redis.StringSliceCmd {
return cl.db.LRange(cl.ctx, key, start, stop)
}
// RangeAli 返回key全部数据
func (cl *ListOperation) RangeAli(key string) *redis.StringSliceCmd {
return cl.db.LRange(cl.ctx, key, 0, -1)
}
// Rem 删除key中的数据
func (cl *ListOperation) Rem(key string, count int64, value interface{}) *redis.IntCmd {
return cl.db.LRem(cl.ctx, key, count, value)
}
// Index 根据索引坐标查询key中的数据
func (cl *ListOperation) Index(key string, index int64) *redis.StringCmd {
return cl.db.LIndex(cl.ctx, key, index)
}
// Insert 在指定位置插入数据
func (cl *ListOperation) Insert(key, op string, pivot, value interface{}) *redis.IntCmd {
return cl.db.LInsert(cl.ctx, key, op, pivot, value)
}

@ -0,0 +1,73 @@
package dorm
import (
"context"
"errors"
"fmt"
"github.com/redis/go-redis/v9"
"time"
)
// RedisClientLock https://github.com/go-redis/redis
type RedisClientLock struct {
operation *RedisClient // 操作
}
// NewLock 实例化锁
func (r *RedisClient) NewLock() *RedisClientLock {
return &RedisClientLock{r}
}
// Lock 上锁
// key 锁名
// val 锁内容
// ttl 锁过期时间
func (rl *RedisClientLock) Lock(ctx context.Context, key string, val string, ttl time.Duration) (resp string, err error) {
if ttl <= 0 {
return resp, errors.New("长期请使用 LockForever 方法")
}
// 获取
get, err := rl.operation.Get(ctx, key).Result()
if errors.Is(err, redis.Nil) {
// 设置
err = rl.operation.Set(ctx, key, val, ttl).Err()
if err != nil {
return resp, errors.New(fmt.Sprintf("上锁失败:%s", err.Error()))
}
return val, nil
}
if get != "" {
return resp, errors.New("上锁失败,已存在")
}
return resp, errors.New(fmt.Sprintf("获取异常:%s", err.Error()))
}
// Unlock 解锁
// key 锁名
func (rl *RedisClientLock) Unlock(ctx context.Context, key string) error {
_, err := rl.operation.Del(ctx, key).Result()
if err != nil {
return errors.New(fmt.Sprintf("解锁失败:%s", err.Error()))
}
return err
}
// LockForever 永远上锁
// key 锁名
// val 锁内容
func (rl *RedisClientLock) LockForever(ctx context.Context, key string, val string) (resp string, err error) {
// 获取
get, err := rl.operation.Get(ctx, key).Result()
if errors.Is(err, redis.Nil) {
// 设置
err = rl.operation.Set(ctx, key, val, 0).Err()
if err != nil {
return resp, errors.New(fmt.Sprintf("上锁失败:%s", err.Error()))
}
return val, nil
}
if get != "" {
return resp, errors.New("上锁失败,已存在")
}
return resp, errors.New(fmt.Sprintf("获取异常:%s", err.Error()))
}

@ -0,0 +1,35 @@
package dorm
import "time"
type empty struct{}
const (
AttrExpr = "expr" // 过期时间
AttrNx = "nx" // 设置Nx
)
type OperationAttr struct {
Name string
Value interface{}
}
type OperationAttrs []*OperationAttr
func (a OperationAttrs) Find(name string) interface{} {
for _, attr := range a {
if attr.Name == name {
return attr.Value
}
}
return nil
}
// WithExpire 过期时间
func WithExpire(t time.Duration) *OperationAttr {
return &OperationAttr{Name: AttrExpr, Value: t}
}
func WithNX() *OperationAttr {
return &OperationAttr{Name: AttrNx, Value: empty{}}
}

@ -0,0 +1,62 @@
package dorm
import (
"context"
"go.dtapp.net/gojson"
"time"
)
const (
SerializerJson = "json"
SerializerString = "string"
)
type JsonGttFunc func() interface{}
type DBGttFunc func() string
// SimpleCache 缓存
type SimpleCache struct {
Operation *StringOperation // 操作类
Expire time.Duration // 过去时间
DBGetter DBGttFunc // 缓存不存在的操作 DB
JsonGetter JsonGttFunc // 缓存不存在的操作 JSON
Serializer string // 序列化方式
}
// NewSimpleCache 构造函数
func (r *RedisClient) NewSimpleCache(operation *StringOperation, expire time.Duration, serializer string) *SimpleCache {
return &SimpleCache{
Operation: operation, // 操作类
Expire: expire, // 过去时间
Serializer: serializer, // 缓存不存在的操作 DB
}
}
// SetCache 设置缓存
func (c *SimpleCache) SetCache(ctx context.Context, key string, value interface{}) {
c.Operation.Set(ctx, key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleCache) GetCache(ctx context.Context, key string) (ret interface{}) {
if c.Serializer == SerializerJson {
f := func() string {
obj := c.JsonGetter()
b, err := gojson.Marshal(obj)
if err != nil {
return ""
}
return string(b)
}
ret = c.Operation.Get(ctx, key).UnwrapOrElse(f)
c.SetCache(ctx, key, ret)
} else if c.Serializer == SerializerString {
f := func() string {
return c.DBGetter()
}
ret = c.Operation.Get(ctx, key).UnwrapOrElse(f)
c.SetCache(ctx, key, ret)
}
return
}

@ -0,0 +1,38 @@
package dorm
import (
"context"
"time"
)
type DBGttInterfaceFunc func() interface{}
// SimpleInterfaceCache 缓存
type SimpleInterfaceCache struct {
Operation *SimpleOperation // 操作类
Expire time.Duration // 过期时间
DBGetter DBGttInterfaceFunc // 缓存不存在的操作 DB
}
// NewSimpleInterfaceCache 构造函数
func (r *RedisClient) NewSimpleInterfaceCache(operation *SimpleOperation, expire time.Duration) *SimpleInterfaceCache {
return &SimpleInterfaceCache{
Operation: operation, // 操作类
Expire: expire, // 过期时间
}
}
// SetCache 设置缓存
func (c *SimpleInterfaceCache) SetCache(ctx context.Context, key string, value interface{}) {
c.Operation.Set(ctx, key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleInterfaceCache) GetCache(ctx context.Context, key string) (ret interface{}) {
f := func() interface{} {
return c.DBGetter()
}
ret = c.Operation.Get(ctx, key).UnwrapOrElse(f)
c.SetCache(ctx, key, ret)
return ret
}

@ -0,0 +1,44 @@
package dorm
import (
"context"
"go.dtapp.net/gojson"
"time"
)
type DBGttJsonFunc func() interface{}
// SimpleJsonCache 缓存
type SimpleJsonCache struct {
Operation *StringOperation // 操作类
Expire time.Duration // 过期时间
DBGetter DBGttJsonFunc // 缓存不存在的操作 DB
}
// NewSimpleJsonCache 构造函数
func (r *RedisClient) NewSimpleJsonCache(operation *StringOperation, expire time.Duration) *SimpleJsonCache {
return &SimpleJsonCache{
Operation: operation, // 操作类
Expire: expire, // 过期时间
}
}
// SetCache 设置缓存
func (c *SimpleJsonCache) SetCache(ctx context.Context, key string, value interface{}) {
c.Operation.Set(ctx, key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleJsonCache) GetCache(ctx context.Context, key string) (ret interface{}) {
f := func() string {
obj := c.DBGetter()
b, err := gojson.Marshal(obj)
if err != nil {
return ""
}
return string(b)
}
ret = c.Operation.Get(ctx, key).UnwrapOrElse(f)
c.SetCache(ctx, key, ret)
return
}

@ -0,0 +1,34 @@
package dorm
import (
"context"
"github.com/redis/go-redis/v9"
"time"
)
type SimpleOperation struct {
db *redis.Client
}
func (r *RedisClient) NewSimpleOperation() *SimpleOperation {
return &SimpleOperation{db: r.db}
}
// Set 设置
func (o *SimpleOperation) Set(ctx context.Context, key string, value interface{}, attrs ...*OperationAttr) *SimpleResult {
exp := OperationAttrs(attrs).Find(AttrExpr)
if exp == nil {
exp = time.Second * 0
}
return NewSimpleResult(o.db.Set(ctx, key, value, exp.(time.Duration)).Result())
}
// Get 获取单个
func (o *SimpleOperation) Get(ctx context.Context, key string) *SimpleResult {
return NewSimpleResult(o.db.Get(ctx, key).Result())
}
// Del 删除key操作支持批量删除
func (o *SimpleOperation) Del(ctx context.Context, keys ...string) *redis.IntCmd {
return o.db.Del(ctx, keys...)
}

@ -0,0 +1,35 @@
package dorm
type SimpleResult struct {
Result interface{}
Err error
}
// NewSimpleResult 构造函数
func NewSimpleResult(result interface{}, err error) *SimpleResult {
return &SimpleResult{Result: result, Err: err}
}
// Unwrap 空值情况下返回错误
func (r *SimpleResult) Unwrap() interface{} {
if r.Err != nil {
panic(r.Err)
}
return r.Result
}
// UnwrapOr 空值情况下设置返回默认值
func (r *SimpleResult) UnwrapOr(defaults interface{}) interface{} {
if r.Err != nil {
return defaults
}
return r.Result
}
// UnwrapOrElse 空值情况下设置返回其他
func (r *SimpleResult) UnwrapOrElse(f func() interface{}) interface{} {
if r.Err != nil {
return f()
}
return r.Result
}

@ -0,0 +1,38 @@
package dorm
import (
"context"
"time"
)
type DBGttStringFunc func() string
// SimpleStringCache 缓存
type SimpleStringCache struct {
Operation *StringOperation // 操作类
Expire time.Duration // 过期时间
DBGetter DBGttStringFunc // 缓存不存在的操作 DB
}
// NewSimpleStringCache 构造函数
func (r *RedisClient) NewSimpleStringCache(operation *StringOperation, expire time.Duration) *SimpleStringCache {
return &SimpleStringCache{
Operation: operation, // 操作类
Expire: expire, // 过期时间
}
}
// SetCache 设置缓存
func (c *SimpleStringCache) SetCache(ctx context.Context, key string, value string) {
c.Operation.Set(ctx, key, value, WithExpire(c.Expire)).Unwrap()
}
// GetCache 获取缓存
func (c *SimpleStringCache) GetCache(ctx context.Context, key string) (ret string) {
f := func() string {
return c.DBGetter()
}
ret = c.Operation.Get(ctx, key).UnwrapOrElse(f)
c.SetCache(ctx, key, ret)
return
}

@ -0,0 +1,31 @@
package dorm
type SliceResult struct {
Result []interface{}
Err error
}
// NewSliceResult 构造函数
func NewSliceResult(result []interface{}, err error) *SliceResult {
return &SliceResult{Result: result, Err: err}
}
// Unwrap 空值情况下返回错误
func (r *SliceResult) Unwrap() []interface{} {
if r.Err != nil {
panic(r.Err)
}
return r.Result
}
// UnwrapOr 空值情况下设置返回默认值
func (r *SliceResult) UnwrapOr(defaults []interface{}) []interface{} {
if r.Err != nil {
return defaults
}
return r.Result
}
func (r *SliceResult) Iter() *Iterator {
return NewIterator(r.Result)
}

@ -0,0 +1,39 @@
package dorm
import (
"context"
"github.com/redis/go-redis/v9"
"time"
)
type StringOperation struct {
db *redis.Client
}
func (r *RedisClient) NewStringOperation() *StringOperation {
return &StringOperation{db: r.db}
}
// Set 设置
func (o *StringOperation) Set(ctx context.Context, key string, value interface{}, attrs ...*OperationAttr) *StringResult {
exp := OperationAttrs(attrs).Find(AttrExpr)
if exp == nil {
exp = time.Second * 0
}
return NewStringResult(o.db.Set(ctx, key, value, exp.(time.Duration)).Result())
}
// Get 获取单个
func (o *StringOperation) Get(ctx context.Context, key string) *StringResult {
return NewStringResult(o.db.Get(ctx, key).Result())
}
// MGet 获取多个
func (o *StringOperation) MGet(ctx context.Context, keys ...string) *SliceResult {
return NewSliceResult(o.db.MGet(ctx, keys...).Result())
}
// Del 删除key操作支持批量删除
func (o *StringOperation) Del(ctx context.Context, keys ...string) *redis.IntCmd {
return o.db.Del(ctx, keys...)
}

@ -0,0 +1,38 @@
package dorm
type StringResult struct {
Result string // 结果
Err error // 错误
}
// NewStringResult 构造函数
func NewStringResult(result string, err error) *StringResult {
return &StringResult{
Result: result,
Err: err,
}
}
// Unwrap 空值情况下返回错误
func (r *StringResult) Unwrap() string {
if r.Err != nil {
panic(r.Err)
}
return r.Result
}
// UnwrapOr 空值情况下设置返回默认值
func (r *StringResult) UnwrapOr(defaults string) string {
if r.Err != nil {
return defaults
}
return r.Result
}
// UnwrapOrElse 空值情况下设置返回其他
func (r *StringResult) UnwrapOrElse(f func() string) string {
if r.Err != nil {
return f()
}
return r.Result
}

@ -0,0 +1,76 @@
package dorm
// Bool 复制 bool 对象,并返回复制体
func Bool(b bool) bool {
return b
}
// Uint8 复制 int8 对象,并返回复制体
func Uint8(ui uint8) uint8 {
return ui
}
// Uint16 复制 uint16 对象,并返回复制体
func Uint16(ui uint16) uint16 {
return ui
}
// Uint32 复制 uint32 对象,并返回复制体
func Uint32(ui uint32) uint32 {
return ui
}
// Uint64 复制 uint64 对象,并返回复制体
func Uint64(ui uint64) uint64 {
return ui
}
// Int8 复制 int8 对象,并返回复制体
func Int8(i int8) int8 {
return i
}
// Int16 复制 int16 对象,并返回复制体
func Int16(i int16) int16 {
return i
}
// Int32 复制 int64 对象,并返回复制体
func Int32(i int32) int32 {
return i
}
// Int64 复制 int64 对象,并返回复制体
func Int64(i int64) int64 {
return i
}
// Float32 复制 float32 对象,并返回复制体
func Float32(f float32) float32 {
return f
}
// Float64 复制 float64 对象,并返回复制体
func Float64(f float64) float64 {
return f
}
// String 复制 string 对象,并返回复制体
func String(s string) string {
return s
}
// Int 复制 int 对象,并返回复制体
func Int(i int) int {
return i
}
// Uint 复制 uint 对象,并返回复制体
func Uint(ui uint) uint {
return ui
}
// Any 复制 any 对象,并返回复制体
func Any(a any) any {
return a
}

@ -1,3 +1,4 @@
package dorm
const Version = "1.0.1"
// Version 版本
const Version = "1.0.59"

@ -1,7 +0,0 @@
package dorm
import "testing"
func TestVersion(t *testing.T) {
t.Log(Version)
}
Loading…
Cancel
Save