merge from x/sqlx

r/paopao-ce-pro
Michael Li 2 years ago
commit 74ce4e5b10
No known key found for this signature in database

@ -1,6 +1,6 @@
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
| ----- | ----- | ----- | ----- | ----- | ----- |
| 002| 北野 | 2022-11-04 | 2022-11-06 | v0.2 | 提议 |
| 002| 北野 | 2022-11-04 | 2023-01-04 | v1.0 | 提议 |
### Friendship功能项的设计概要
Friendship功能提供好友间分享推文信息的机制更好的帮助用户建立自己的推文分享小圈子。Friendship本质上想优化的是泡泡广场页面推文列表的生成机制开启功能后推文列表只能获取 `公开/私密/好友` 的推文,每个用户都有属于自己的个性化推文列表。在提供个性化推文列表生成机制的同时,好友体系的建立也顺便帮助用户建立自己的个性化有限范围内的灵魂社交小圈子,只有相互间拥有个性化认同感的用户才能互为好友。
@ -27,6 +27,8 @@ Friendship功能提供好友间分享推文信息的机制更好的帮助用
* 推文展示时标记推文的可见性描述;
#### 设计细节
* 参考实现(PR):
[add support Friendship feature #192](https://github.com/rocboss/paopao-ce/pull/192)
* 预览
@ -36,6 +38,7 @@ Friendship功能提供好友间分享推文信息的机制更好的帮助用
| ![](.assets/002-02.png)![](.assets/002-01.png)|
| ![](.assets/002-07.png)|
| ![](.assets/002-08.png)|
### 疑问
1. 什么是弱关系好友体系?
@ -58,4 +61,7 @@ Friendship功能提供好友间分享推文信息的机制更好的帮助用
* 初始文档
#### v0.2(2022-11-06) - 北野
* 添加初始文档内容
* 添加初始文档内容
#### v1.0(2023-01-04) - 北野
* 添加参考实现PR信息

@ -1,6 +1,6 @@
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
| ----- | ----- | ----- | ----- | ----- | ----- |
| 005| 北野 | 2022-11-21 | 2022-12-10 | v1.0 | 提议 |
| 005| 北野 | 2022-11-21 | 2023-01-04 | v1.1 | 提议 |
### 引入go-mir优化后端架构设计
引入[github.com/alimy/mir/v3](https://github.com/alimy/mir)优化后端的架构设计,使得后端代码更具扩展型。
@ -16,6 +16,9 @@
依赖库:
* [go-mir](https://github.com/alimy/mir)
参考实现(PR):
* [引入go-mir重构paopao-ce的接入层与业务逻辑层 #196](https://github.com/rocboss/paopao-ce/pull/196)
### 疑问
1. 为什么引入go-mir
@ -35,3 +38,6 @@
#### v1.0(2022-12-10) - 北野
* 添加内容
#### v1.1(2023-01-04) - 北野
* 添加参考实现PR信息

@ -24,6 +24,7 @@ require (
github.com/golang-migrate/migrate/v4 v4.15.2
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.12+incompatible
github.com/jackc/pgx/v5 v5.2.0
github.com/jmoiron/sqlx v1.3.5
github.com/json-iterator/go v1.1.12
github.com/meilisearch/meilisearch-go v0.21.0
github.com/minio/minio-go/v7 v7.0.45
@ -36,13 +37,13 @@ require (
google.golang.org/protobuf v1.28.1
gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/resty.v1 v1.12.0
gorm.io/driver/mysql v1.3.4
gorm.io/driver/postgres v1.3.7
gorm.io/driver/sqlite v1.3.4
gorm.io/gorm v1.23.4
gorm.io/plugin/dbresolver v1.1.0
gorm.io/plugin/soft_delete v1.1.0
modernc.org/sqlite v1.17.3
gorm.io/driver/mysql v1.4.5
gorm.io/driver/postgres v1.4.6
gorm.io/driver/sqlite v1.4.4
gorm.io/gorm v1.24.3
gorm.io/plugin/dbresolver v1.4.0
gorm.io/plugin/soft_delete v1.2.0
modernc.org/sqlite v1.20.1
)
require (
@ -59,7 +60,7 @@ require (
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.10.1 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
@ -67,14 +68,8 @@ require (
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/hcl v1.0.0 // 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-20221227161230-091c0ba34f0a // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
@ -86,8 +81,8 @@ require (
github.com/magiconair/properties v1.8.6 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-sqlite3 v1.14.12 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-sqlite3 v1.14.15 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
@ -111,25 +106,25 @@ require (
github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 // indirect
golang.org/x/crypto v0.4.0 // indirect
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect
golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect
golang.org/x/text v0.4.0 // indirect
golang.org/x/net v0.3.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/uint128 v1.1.1 // indirect
modernc.org/cc/v3 v3.36.0 // indirect
modernc.org/ccgo/v3 v3.16.6 // indirect
modernc.org/libc v1.16.7 // indirect
modernc.org/mathutil v1.4.1 // indirect
modernc.org/memory v1.1.1 // indirect
modernc.org/opt v0.1.1 // indirect
modernc.org/strutil v1.1.1 // indirect
modernc.org/token v1.0.0 // indirect
lukechampine.com/uint128 v1.2.0 // indirect
modernc.org/cc/v3 v3.40.0 // indirect
modernc.org/ccgo/v3 v3.16.13 // indirect
modernc.org/libc v1.22.2 // indirect
modernc.org/mathutil v1.5.0 // indirect
modernc.org/memory v1.4.0 // indirect
modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.1.3 // indirect
modernc.org/token v1.0.1 // indirect
)

151
go.sum

@ -284,7 +284,6 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
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/cockroachdb/cockroach-go/v2 v2.1.1/go.mod h1:7NtUnP6eK+l6k483WSYNrq3Kb23bWV10IRV1TyeSpwM=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
@ -587,8 +586,9 @@ github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5Nq
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
@ -735,6 +735,7 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@ -832,7 +833,6 @@ github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6t
github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw=
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=
@ -841,17 +841,9 @@ github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5
github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI=
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/pgerrcode v0.0.0-20201024163028-a0d42d470451/go.mod h1:a/s9Lp5W7n/DD0VrVoyJ00FbP2ytTPDVOivvn2bMlds=
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/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/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78=
@ -862,12 +854,10 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:
github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
github.com/jackc/pgproto3/v2 v2.0.7/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-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E=
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/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
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=
@ -875,9 +865,6 @@ github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4
github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po=
github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ=
github.com/jackc/pgtype v1.6.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig=
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=
@ -885,9 +872,6 @@ github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXg
github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o=
github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg=
github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA=
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/pgx/v5 v5.2.0 h1:NdPpngX0Y6z6XDFKqmFQaE+bCtkqzvQIOt1wvBlAqs8=
github.com/jackc/pgx/v5 v5.2.0/go.mod h1:Ptn7zmohNsWEsdxRawMzk3gaKma2obW+NWTnKa0S4nk=
github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
@ -895,7 +879,7 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f
github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk=
github.com/jackc/puddle v1.1.1/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/puddle/v2 v2.1.2/go.mod h1:2lpufsF5mRHO6SuZkm0fNYxM6SWHfvyFj62KwNzgels=
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
@ -913,6 +897,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g=
github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ=
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
@ -1037,8 +1023,9 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
@ -1050,8 +1037,8 @@ github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsO
github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.10/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
@ -1289,7 +1276,6 @@ github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAm
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
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/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
@ -1429,6 +1415,7 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
@ -1478,7 +1465,6 @@ go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqe
go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ=
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/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
@ -1486,13 +1472,11 @@ go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
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/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
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=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 h1:18EFjUmQOcUvxNYSkA6jO9VAiXCnxFY6NyDX0bHDmkU=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
@ -1522,20 +1506,18 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/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-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
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-20210817164053-32db794688a5/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-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 h1:Y/gsMcFOcR+6S6f3YeMKl5g+dZMEWqcz5Czj/GWYbkM=
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@ -1660,8 +1642,9 @@ golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0 h1:VWL6FNY2bEEmsGVKabSlHu5Irp34xmMRoqb/9lF9lxk=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@ -1692,6 +1675,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220923202941-7f9b1623fab7/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -1812,7 +1797,6 @@ golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@ -1821,15 +1805,20 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/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-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -1839,8 +1828,9 @@ 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/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1895,7 +1885,6 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
@ -2168,27 +2157,28 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
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/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9oI=
gorm.io/driver/mysql v1.3.4 h1:/KoBMgsUHC3bExsekDcmNYaBnfH2WNeFuXqqrqMc98Q=
gorm.io/driver/mysql v1.3.4/go.mod h1:s4Tq0KmD0yhPGHbZEwg1VPlH0vT/GBHJZorPzhcxBUE=
gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c=
gorm.io/driver/mysql v1.4.5 h1:u1lytId4+o9dDaNcPCFzNv7h6wvmc92UjNk3z8enSBU=
gorm.io/driver/mysql v1.4.5/go.mod h1:SxzItlnT1cb6e1e4ZRpgJN2VYtcqJgqnHxWr4wsP8oc=
gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg=
gorm.io/driver/postgres v1.3.7 h1:FKF6sIMDHDEvvMF/XJvbnCl0nu6KSKUaPXevJ4r+VYQ=
gorm.io/driver/postgres v1.3.7/go.mod h1:f02ympjIcgtHEGFMZvdgTxODZ9snAHDb4hXfigBVuNI=
gorm.io/driver/postgres v1.4.6 h1:1FPESNXqIKG5JmraaH2bfCVlMQ7paLoCreFxDtqzwdc=
gorm.io/driver/postgres v1.4.6/go.mod h1:UJChCNLFKeBqQRE+HrkFUbKbq9idPXmTOk2u4Wok8S4=
gorm.io/driver/sqlite v1.1.3/go.mod h1:AKDgRWk8lcSQSw+9kxCJnX/yySj8G3rdwYlU57cB45c=
gorm.io/driver/sqlite v1.3.4 h1:NnFOPVfzi4CPsJPH4wXr6rMkPb4ElHEqKMvrsx9c9Fk=
gorm.io/driver/sqlite v1.3.4/go.mod h1:B+8GyC9K7VgzJAcrcXMRPdnMcck+8FgJynEehEPM16U=
gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc=
gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
gorm.io/gorm v1.20.1/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.20.11/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.23.0/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.23.4 h1:1BKWM67O6CflSLcwGQR7ccfmC4ebOxQrTfOQGRE9wjg=
gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/plugin/dbresolver v1.1.0 h1:cegr4DeprR6SkLIQlKhJLYxH8muFbJ4SmnojXvoeb00=
gorm.io/plugin/dbresolver v1.1.0/go.mod h1:tpImigFAEejCALOttyhWqsy4vfa2Uh/vAUVnL5IRF7Y=
gorm.io/plugin/soft_delete v1.1.0 h1:LcE4L+GD29RkkMLxMYHpT4wQCJ/9945FsdU/mHGaDuE=
gorm.io/plugin/soft_delete v1.1.0/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk=
gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk=
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/gorm v1.24.2/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/gorm v1.24.3 h1:WL2ifUmzR/SLp85CSURAfybcHnGZ+yLSGSxgYXlFBHg=
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
gorm.io/plugin/dbresolver v1.4.0 h1:MnT3JFDFpZ1lJ6MoGW5jOAHHuItL/jfBCwqmdVWMC+A=
gorm.io/plugin/dbresolver v1.4.0/go.mod h1:w0DKqg02frWKwbBMTQkJ7aVxeKnap2cShQcroOQaq8k=
gorm.io/plugin/soft_delete v1.2.0 h1:txWHRMqLPqfXUFytXCdxb/jthRe3CrG4R5XOdagut6Q=
gorm.io/plugin/soft_delete v1.2.0/go.mod h1:Zv7vQctOJTGOsJ/bWgrN1n3od0GBAZgnLjEx+cApLGk=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
@ -2244,20 +2234,16 @@ k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
modernc.org/cc/v3 v3.32.4/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
modernc.org/cc/v3 v3.36.0 h1:0kmRkTmqNidmu3c7BNDSdVHCxXCkWLmWmCIVX4LUboo=
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=
modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
modernc.org/ccgo/v3 v3.9.2/go.mod h1:gnJpy6NIVqkETT+L5zPsQFj7L2kkhfPMzOghRNv/CFo=
modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
modernc.org/ccgo/v3 v3.16.6 h1:3l18poV+iUemQ98O3X5OMr97LOqlzis+ytivU4NqGhA=
modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw=
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
@ -2265,41 +2251,38 @@ modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM=
modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
modernc.org/libc v1.9.5/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=
modernc.org/libc v1.16.7 h1:qzQtHhsZNpVPpeCu+aMIQldXeV1P0vRhSqCL0nOIJOA=
modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8=
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU=
modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs=
modernc.org/sqlite v1.17.3 h1:iE+coC5g17LtByDYDWKpR6m2Z9022YrSh3bumwOnIrI=
modernc.org/sqlite v1.17.3/go.mod h1:10hPVYar9C0kfXuTWGz8s0XtB8uAGymUy51ZzStYe3k=
modernc.org/sqlite v1.20.1 h1:z6qRLw72B0VfRrJjs3l6hWkzYDx1bo0WGVrBGP4ohhM=
modernc.org/sqlite v1.20.1/go.mod h1:fODt+bFmc/j8LcoCbMSkAuKuGmhxjG45KGc25N2705M=
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.5.2/go.mod h1:pmJYOLgpiys3oI4AeAafkcUfE+TKKilminxNyU/+Zlo=
modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao=
modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw=
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34=
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM=
modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=

@ -122,7 +122,6 @@ func Initialize(suite []string, noDefault bool) {
}
setupLogger()
setupDBEngine()
}
func GetOssDomain() string {

@ -1,94 +1,57 @@
// Copyright 2022 ROC. All rights reserved.
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (
"database/sql"
"sync"
"time"
"github.com/alimy/cfg"
"github.com/go-redis/redis/v8"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"gorm.io/plugin/dbresolver"
)
var (
db *gorm.DB
Redis *redis.Client
once sync.Once
_sqldb *sql.DB
_redisClient *redis.Client
_onceSql, _onceRedis sync.Once
)
func MustGormDB() *gorm.DB {
once.Do(func() {
func MustSqlDB() *sql.DB {
_onceSql.Do(func() {
var err error
if db, err = newDBEngine(); err != nil {
logrus.Fatalf("new gorm db failed: %s", err)
if _, _sqldb, err = newSqlDB(); err != nil {
logrus.Fatalf("new sql db failed: %s", err)
}
})
return db
return _sqldb
}
func newDBEngine() (*gorm.DB, error) {
newLogger := logger.New(
logrus.StandardLogger(), // io writer日志输出的目标前缀和日志包含的内容
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: DatabaseSetting.logLevel(), // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: false, // 禁用彩色打印
},
)
config := &gorm.Config{
Logger: newLogger,
NamingStrategy: schema.NamingStrategy{
TablePrefix: DatabaseSetting.TablePrefix,
SingularTable: true,
},
}
plugin := dbresolver.Register(dbresolver.Config{}).
SetConnMaxIdleTime(time.Hour).
SetConnMaxLifetime(24 * time.Hour).
SetMaxIdleConns(MysqlSetting.MaxIdleConns).
SetMaxOpenConns(MysqlSetting.MaxOpenConns)
func MustRedis() *redis.Client {
_onceRedis.Do(func() {
_redisClient = redis.NewClient(&redis.Options{
Addr: redisSetting.Host,
Password: redisSetting.Password,
DB: redisSetting.DB,
})
})
return _redisClient
}
var (
db *gorm.DB
err error
)
func newSqlDB() (driver string, db *sql.DB, err error) {
if cfg.If("MySQL") {
logrus.Debugln("use MySQL as db")
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil {
db.Use(plugin)
}
} else if cfg.If("Postgres") {
logrus.Debugln("use PostgreSQL as db")
db, err = gorm.Open(postgres.Open(PostgresSetting.Dsn()), config)
driver = "mysql"
db, err = sql.Open(driver, MysqlSetting.Dsn())
} else if cfg.If("PostgreSQL") || cfg.If("Postgres") {
driver = "pgx"
db, err = sql.Open(driver, PostgresSetting.Dsn())
} else if cfg.If("Sqlite3") {
logrus.Debugf("use Sqlite3 as db path:%s sqlite3InCgoEnabled:%t", Sqlite3Setting.Path, sqlite3InCgoEnabled)
db, err = gormOpenSqlite3(config)
driver, db, err = OpenSqlite3()
} else {
logrus.Debugln("use default of MySQL as db")
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil {
db.Use(plugin)
}
driver = "mysql"
db, err = sql.Open(driver, MysqlSetting.Dsn())
}
return db, err
}
func setupDBEngine() {
Redis = redis.NewClient(&redis.Options{
Addr: redisSetting.Host,
Password: redisSetting.Password,
DB: redisSetting.DB,
})
return
}

@ -18,8 +18,9 @@ const (
sqlite3InCgoEnabled = true
)
func OpenSqlite3() (*sql.DB, error) {
return sql.Open("sqlite3", Sqlite3Setting.Dsn("sqlite3"))
func OpenSqlite3() (string, *sql.DB, error) {
db, err := sql.Open("sqlite3", Sqlite3Setting.Dsn("sqlite3"))
return "sqlite3", db, err
}
func gormOpenSqlite3(opts ...gorm.Option) (*gorm.DB, error) {

@ -0,0 +1,84 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (
"sync"
"time"
"github.com/alimy/cfg"
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"gorm.io/gorm/schema"
"gorm.io/plugin/dbresolver"
)
var (
_gormdb *gorm.DB
_onceGorm sync.Once
)
func MustGormDB() *gorm.DB {
_onceGorm.Do(func() {
var err error
if _gormdb, err = newGormDB(); err != nil {
logrus.Fatalf("new gorm db failed: %s", err)
}
})
return _gormdb
}
func newGormDB() (*gorm.DB, error) {
newLogger := logger.New(
logrus.StandardLogger(), // io writer日志输出的目标前缀和日志包含的内容
logger.Config{
SlowThreshold: time.Second, // 慢 SQL 阈值
LogLevel: DatabaseSetting.logLevel(), // 日志级别
IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound记录未找到错误
Colorful: false, // 禁用彩色打印
},
)
config := &gorm.Config{
Logger: newLogger,
NamingStrategy: schema.NamingStrategy{
TablePrefix: DatabaseSetting.TablePrefix,
SingularTable: true,
},
}
plugin := dbresolver.Register(dbresolver.Config{}).
SetConnMaxIdleTime(time.Hour).
SetConnMaxLifetime(24 * time.Hour).
SetMaxIdleConns(MysqlSetting.MaxIdleConns).
SetMaxOpenConns(MysqlSetting.MaxOpenConns)
var (
db *gorm.DB
err error
)
if cfg.If("MySQL") {
logrus.Debugln("use MySQL as db")
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil {
db.Use(plugin)
}
} else if cfg.If("Postgres") {
logrus.Debugln("use PostgreSQL as db")
db, err = gorm.Open(postgres.Open(PostgresSetting.Dsn()), config)
} else if cfg.If("Sqlite3") {
logrus.Debugf("use Sqlite3 as db path:%s sqlite3InCgoEnabled:%t", Sqlite3Setting.Path, sqlite3InCgoEnabled)
db, err = gormOpenSqlite3(config)
} else {
logrus.Debugln("use default of MySQL as db")
if db, err = gorm.Open(mysql.Open(MysqlSetting.Dsn()), config); err == nil {
db.Use(plugin)
}
}
return db, err
}

@ -19,8 +19,9 @@ const (
sqlite3InCgoEnabled = false
)
func OpenSqlite3() (*sql.DB, error) {
return sql.Open("sqlite", Sqlite3Setting.Dsn("sqlite"))
func OpenSqlite3() (string, *sql.DB, error) {
db, err := sql.Open("sqlite", Sqlite3Setting.Dsn("sqlite"))
return "sqlite", db, err
}
func gormOpenSqlite3(opts ...gorm.Option) (*gorm.DB, error) {

@ -0,0 +1,28 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf
import (
"sync"
"github.com/jmoiron/sqlx"
"github.com/sirupsen/logrus"
)
var (
_sqlxdb *sqlx.DB
_onceSqlx sync.Once
)
func MustSqlxDB() *sqlx.DB {
_onceSqlx.Do(func() {
driver, db, err := newSqlDB()
if err != nil {
logrus.Fatalf("new sqlx db failed: %s", err)
}
_sqlxdb = sqlx.NewDb(db, driver)
})
return _sqlxdb
}

@ -30,9 +30,9 @@ func DataService() core.DataService {
var v core.VersionInfo
if cfg.If("Gorm") {
ds, v = jinzhu.NewDataService()
} else if cfg.If("Sqlx") && cfg.If("MySQL") {
} else if cfg.If("Sqlx") {
ds, v = sakila.NewDataService()
} else if cfg.If("Sqlx") && (cfg.If("Postgres") || cfg.If("PostgreSQL")) {
} else if cfg.If("Sqlc") && (cfg.If("Postgres") || cfg.If("PostgreSQL")) {
ds, v = slonik.NewDataService()
} else {
// default use gorm as orm for sql database

@ -48,7 +48,7 @@ func (t *Tag) Get(db *gorm.DB) (*Tag, error) {
err := db.First(&tag).Error
if err != nil {
return &tag, err
return nil, err
}
return &tag, nil
@ -88,7 +88,7 @@ func (t *Tag) List(db *gorm.DB, conditions *ConditionsT, offset, limit int) ([]*
}
}
if err = db.Where("is_del = ?", 0).Find(&tags).Error; err != nil {
if err = db.Where("is_del = 0 and quote_num > 0").Find(&tags).Error; err != nil {
return nil, err
}

@ -24,32 +24,32 @@ func newMessageService(db *gorm.DB) core.MessageService {
}
}
func (d *messageServant) CreateMessage(msg *core.Message) (*core.Message, error) {
return msg.Create(d.db)
func (s *messageServant) CreateMessage(msg *core.Message) (*core.Message, error) {
return msg.Create(s.db)
}
func (d *messageServant) GetUnreadCount(userID int64) (int64, error) {
return (&dbr.Message{}).Count(d.db, &dbr.ConditionsT{
func (s *messageServant) GetUnreadCount(userID int64) (int64, error) {
return (&dbr.Message{}).Count(s.db, &dbr.ConditionsT{
"receiver_user_id": userID,
"is_read": dbr.MsgStatusUnread,
})
}
func (d *messageServant) GetMessageByID(id int64) (*core.Message, error) {
func (s *messageServant) GetMessageByID(id int64) (*core.Message, error) {
return (&dbr.Message{
Model: &dbr.Model{
ID: id,
},
}).Get(d.db)
}).Get(s.db)
}
func (d *messageServant) ReadMessage(message *core.Message) error {
func (s *messageServant) ReadMessage(message *core.Message) error {
message.IsRead = 1
return message.Update(d.db)
return message.Update(s.db)
}
func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(d.db, conditions, offset, limit)
func (s *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) {
messages, err := (&dbr.Message{}).List(s.db, conditions, offset, limit)
if err != nil {
return nil, err
}
@ -63,6 +63,6 @@ func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit
return mfs, nil
}
func (d *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) {
return (&dbr.Message{}).Count(d.db, conditions)
func (s *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) {
return (&dbr.Message{}).Count(s.db, conditions)
}

@ -25,49 +25,49 @@ func newWalletService(db *gorm.DB) core.WalletService {
}
}
func (d *walletServant) GetRechargeByID(id int64) (*core.WalletRecharge, error) {
func (s *walletServant) GetRechargeByID(id int64) (*core.WalletRecharge, error) {
recharge := &dbr.WalletRecharge{
Model: &dbr.Model{
ID: id,
},
}
return recharge.Get(d.db)
return recharge.Get(s.db)
}
func (d *walletServant) CreateRecharge(userId, amount int64) (*core.WalletRecharge, error) {
func (s *walletServant) CreateRecharge(userId, amount int64) (*core.WalletRecharge, error) {
recharge := &dbr.WalletRecharge{
UserID: userId,
Amount: amount,
}
return recharge.Create(d.db)
return recharge.Create(s.db)
}
func (d *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
func (s *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
statement := &dbr.WalletStatement{
UserID: userID,
}
return statement.List(d.db, &dbr.ConditionsT{
return statement.List(s.db, &dbr.ConditionsT{
"ORDER": "id DESC",
}, offset, limit)
}
func (d *walletServant) GetUserWalletBillCount(userID int64) (int64, error) {
func (s *walletServant) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &dbr.WalletStatement{
UserID: userID,
}
return statement.Count(d.db, &dbr.ConditionsT{})
return statement.Count(s.db, &dbr.ConditionsT{})
}
func (d *walletServant) HandleRechargeSuccess(recharge *core.WalletRecharge, tradeNo string) error {
func (s *walletServant) HandleRechargeSuccess(recharge *core.WalletRecharge, tradeNo string) error {
user, _ := (&dbr.User{
Model: &dbr.Model{
ID: recharge.UserID,
},
}).Get(d.db)
}).Get(s.db)
return d.db.Transaction(func(tx *gorm.DB) error {
return s.db.Transaction(func(tx *gorm.DB) error {
// 扣除金额
if err := tx.Model(user).Update("balance", gorm.Expr("balance + ?", recharge.Amount)).Error; err != nil {
// 返回任何错误都会回滚事务
@ -97,8 +97,8 @@ func (d *walletServant) HandleRechargeSuccess(recharge *core.WalletRecharge, tra
})
}
func (d *walletServant) HandlePostAttachmentBought(post *core.Post, user *core.User) error {
return d.db.Transaction(func(tx *gorm.DB) error {
func (s *walletServant) HandlePostAttachmentBought(post *core.Post, user *core.User) error {
return s.db.Transaction(func(tx *gorm.DB) error {
// 扣除金额
if err := tx.Model(user).Update("balance", gorm.Expr("balance - ?", post.AttachmentPrice)).Error; err != nil {
// 返回任何错误都会回滚事务
@ -133,7 +133,7 @@ func (d *walletServant) HandlePostAttachmentBought(post *core.Post, user *core.U
ID: post.UserID,
},
}
master, _ = master.Get(d.db)
master, _ = master.Get(s.db)
if err := tx.Model(master).Update("balance", gorm.Expr("balance + ?", income)).Error; err != nil {
// 返回任何错误都会回滚事务

@ -0,0 +1,59 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.AuthorizationManageService = (*authorizationManageServant)(nil)
)
type authorizationManageServant struct {
db *sqlx.DB
stmtIdx *sqlx.Stmt
stmtUpdateFriend *sqlx.Stmt
}
func (s *authorizationManageServant) IsAllow(user *core.User, action *core.Action) bool {
// TODO
debug.NotImplemented()
return false
}
func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet {
// TODO
debug.NotImplemented()
return nil
}
func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFilter {
// TODO
debug.NotImplemented()
return nil
}
func (s *authorizationManageServant) BeFriendIds(userId int64) ([]int64, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *authorizationManageServant) isFriend(userId int64, friendId int64) bool {
// TODO
debug.NotImplemented()
return false
}
func newAuthorizationManageService(db *sqlx.DB) core.AuthorizationManageService {
return &authorizationManageServant{
db: db,
stmtIdx: c(`SELECT * FROM @person WHERE first_name=?`),
stmtUpdateFriend: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,110 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.CommentService = (*commentServant)(nil)
_ core.CommentManageService = (*commentManageServant)(nil)
)
type commentServant struct {
db *sqlx.DB
stmtGetComments *sqlx.Stmt
stmtGetReply *sqlx.Stmt
}
type commentManageServant struct {
db *sqlx.DB
stmtDelComments *sqlx.Stmt
stmtAddComents *sqlx.Stmt
}
func (s *commentServant) GetComments(conditions *core.ConditionsT, offset, limit int) ([]*core.Comment, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *commentServant) GetCommentReplyByID(id int64) (*core.CommentReply, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *commentServant) GetCommentCount(conditions *core.ConditionsT) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*core.CommentContent, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentReplyFormated, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *commentManageServant) DeleteComment(comment *core.Comment) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *commentManageServant) CreateComment(comment *core.Comment) (*core.Comment, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *commentManageServant) CreateCommentReply(reply *core.CommentReply) (*core.CommentReply, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *commentManageServant) DeleteCommentReply(reply *core.CommentReply) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *commentManageServant) CreateCommentContent(content *core.CommentContent) (*core.CommentContent, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func newCommentService(db *sqlx.DB) core.CommentService {
return &commentServant{
db: db,
stmtGetComments: c(`SELECT * FROM @person WHERE first_name=?`),
stmtGetReply: c(`SELECT * FROM @person WHERE first_name=?`),
}
}
func newCommentManageService(db *sqlx.DB) core.CommentManageService {
return &commentManageServant{
db: db,
stmtAddComents: c(`SELECT * FROM @person WHERE first_name=?`),
stmtDelComments: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,65 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.ContactManageService = (*contactManageServant)(nil)
)
type contactManageServant struct {
db *sqlx.DB
stmtAddFriend *sqlx.Stmt
stmtDelFriend *sqlx.Stmt
}
func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, greetings string) (err error) {
// TODO
debug.NotImplemented()
return nil
}
func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err error) {
// TODO
debug.NotImplemented()
return nil
}
func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err error) {
// TODO
debug.NotImplemented()
return nil
}
func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err error) {
// TODO
debug.NotImplemented()
return nil
}
func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*core.ContactList, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool {
// TODO
debug.NotImplemented()
return false
}
func newContactManageService(db *sqlx.DB) core.ContactManageService {
return &contactManageServant{
db: db,
stmtAddFriend: c(`SELECT * FROM @person WHERE first_name=?`),
stmtDelFriend: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,54 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.IndexPostsService = (*indexPostsServant)(nil)
_ core.IndexPostsService = (*simpleIndexPostsServant)(nil)
)
type indexPostsServant struct {
db *sqlx.DB
stmtIndex *sqlx.Stmt
}
type simpleIndexPostsServant struct {
db *sqlx.DB
stmtIndex *sqlx.Stmt
}
// IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的
func (s *indexPostsServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
// simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数
func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func newIndexPostsService(db *sqlx.DB) core.IndexPostsService {
return &indexPostsServant{
db: db,
stmtIndex: c(`SELECT * FROM @person WHERE first_name=?`),
}
}
func newSimpleIndexPostsService(db *sqlx.DB) core.IndexPostsService {
return &simpleIndexPostsServant{
db: db,
stmtIndex: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,67 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.MessageService = (*messageServant)(nil)
)
type messageServant struct {
db *sqlx.DB
stmtAddMsg *sqlx.Stmt
stmtGetMsg *sqlx.Stmt
stmtReadMsg *sqlx.Stmt
}
func (s *messageServant) CreateMessage(msg *core.Message) (*core.Message, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *messageServant) GetUnreadCount(userID int64) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func (s *messageServant) GetMessageByID(id int64) (*core.Message, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *messageServant) ReadMessage(message *core.Message) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func newMessageService(db *sqlx.DB) core.MessageService {
return &messageServant{
db: db,
stmtAddMsg: c(`SELECT * FROM @person WHERE first_name=?`),
stmtGetMsg: c(`SELECT * FROM @person WHERE first_name=?`),
stmtReadMsg: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -1,23 +1,86 @@
// Copyright 2022 ROC. All rights reserved.
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
// Core service implement base sqlx+mysql. All sub-service
// will declare here and provide initial function.
package sakila
import (
"github.com/Masterminds/semver/v3"
"github.com/alimy/cfg"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao/cache"
"github.com/rocboss/paopao-ce/internal/dao/security"
"github.com/sirupsen/logrus"
)
var (
_ core.DataService = (*dataServant)(nil)
_ core.VersionInfo = (*dataServant)(nil)
)
type dataServant struct {
core.IndexPostsService
core.WalletService
core.MessageService
core.TopicService
core.TweetService
core.TweetManageService
core.TweetHelpService
core.CommentService
core.CommentManageService
core.UserManageService
core.ContactManageService
core.SecurityService
core.AttachmentCheckService
}
func NewDataService() (core.DataService, core.VersionInfo) {
logrus.Fatal("not support now")
return nil, nil
// initialize CacheIndex if needed
var (
c core.CacheIndexService
v core.VersionInfo
)
db := sqlxDB()
pvs := security.NewPhoneVerifyService()
i := newIndexPostsService(db)
if cfg.If("SimpleCacheIndex") {
i = newSimpleIndexPostsService(db)
c, v = cache.NewSimpleCacheIndexService(i)
} else if cfg.If("BigCacheIndex") {
a := newAuthorizationManageService(db)
c, v = cache.NewBigCacheIndexService(i, a)
} else {
c, v = cache.NewNoneCacheIndexService(i)
}
logrus.Infof("use %s as cache index service by version: %s", v.Name(), v.Version())
ds := &dataServant{
IndexPostsService: c,
WalletService: newWalletService(db),
MessageService: newMessageService(db),
TopicService: newTopicService(db),
TweetService: newTweetService(db),
TweetManageService: newTweetManageService(db, c),
TweetHelpService: newTweetHelpService(db),
CommentService: newCommentService(db),
CommentManageService: newCommentManageService(db),
UserManageService: newUserManageService(db),
ContactManageService: newContactManageService(db),
SecurityService: newSecurityService(db, pvs),
AttachmentCheckService: security.NewAttachmentCheckService(),
}
return ds, ds
}
func NewAuthorizationManageService() core.AuthorizationManageService {
logrus.Fatal("not support now")
return nil
return newAuthorizationManageService(sqlxDB())
}
func (s *dataServant) Name() string {
return "Sqlx"
}
func (s *dataServant) Version() *semver.Version {
return semver.MustParse("v0.1.0")
}

@ -0,0 +1,52 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.SecurityService = (*securityServant)(nil)
)
type securityServant struct {
db *sqlx.DB
phoneVerify core.PhoneVerifyService
stmtAddCaptcha *sqlx.Stmt
stmtGetCaptcha *sqlx.Stmt
}
// GetLatestPhoneCaptcha 获取最新短信验证码
func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*core.Captcha, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
// UsePhoneCaptcha 更新短信验证码
func (s *securityServant) UsePhoneCaptcha(captcha *core.Captcha) error {
// TODO
debug.NotImplemented()
return nil
}
// SendPhoneCaptcha 发送短信验证码
func (s *securityServant) SendPhoneCaptcha(phone string) error {
// TODO
debug.NotImplemented()
return nil
}
func newSecurityService(db *sqlx.DB, phoneVerify core.PhoneVerifyService) core.SecurityService {
return &securityServant{
db: db,
phoneVerify: phoneVerify,
stmtAddCaptcha: c(`SELECT * FROM @person WHERE first_name=?`),
stmtGetCaptcha: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,52 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
// Core service implement base sqlx+mysql. All sub-service
// will declare here and provide initial function.
package sakila
import (
"strings"
"sync"
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/sirupsen/logrus"
)
var (
_db *sqlx.DB
_once sync.Once
)
func sqlxDB() *sqlx.DB {
_once.Do(func() {
_db = conf.MustSqlxDB()
})
return _db
}
func c(query string) *sqlx.Stmt {
db := sqlxDB()
stmt, err := db.Preparex(db.Rebind(t(query)))
if err != nil {
logrus.Fatalf("prepare query(%s) error: %s", query, err)
}
return stmt
}
func n(query string) *sqlx.NamedStmt {
db := sqlxDB()
stmt, err := db.PrepareNamed(t(query))
if err != nil {
logrus.Fatalf("prepare named query(%s) error: %s", query, err)
}
return stmt
}
// t repace table prefix for query
func t(query string) string {
return strings.Replace(query, "@", conf.DatabaseSetting.TablePrefix, -1)
}

@ -0,0 +1,55 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.TopicService = (*topicServant)(nil)
)
type topicServant struct {
db *sqlx.DB
stmtAddTag *sqlx.Stmt
stmtDelTag *sqlx.Stmt
stmtListTag *sqlx.Stmt
}
func (s *topicServant) CreateTag(tag *core.Tag) (*core.Tag, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *topicServant) DeleteTag(tag *core.Tag) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *topicServant) GetTags(conditions *core.ConditionsT, offset, limit int) ([]*core.Tag, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *topicServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func newTopicService(db *sqlx.DB) core.TopicService {
return &topicServant{
db: db,
stmtAddTag: c(`SELECT * FROM @person WHERE first_name=?`),
stmtDelTag: c(`SELECT * FROM @person WHERE first_name=?`),
stmtListTag: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,257 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/debug"
"gorm.io/gorm"
)
var (
_ core.TweetService = (*tweetServant)(nil)
_ core.TweetManageService = (*tweetManageServant)(nil)
_ core.TweetHelpService = (*tweetHelpServant)(nil)
)
type tweetServant struct {
db *sqlx.DB
stmtGetTweet *sqlx.Stmt
stmtListTweet *sqlx.Stmt
stmtListStar *sqlx.Stmt
}
type tweetManageServant struct {
db *sqlx.DB
cacheIndex core.CacheIndexService
stmtAddTweet *sqlx.Stmt
stmtDelTweet *sqlx.Stmt
stmtStickTweet *sqlx.Stmt
}
type tweetHelpServant struct {
db *sqlx.DB
stmtAddTag *sqlx.Stmt
stmtDelTag *sqlx.Stmt
stmtListTag *sqlx.Stmt
}
// MergePosts post数据整合
func (s *tweetHelpServant) MergePosts(posts []*core.Post) ([]*core.PostFormated, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
// RevampPosts post数据整形修复
func (s *tweetHelpServant) RevampPosts(posts []*core.PostFormated) ([]*core.PostFormated, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*dbr.PostContent, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*core.PostCollection, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) DeletePostCollection(p *core.PostCollection) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *tweetManageServant) CreatePostContent(content *core.PostContent) (*core.PostContent, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) CreateAttachment(attachment *core.Attachment) (*core.Attachment, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) CreatePost(post *core.Post) (*core.Post, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) LockPost(post *core.Post) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *tweetManageServant) StickPost(post *core.Post) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *tweetManageServant) VisiblePost(post *core.Post, visibility core.PostVisibleT) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *tweetManageServant) UpdatePost(post *core.Post) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*core.PostStar, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetManageServant) DeletePostStar(p *core.PostStar) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetPosts(conditions *core.ConditionsT, offset, limit int) ([]*core.Post, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetPostCount(conditions *core.ConditionsT) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*core.PostStar, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*core.PostCollection, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*core.PostCollection, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*core.PostAttachmentBill, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*core.PostContent, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *tweetServant) GetPostContentByID(id int64) (*core.PostContent, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func newTweetService(db *sqlx.DB) core.TweetService {
return &tweetServant{
db: db,
stmtGetTweet: c(`SELECT * FROM @person WHERE first_name=?`),
stmtListTweet: c(`SELECT * FROM @person WHERE first_name=?`),
stmtListStar: c(`SELECT * FROM @person WHERE first_name=?`),
}
}
func newTweetManageService(db *sqlx.DB, cacheIndex core.CacheIndexService) core.TweetManageService {
return &tweetManageServant{
db: db,
cacheIndex: cacheIndex,
stmtAddTweet: c(`SELECT * FROM @person WHERE first_name=?`),
stmtDelTweet: c(`SELECT * FROM @person WHERE first_name=?`),
stmtStickTweet: c(`SELECT * FROM @person WHERE first_name=?`),
}
}
func newTweetHelpService(db *sqlx.DB) core.TweetHelpService {
return &tweetHelpServant{
db: db,
stmtAddTag: c(`SELECT * FROM @person WHERE first_name=?`),
stmtDelTag: c(`SELECT * FROM @person WHERE first_name=?`),
stmtListTag: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,79 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.UserManageService = (*userManageServant)(nil)
)
type userManageServant struct {
db *sqlx.DB
stmtAddUser *sqlx.Stmt
stmtUpdateUser *sqlx.Stmt
stmtGetUser *sqlx.Stmt
}
func (s *userManageServant) GetUserByID(id int64) (*core.User, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *userManageServant) GetUserByUsername(username string) (*core.User, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *userManageServant) GetUserByPhone(phone string) (*core.User, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *userManageServant) GetUsersByIDs(ids []int64) ([]*core.User, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *userManageServant) GetUsersByKeyword(keyword string) ([]*core.User, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *userManageServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *userManageServant) CreateUser(user *core.User) (*core.User, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *userManageServant) UpdateUser(user *core.User) error {
// TODO
debug.NotImplemented()
return nil
}
func newUserManageService(db *sqlx.DB) core.UserManageService {
return &userManageServant{
db: db,
stmtAddUser: c(`SELECT * FROM @person WHERE first_name=?`),
stmtUpdateUser: c(`SELECT * FROM @person WHERE first_name=?`),
stmtGetUser: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -0,0 +1,66 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package sakila
import (
"github.com/jmoiron/sqlx"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/debug"
)
var (
_ core.WalletService = (*walletServant)(nil)
)
type walletServant struct {
db *sqlx.DB
stmtAddRecharge *sqlx.Stmt
stmtGetRecharge *sqlx.Stmt
stmtGetBills *sqlx.Stmt
}
func (s *walletServant) GetRechargeByID(id int64) (*core.WalletRecharge, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *walletServant) CreateRecharge(userId, amount int64) (*core.WalletRecharge, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
// TODO
debug.NotImplemented()
return nil, nil
}
func (s *walletServant) GetUserWalletBillCount(userID int64) (int64, error) {
// TODO
debug.NotImplemented()
return 0, nil
}
func (s *walletServant) HandleRechargeSuccess(recharge *core.WalletRecharge, tradeNo string) error {
// TODO
debug.NotImplemented()
return nil
}
func (s *walletServant) HandlePostAttachmentBought(post *core.Post, user *core.User) error {
// TODO
debug.NotImplemented()
return nil
}
func newWalletService(db *sqlx.DB) core.WalletService {
return &walletServant{
db: db,
stmtAddRecharge: c(`SELECT * FROM @person WHERE first_name=?`),
stmtGetRecharge: c(`SELECT * FROM @person WHERE first_name=?`),
stmtGetBills: c(`SELECT * FROM @person WHERE first_name=?`),
}
}

@ -42,9 +42,9 @@ func Run() {
db, err = sql.Open("mysql", conf.MysqlSetting.Dsn()+"&multiStatements=true")
} else if cfg.If("PostgreSQL") || cfg.If("Postgres") {
dbName = (*conf.PostgresSetting)["DBName"]
db, err = sql.Open("postgres", conf.PostgresSetting.Dsn())
db, err = sql.Open("pgx", conf.PostgresSetting.Dsn())
} else if cfg.If("Sqlite3") {
db, err = conf.OpenSqlite3()
_, db, err = conf.OpenSqlite3()
} else {
dbName = conf.MysqlSetting.DBName
db, err = sql.Open("mysql", conf.MysqlSetting.Dsn())

@ -20,9 +20,7 @@ import (
"github.com/rocboss/paopao-ce/pkg/xerror"
)
type BaseServant struct {
// TODO
}
type BaseServant types.Empty
type DaoServant struct {
Redis *redis.Client

@ -6,6 +6,8 @@ package broker
import (
"github.com/alimy/cfg"
"github.com/go-redis/redis/v8"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao"
"github.com/sirupsen/logrus"
@ -15,6 +17,7 @@ var (
ds core.DataService
ts core.TweetSearchService
oss core.ObjectStorageService
redisClient *redis.Client
DisablePhoneVerify bool
)
@ -22,6 +25,7 @@ func Initialize() {
ds = dao.DataService()
ts = dao.TweetSearchService()
oss = dao.ObjectStorageService()
redisClient = conf.MustRedis()
DisablePhoneVerify = !cfg.If("Sms")
}

@ -9,7 +9,6 @@ import (
"time"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/convert"
"github.com/rocboss/paopao-ce/pkg/errcode"
@ -31,7 +30,7 @@ func CreateWhisper(c *gin.Context, msg *core.Message) (*core.Message, error) {
whisperKey := fmt.Sprintf("WhisperTimes:%d", msg.SenderUserID)
// 今日频次限制
if res, _ := conf.Redis.Get(c, whisperKey).Result(); convert.StrTo(res).MustInt() >= MAX_WHISPER_NUM_DAILY {
if res, _ := redisClient.Get(c, whisperKey).Result(); convert.StrTo(res).MustInt() >= MAX_WHISPER_NUM_DAILY {
return nil, errcode.TooManyWhisperNum
}
@ -42,11 +41,11 @@ func CreateWhisper(c *gin.Context, msg *core.Message) (*core.Message, error) {
}
// 写入当日(自然日)计数缓存
conf.Redis.Incr(c, whisperKey).Result()
redisClient.Incr(c, whisperKey).Result()
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
conf.Redis.Expire(c, whisperKey, endTime.Sub(currentTime))
redisClient.Expire(c, whisperKey, endTime.Sub(currentTime))
return msg, err
}

@ -501,8 +501,8 @@ func DeleteSearchPost(post *core.Post) error {
}
func PushPostsToSearch(c *gin.Context) {
if ok, _ := conf.Redis.SetNX(c, "JOB_PUSH_TO_SEARCH", 1, time.Hour).Result(); ok {
defer conf.Redis.Del(c, "JOB_PUSH_TO_SEARCH")
if ok, _ := redisClient.SetNX(c, "JOB_PUSH_TO_SEARCH", 1, time.Hour).Result(); ok {
defer redisClient.Del(c, "JOB_PUSH_TO_SEARCH")
splitNum := 1000
totalRows, _ := GetPostCount(&core.ConditionsT{

@ -13,7 +13,6 @@ import (
"github.com/gin-gonic/gin"
"github.com/gofrs/uuid"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/convert"
"github.com/rocboss/paopao-ce/pkg/errcode"
@ -102,7 +101,7 @@ func DoLogin(ctx *gin.Context, param *AuthRequest) (*core.User, error) {
}
if user.Model != nil && user.ID > 0 {
if errTimes, err := conf.Redis.Get(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID)).Result(); err == nil {
if errTimes, err := redisClient.Get(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID)).Result(); err == nil {
if convert.StrTo(errTimes).MustInt() >= _MaxLoginErrTimes {
return nil, errcode.TooManyLoginError
}
@ -116,14 +115,14 @@ func DoLogin(ctx *gin.Context, param *AuthRequest) (*core.User, error) {
}
// 清空登录计数
conf.Redis.Del(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID))
redisClient.Del(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID))
return user, nil
}
// 登录错误计数
_, err = conf.Redis.Incr(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID)).Result()
_, err = redisClient.Incr(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID)).Result()
if err == nil {
conf.Redis.Expire(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID), time.Hour).Result()
redisClient.Expire(ctx, fmt.Sprintf("%s:%d", _LoginErrKey, user.ID), time.Hour).Result()
}
return nil, errcode.UnauthorizedAuthFailed
@ -435,12 +434,12 @@ func SendPhoneCaptcha(ctx *gin.Context, phone string) error {
}
// 写入计数缓存
conf.Redis.Incr(ctx, "PaoPaoSmsCaptcha:"+phone).Result()
redisClient.Incr(ctx, "PaoPaoSmsCaptcha:"+phone).Result()
currentTime := time.Now()
endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location())
conf.Redis.Expire(ctx, "PaoPaoSmsCaptcha:"+phone, endTime.Sub(currentTime))
redisClient.Expire(ctx, "PaoPaoSmsCaptcha:"+phone, endTime.Sub(currentTime))
return nil
}

@ -5,11 +5,11 @@
package broker
import (
"github.com/rocboss/paopao-ce/internal/core"
"time"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/pkg/errcode"
)
@ -26,7 +26,7 @@ func CreateRecharge(userID, amount int64) (*core.WalletRecharge, error) {
}
func FinishRecharge(ctx *gin.Context, id int64, tradeNo string) error {
if ok, _ := conf.Redis.SetNX(ctx, "PaoPaoRecharge:"+tradeNo, 1, time.Second*5).Result(); ok {
if ok, _ := redisClient.SetNX(ctx, "PaoPaoRecharge:"+tradeNo, 1, time.Second*5).Result(); ok {
recharge, err := ds.GetRechargeByID(id)
if err != nil {
return err
@ -36,7 +36,7 @@ func FinishRecharge(ctx *gin.Context, id int64, tradeNo string) error {
// 标记为已付款
err := ds.HandleRechargeSuccess(recharge, tradeNo)
defer conf.Redis.Del(ctx, "PaoPaoRecharge:"+tradeNo)
defer redisClient.Del(ctx, "PaoPaoRecharge:"+tradeNo)
if err != nil {
return err

@ -6,6 +6,7 @@ package api
import (
"github.com/alimy/cfg"
"github.com/go-redis/redis/v8"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/dao"
@ -14,11 +15,13 @@ import (
)
var (
redisClient *redis.Client
alipayClient *alipay.Client
objectStorage core.ObjectStorageService
)
func Initialize() {
redisClient = conf.MustRedis()
objectStorage = dao.ObjectStorageService()
if cfg.If("Alipay") {

@ -14,7 +14,6 @@ import (
"github.com/afocus/captcha"
"github.com/gin-gonic/gin"
"github.com/gofrs/uuid"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/servants/web/assets"
"github.com/rocboss/paopao-ce/internal/servants/web/broker"
@ -65,7 +64,7 @@ func GetCaptcha(c *gin.Context) {
key := util.EncodeMD5(uuid.Must(uuid.NewV4()).String())
// 五分钟有效期
conf.Redis.SetEX(c, "PaoPaoCaptcha:"+key, password, time.Minute*5)
redisClient.SetEX(c, "PaoPaoCaptcha:"+key, password, time.Minute*5)
response := app.NewResponse(c)
response.ToResponse(gin.H{
@ -85,14 +84,14 @@ func PostCaptcha(c *gin.Context) {
}
// 验证图片验证码
if res, err := conf.Redis.Get(c.Request.Context(), "PaoPaoCaptcha:"+param.ImgCaptchaID).Result(); err != nil || res != param.ImgCaptcha {
if res, err := redisClient.Get(c.Request.Context(), "PaoPaoCaptcha:"+param.ImgCaptchaID).Result(); err != nil || res != param.ImgCaptcha {
response.ToErrorResponse(errcode.ErrorCaptchaPassword)
return
}
conf.Redis.Del(c.Request.Context(), "PaoPaoCaptcha:"+param.ImgCaptchaID).Result()
redisClient.Del(c.Request.Context(), "PaoPaoCaptcha:"+param.ImgCaptchaID).Result()
// 今日频次限制
if res, _ := conf.Redis.Get(c.Request.Context(), "PaoPaoSmsCaptcha:"+param.Phone).Result(); convert.StrTo(res).MustInt() >= MAX_PHONE_CAPTCHA {
if res, _ := redisClient.Get(c.Request.Context(), "PaoPaoSmsCaptcha:"+param.Phone).Result(); convert.StrTo(res).MustInt() >= MAX_PHONE_CAPTCHA {
response.ToErrorResponse(errcode.TooManyPhoneCaptchaSend)
return
}

@ -19,7 +19,7 @@ import (
func RouteWeb(e *gin.Engine) {
oss := dao.ObjectStorageService()
ds := &base.DaoServant{
Redis: conf.Redis,
Redis: conf.MustRedis(),
Ds: dao.DataService(),
Ts: dao.TweetSearchService(),
}

@ -33,7 +33,7 @@ func (s *adminService) Version() *semver.Version {
}
func (s *adminService) OnInit() error {
s.registerRoute(servants.RegisterAdminServants)
s.registerRoute(s, servants.RegisterAdminServants)
return nil
}

@ -33,7 +33,7 @@ func (s *botService) Version() *semver.Version {
}
func (s *botService) OnInit() error {
s.registerRoute(servants.RegisterBotServants)
s.registerRoute(s, servants.RegisterBotServants)
return nil
}

@ -31,7 +31,7 @@ func (s *docsService) Version() *semver.Version {
}
func (s *docsService) OnInit() error {
s.registerRoute(servants.RegisterDocsServants)
s.registerRoute(s, servants.RegisterDocsServants)
return nil
}

@ -31,7 +31,7 @@ func (s *frontendWebService) Version() *semver.Version {
}
func (s *frontendWebService) OnInit() error {
s.registerRoute(servants.RegisterFrontendWebServants)
s.registerRoute(s, servants.RegisterFrontendWebServants)
return nil
}

@ -23,32 +23,10 @@ type grpcServer struct {
}
func (s *grpcServer) start() error {
s.Lock()
if s.serverStatus == _statusServerStarted || s.serverStatus == _statusServerStoped {
return nil
}
oldStatus := s.serverStatus
s.serverStatus = _statusServerStarted
s.Unlock()
if err := s.server.Serve(s.listener); err != nil {
s.Lock()
s.serverStatus = oldStatus
s.Unlock()
return err
}
return nil
return s.server.Serve(s.listener)
}
func (s *grpcServer) stop() error {
s.Lock()
defer s.Unlock()
if s.serverStatus == _statusServerStoped || s.serverStatus == _statusServerInitilized {
return nil
}
s.server.Stop()
s.serverStatus = _statusServerStoped
return nil
}

@ -14,19 +14,17 @@ type baseGRPCService struct {
server *grpcServer
}
func (s *baseGRPCService) registerServer(h func(s *grpc.Server)) {
if s.server.status() != _statusServerStarted {
h(s.server.server)
}
func (s *baseGRPCService) registerServer(srv Service, h func(s *grpc.Server)) {
h(s.server.server)
s.server.addService(srv)
}
func (s *baseGRPCService) OnStart() error {
if err := s.server.start(); err != nil {
return err
}
// do nothing default
return nil
}
func (s *baseGRPCService) OnStop() error {
return s.server.stop()
// do nothing default
return nil
}

@ -24,34 +24,9 @@ type httpServer struct {
}
func (s *httpServer) start() error {
s.Lock()
if s.serverStatus == _statusServerStarted || s.serverStatus == _statusServerStoped {
return nil
}
oldStatus := s.serverStatus
s.serverStatus = _statusServerStarted
s.Unlock()
if err := s.server.ListenAndServe(); err != nil {
s.Lock()
s.serverStatus = oldStatus
s.Unlock()
return err
}
return nil
return s.server.ListenAndServe()
}
func (s *httpServer) stop() error {
s.Lock()
defer s.Unlock()
if s.serverStatus == _statusServerStoped || s.serverStatus == _statusServerInitilized {
return nil
}
if err := s.server.Shutdown(context.Background()); err != nil {
return err
}
s.serverStatus = _statusServerStoped
return nil
return s.server.Shutdown(context.Background())
}

@ -14,19 +14,17 @@ type baseHttpService struct {
server *httpServer
}
func (s *baseHttpService) registerRoute(h func(e *gin.Engine)) {
if s.server.status() != _statusServerStarted {
h(s.server.e)
}
func (s *baseHttpService) registerRoute(srv Service, h func(e *gin.Engine)) {
h(s.server.e)
s.server.addService(srv)
}
func (s *baseHttpService) OnStart() error {
if err := s.server.start(); err != nil {
return err
}
// do nothing default
return nil
}
func (s *baseHttpService) OnStop() error {
return s.server.stop()
// do nothing default
return nil
}

@ -32,7 +32,7 @@ func (s *localossService) Version() *semver.Version {
}
func (s *localossService) OnInit() error {
s.registerRoute(servants.RegisterLocalossServants)
s.registerRoute(s, servants.RegisterLocalossServants)
return nil
}

@ -33,7 +33,7 @@ func (s *mobileService) Version() *semver.Version {
}
func (s *mobileService) OnInit() error {
s.registerServer(servants.RegisterMobileServants)
s.registerServer(s, servants.RegisterMobileServants)
return nil
}

@ -4,7 +4,15 @@
package service
import "sync"
import (
"fmt"
"sync"
"github.com/fatih/color"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/pkg/util"
)
var (
httpServers = newServerPool[*httpServer]()
@ -12,17 +20,16 @@ var (
)
const (
_statusServerUnknow uint8 = iota
_statusServerInitilized
_statusServerStarted
_statusServerStoped
actOnStart byte = iota
actOnStop
actStart
actStop
)
type server interface {
status() uint8
setStatus(uint8)
start() error
stop() error
services() []Service
}
type serverPool[T server] struct {
@ -30,8 +37,7 @@ type serverPool[T server] struct {
}
type baseServer struct {
sync.RWMutex
serverStatus uint8
ss map[string]Service
}
func (p *serverPool[T]) from(addr string, newServer func() T) T {
@ -40,23 +46,60 @@ func (p *serverPool[T]) from(addr string, newServer func() T) T {
return s
}
s = newServer()
s.setStatus(_statusServerInitilized)
p.servers[addr] = s
return s
}
func (s *baseServer) setStatus(status uint8) {
s.RLock()
defer s.RUnlock()
func (p *serverPool[T]) startServer(wg *sync.WaitGroup, maxSidSize int) {
for _, srv := range p.servers {
wg.Add(1)
go func(t T) {
ss := t.services()
if len(ss) < 1 {
return
}
for _, s := range ss {
colorPrint(actOnStart, s.OnStart(), maxSidSize, s)
}
colorPrint(actStart, t.start(), maxSidSize, ss...)
// remember to done sync.WaitGroup
wg.Done()
}(srv)
}
}
func (p *serverPool[T]) stopServer(maxSidSize int) {
for _, srv := range p.servers {
ss := srv.services()
if len(ss) < 1 {
return
}
for _, s := range ss {
colorPrint(actOnStop, s.OnStop(), maxSidSize, s)
}
colorPrint(actStop, srv.stop(), maxSidSize, ss...)
}
}
s.serverStatus = status
func (p *serverPool[T]) allServices() (ss []Service) {
for _, srv := range p.servers {
ss = append(ss, srv.services()...)
}
return
}
func (s *baseServer) status() uint8 {
s.RLock()
defer s.RUnlock()
func (s *baseServer) addService(srv Service) {
if srv != nil {
sid := srv.Name() + "@" + srv.Version().String()
s.ss[sid] = srv
}
}
return s.serverStatus
func (s *baseServer) services() (ss []Service) {
for _, s := range s.ss {
ss = append(ss, s)
}
return
}
func newServerPool[T server]() *serverPool[T] {
@ -67,7 +110,81 @@ func newServerPool[T server]() *serverPool[T] {
func newBaseServe() *baseServer {
return &baseServer{
RWMutex: sync.RWMutex{},
serverStatus: _statusServerUnknow,
ss: make(map[string]Service),
}
}
func checkServices() (int, int) {
var ss []Service
ss = append(ss, httpServers.allServices()...)
ss = append(ss, grpcServers.allServices()...)
return len(ss), maxSidSize(ss)
}
// maxSidSize max service id string length
func maxSidSize(ss []Service) int {
length := 0
for _, s := range ss {
size := len(s.Name() + "@" + s.Version().String())
if size > length {
length = size
}
}
return length
}
func colorPrint(act byte, err error, l int, ss ...Service) {
s := ss[0]
switch act {
case actOnStart:
if err == nil {
fmt.Fprintf(color.Output, "%s [start] - %s", util.SidStr(s.Name(), s.Version(), l), s)
} else {
fmt.Fprintf(color.Output, "%s [start] - run OnStart error: %s\n", util.SidStr(s.Name(), s.Version(), l), err)
}
case actOnStop:
if err == nil {
fmt.Fprintf(color.Output, "%s [stop] - finish...\n", util.SidStr(s.Name(), s.Version(), l))
} else {
fmt.Fprintf(color.Output, "%s [stop] - run OnStop error: %s\n", util.SidStr(s.Name(), s.Version(), l), err)
}
case actStart:
if err != nil {
for _, s = range ss {
fmt.Fprintf(color.Output, "%s [start] - starting server occurs error: %s\n", util.SidStr(s.Name(), s.Version(), l), err)
}
}
case actStop:
if err != nil {
for _, s = range ss {
fmt.Fprintf(color.Output, "%s [stop] - stopping server occurs error: %s\n", util.SidStr(s.Name(), s.Version(), l), err)
}
}
}
}
// Start start all servers
func Start(wg *sync.WaitGroup) {
srvSize, maxSidSize := checkServices()
if srvSize < 1 {
return
}
// some initialize for server engine
gin.SetMode(conf.RunMode())
// start servers
httpServers.startServer(wg, maxSidSize)
grpcServers.startServer(wg, maxSidSize)
}
// Stop stop all servers
func Stop() {
srvSize, maxSidSize := checkServices()
if srvSize < 1 {
return
}
// stop servers
httpServers.stopServer(maxSidSize)
grpcServers.stopServer(maxSidSize)
}

@ -34,8 +34,8 @@ func (baseService) String() string {
return ""
}
// InitService Initial service
func InitService() []Service {
// MustInitService Initial service
func MustInitService() []Service {
ss := newService()
for _, s := range ss {
if err := s.OnInit(); err != nil {
@ -45,18 +45,6 @@ func InitService() []Service {
return ss
}
// MaxSidSize max service id string length
func MaxSidSize(ss []Service) int {
length := 0
for _, s := range ss {
size := len(s.Name() + "@" + s.Version().String())
if size > length {
length = size
}
}
return length
}
func newService() (ss []Service) {
// add all service if declared in features on config.yaml
cfg.In(cfg.Actions{

@ -33,7 +33,7 @@ func (s *spaceXService) Version() *semver.Version {
}
func (s *spaceXService) OnInit() error {
s.registerRoute(servants.RegisterSpaceXServants)
s.registerRoute(s, servants.RegisterSpaceXServants)
return nil
}

@ -33,7 +33,7 @@ func (s *webService) Version() *semver.Version {
}
func (s *webService) OnInit() error {
s.registerRoute(servants.RegisterWebServants)
s.registerRoute(s, servants.RegisterWebServants)
return nil
}
@ -88,7 +88,6 @@ func newWebService() Service {
},
}
})
return &webService{
baseHttpService: &baseHttpService{
server: server,

@ -31,7 +31,7 @@ func (s *oldWebService) Version() *semver.Version {
}
func (s *oldWebService) OnInit() error {
s.registerRoute(routers.RegisterRoute)
s.registerRoute(s, routers.RegisterRoute)
return nil
}

@ -14,7 +14,6 @@ import (
"syscall"
"github.com/fatih/color"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/service"
@ -53,52 +52,29 @@ func flagParse() {
flag.Parse()
}
func runService(wg *sync.WaitGroup, ss []service.Service) {
gin.SetMode(conf.RunMode())
fmt.Fprintf(color.Output, "\nstarting run service...\n\n")
l := service.MaxSidSize(ss)
for _, s := range ss {
go func(s service.Service) {
fmt.Fprintf(color.Output, "%s [start] - %s", util.SidStr(s.Name(), s.Version(), l), s)
if err := s.OnStart(); err != nil {
fmt.Fprintf(color.Output, "%s [start] - occurs on error: %s\n", util.SidStr(s.Name(), s.Version(), l), err)
}
wg.Done()
}(s)
}
}
func runManage(wg *sync.WaitGroup, ss []service.Service) {
quit := make(chan os.Signal, 1)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
fmt.Fprintf(color.Output, "\nshutting down server...\n\n")
l := service.MaxSidSize(ss)
for _, s := range ss {
if err := s.OnStop(); err != nil {
fmt.Fprintf(color.Output, "%s [stop] - occurs on error: %s\n", util.SidStr(s.Name(), s.Version(), l), err)
}
fmt.Fprintf(color.Output, "%s [stop] - finish...\n", util.SidStr(s.Name(), s.Version(), l))
}
wg.Done()
}
func main() {
util.PrintHelloBanner(debug.VersionInfo())
if ss := service.InitService(); len(ss) > 0 {
wg := &sync.WaitGroup{}
wg.Add(len(ss) + 1)
runService(wg, ss)
go runManage(wg, ss)
wg.Wait()
} else {
ss := service.MustInitService()
if len(ss) < 1 {
fmt.Fprintln(color.Output, "no service need start so just exit")
return
}
wg := &sync.WaitGroup{}
// start services
fmt.Fprintf(color.Output, "\nstarting run service...\n\n")
service.Start(wg)
// graceful stop services
wg.Add(1)
go func() {
quit := make(chan os.Signal, 1)
// kill (no param) default send syscall.SIGTERM
// kill -2 is syscall.SIGINT
// kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
fmt.Fprintf(color.Output, "\nshutting down server...\n\n")
service.Stop()
wg.Done()
}()
wg.Wait()
}

@ -0,0 +1,17 @@
// Copyright 2023 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package debug
import (
"github.com/sirupsen/logrus"
)
func TODO() {
logrus.Fatalln("in todo progress")
}
func NotImplemented() {
logrus.Fatalln("not implemented")
}
Loading…
Cancel
Save