From e847aa4d6effc36c31b9c976bffeb3fc1e9240d9 Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 20 Nov 2024 23:22:32 +0800 Subject: [PATCH] chore: improve template (#161) * chore: improve template * chore: improve template --- cmd/eagle/README.md | 4 +- cmd/eagle/go.mod | 19 ++- cmd/eagle/go.sum | 25 ---- cmd/eagle/internal/cache/add/add.go | 2 +- cmd/eagle/internal/cache/add/cache.go | 3 +- cmd/eagle/internal/cache/add/template.go | 18 +-- cmd/eagle/internal/handler/add/add.go | 6 +- cmd/eagle/internal/handler/add/handler.go | 3 +- cmd/eagle/internal/handler/add/template.go | 50 +++++++- cmd/eagle/internal/proto/server/server.go | 2 +- cmd/eagle/internal/repo/add/repo.go | 3 +- cmd/eagle/internal/repo/add/template.go | 130 ++++++++++++++------- cmd/eagle/internal/service/add/add.go | 2 +- cmd/eagle/internal/service/add/service.go | 3 +- cmd/eagle/internal/service/add/template.go | 8 +- cmd/eagle/main.go | 2 +- go.mod | 2 +- 17 files changed, 180 insertions(+), 102 deletions(-) diff --git a/cmd/eagle/README.md b/cmd/eagle/README.md index 4bf54f9964..a4b6083fdf 100644 --- a/cmd/eagle/README.md +++ b/cmd/eagle/README.md @@ -9,7 +9,7 @@ ## Go 版本要求 -GO >= 1.13 +GO >= 1.18 ## 脚手架工具获取 @@ -30,7 +30,7 @@ export GOPROXY=https://mirrors.aliyun.com/goproxy/,direct 下载 ```bash -go get -u -v github.com/go-eagle/eagle/cmd/eagle +go install github.com/go-eagle/eagle/cmd/eagle@latest ``` windows: diff --git a/cmd/eagle/go.mod b/cmd/eagle/go.mod index be3bc830b4..98b6d7f7c8 100644 --- a/cmd/eagle/go.mod +++ b/cmd/eagle/go.mod @@ -1,6 +1,6 @@ module github.com/go-eagle/eagle/cmd/eagle -go 1.16 +go 1.22 require ( github.com/AlecAivazis/survey/v2 v2.2.12 @@ -8,9 +8,22 @@ require ( github.com/emicklei/proto v1.9.1 github.com/fatih/color v1.9.0 github.com/jedib0t/go-pretty/v6 v6.2.7 - github.com/mattn/go-colorable v0.1.6 // indirect github.com/spf13/cobra v1.1.3 - golang.org/x/crypto v0.17.0 // indirect golang.org/x/mod v0.8.0 +) + +require ( + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect + github.com/mattn/go-colorable v0.1.6 // indirect + github.com/mattn/go-isatty v0.0.12 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect + github.com/rivo/uniseg v0.2.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/crypto v0.17.0 // indirect + golang.org/x/sys v0.15.0 // indirect + golang.org/x/term v0.15.0 // indirect + golang.org/x/text v0.14.0 // indirect gopkg.in/yaml.v3 v3.0.0 // indirect ) diff --git a/cmd/eagle/go.sum b/cmd/eagle/go.sum index 151f25c6bd..e48fb3b63e 100644 --- a/cmd/eagle/go.sum +++ b/cmd/eagle/go.sum @@ -199,7 +199,6 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -212,7 +211,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -233,7 +231,6 @@ golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -250,10 +247,6 @@ golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -262,8 +255,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/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.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/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= @@ -283,27 +274,14 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= 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= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -325,9 +303,6 @@ golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= diff --git a/cmd/eagle/internal/cache/add/add.go b/cmd/eagle/internal/cache/add/add.go index b0b08f7a2d..4ea7c105bb 100644 --- a/cmd/eagle/internal/cache/add/add.go +++ b/cmd/eagle/internal/cache/add/add.go @@ -22,7 +22,7 @@ var ( ) func init() { - CmdAdd.Flags().StringVarP(&targetDir, "-target-dir", "t", "internal/cache", "generate target directory") + CmdAdd.Flags().StringVarP(&targetDir, "-target-dir", "t", "internal/dal/cache", "generate target directory") } func run(cmd *cobra.Command, args []string) { diff --git a/cmd/eagle/internal/cache/add/cache.go b/cmd/eagle/internal/cache/add/cache.go index e5e7a5b057..32dc5e00de 100644 --- a/cmd/eagle/internal/cache/add/cache.go +++ b/cmd/eagle/internal/cache/add/cache.go @@ -2,7 +2,6 @@ package add import ( "fmt" - "io/ioutil" "os" "path" @@ -41,5 +40,5 @@ func (c *Cache) Generate() error { if _, err := os.Stat(name); !os.IsNotExist(err) { return fmt.Errorf("%s already exists", c.Name) } - return ioutil.WriteFile(name, body, 0644) + return os.WriteFile(name, body, 0644) } diff --git a/cmd/eagle/internal/cache/add/template.go b/cmd/eagle/internal/cache/add/template.go index 0db44a3be5..cc591165fb 100644 --- a/cmd/eagle/internal/cache/add/template.go +++ b/cmd/eagle/internal/cache/add/template.go @@ -10,7 +10,7 @@ import ( const cacheTemplate = ` package cache -//go:generate mockgen -source=internal/cache/{{.UsName}}_cache.go -destination=internal/mock/{{.UsName}}_cache_mock.go -package mock +//go:generate mockgen -source=internal/dal/cache/{{.UsName}}_cache.go -destination=internal/mock/{{.UsName}}_cache_mock.go -package mock import ( "context" @@ -20,14 +20,15 @@ import ( "github.com/go-eagle/eagle/pkg/cache" "github.com/go-eagle/eagle/pkg/encoding" "github.com/go-eagle/eagle/pkg/log" - "github.com/go-eagle/eagle/pkg/redis" + "github.com/go-eagle/eagle/pkg/utils" + "github.com/redis/go-redis/v9" - "{{.ModName}}/internal/model" + "{{.ModName}}/internal/dal/db/model" ) -const ( +var ( // Prefix{{.Name}}CacheKey cache prefix - Prefix{{.Name}}CacheKey = "{{.ColonName}}:%d" + Prefix{{.Name}}CacheKey = utils.ConcatString(prefix, "{{.ColonName}}:%d") ) // {{.Name}}Cache define cache interface @@ -37,6 +38,7 @@ type {{.Name}}Cache interface { MultiGet{{.Name}}Cache(ctx context.Context, ids []int64) (map[string]*model.{{.Name}}Model, error) MultiSet{{.Name}}Cache(ctx context.Context, data []*model.{{.Name}}Model, duration time.Duration) error Del{{.Name}}Cache(ctx context.Context, id int64) error + SetCacheWithNotFound(ctx context.Context, id int64) error } // {{.LcName}}Cache define cache struct @@ -45,11 +47,11 @@ type {{.LcName}}Cache struct { } // New{{.Name}}Cache new a cache -func New{{.Name}}Cache() {{.Name}}Cache { +func New{{.Name}}Cache(rdb *redis.Client) {{.Name}}Cache { jsonEncoding := encoding.JSONEncoding{} cachePrefix := "" return &{{.LcName}}Cache{ - cache: cache.NewRedisCache(redis.RedisClient, cachePrefix, jsonEncoding, func() interface{} { + cache: cache.NewRedisCache(rdb, cachePrefix, jsonEncoding, func() interface{} { return &model.{{.Name}}Model{} }), } @@ -78,7 +80,7 @@ func (c *{{.LcName}}Cache) Get{{.Name}}Cache(ctx context.Context, id int64) (dat cacheKey := c.Get{{.Name}}CacheKey(id) err = c.cache.Get(ctx, cacheKey, &data) if err != nil { - log.WithContext(ctx).Warnf("get err from redis, err: %+v", err) + log.WithContext(ctx).Warnf("[cache] Get{{.Name}}Cache err from redis, err: %+v", err) return nil, err } return data, nil diff --git a/cmd/eagle/internal/handler/add/add.go b/cmd/eagle/internal/handler/add/add.go index c4da32bc7d..40637ae0dc 100644 --- a/cmd/eagle/internal/handler/add/add.go +++ b/cmd/eagle/internal/handler/add/add.go @@ -3,9 +3,9 @@ package add import ( "fmt" - "github.com/go-eagle/eagle/cmd/eagle/internal/utils" - "github.com/spf13/cobra" + + "github.com/go-eagle/eagle/cmd/eagle/internal/utils" ) // CmdCache represents the new command. @@ -25,7 +25,7 @@ var ( func init() { CmdAdd.Flags().StringVarP(&targetDir, "target-dir", "t", "internal/handler", "generate target directory") CmdAdd.Flags().StringVarP(&version, "version", "v", "v1", "handler version") - CmdAdd.Flags().StringVarP(&method, "method", "m", "get", "http method") + CmdAdd.Flags().StringVarP(&method, "method", "m", "GET", "http method, eg: GET, POST, PUT, PATCH, DELETE") } func run(cmd *cobra.Command, args []string) { diff --git a/cmd/eagle/internal/handler/add/handler.go b/cmd/eagle/internal/handler/add/handler.go index 55e37f7f17..74362b3fe9 100644 --- a/cmd/eagle/internal/handler/add/handler.go +++ b/cmd/eagle/internal/handler/add/handler.go @@ -2,7 +2,6 @@ package add import ( "fmt" - "io/ioutil" "os" "path" @@ -39,5 +38,5 @@ func (h *Handler) Generate() error { if _, err := os.Stat(name); !os.IsNotExist(err) { return fmt.Errorf("%s already exists", h.Name) } - return ioutil.WriteFile(name, body, 0644) + return os.WriteFile(name, body, 0644) } diff --git a/cmd/eagle/internal/handler/add/template.go b/cmd/eagle/internal/handler/add/template.go index feb7c82139..c145b91332 100644 --- a/cmd/eagle/internal/handler/add/template.go +++ b/cmd/eagle/internal/handler/add/template.go @@ -13,6 +13,10 @@ package v1 import ( "github.com/gin-gonic/gin" "github.com/go-eagle/eagle/pkg/app" + "github.com/go-eagle/eagle/pkg/errcode" + + "github.com/go-eagle/eagle-layout/internal/service" + "github.com/go-eagle/eagle-layout/internal/types" ) // {{.Name}} {{.LcName}} @@ -23,9 +27,51 @@ import ( // @Produce json // @Router /{{.UsName}} {{.Method}} func {{.Name}}(c *gin.Context) { - // here add your code + var req types.{{.Name}}Request + {{- if .Method eq "GET" }} + if err := c.ShouldBindQuery(&req); err != nil { + app.Error(c, errcode.ErrInvalidParam.WithDetails(err.Error())) + return + } + {{- end }} + + {{- if .Method eq "POST" }} + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, errcode.ErrInvalidParam.WithDetails(err.Error())) + return + } + {{- end }} + + {{- if .Method eq "PUT" }} + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, errcode.ErrInvalidParam.WithDetails(err.Error())) + return + } + {{- end }} + + {{- if .Method eq "PATCH" }} + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, errcode.ErrInvalidParam.WithDetails(err.Error())) + return + } + {{- end }} + + {{- if .Method eq "DELETE" }} + if err := c.ShouldBindJSON(&req); err != nil { + app.Error(c, errcode.ErrInvalidParam.WithDetails(err.Error())) + return + } + {{- end }} + + var ret any + // change to your service + // ret, err := service.GreeterSvc.Hello(c, req.Name) + // if err != nil { + // app.Error(c, err) + // return + // } - app.Success(c, gin.H{}) + app.Success(c, ret) } ` diff --git a/cmd/eagle/internal/proto/server/server.go b/cmd/eagle/internal/proto/server/server.go index 81a2f12218..d5c4eae051 100644 --- a/cmd/eagle/internal/proto/server/server.go +++ b/cmd/eagle/internal/proto/server/server.go @@ -74,7 +74,7 @@ func run(cmd *cobra.Command, args []string) { } for _, s := range res { serviceName := strings.Replace(strings.ToLower(s.Service), "service", "", 1) - to := path.Join(targetDir, serviceName+"_svc.go") + to := path.Join(targetDir, serviceName+"_grpc_svc.go") if _, err := os.Stat(to); !os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "%s already exists: %s\n", s.Service, to) continue diff --git a/cmd/eagle/internal/repo/add/repo.go b/cmd/eagle/internal/repo/add/repo.go index c6d6847884..66815e5c72 100644 --- a/cmd/eagle/internal/repo/add/repo.go +++ b/cmd/eagle/internal/repo/add/repo.go @@ -2,7 +2,6 @@ package add import ( "fmt" - "io/ioutil" "os" "path" @@ -41,5 +40,5 @@ func (r *Repo) Generate() error { if _, err := os.Stat(name); !os.IsNotExist(err) { return fmt.Errorf("%s already exists", r.Name) } - return ioutil.WriteFile(name, body, 0644) + return os.WriteFile(name, body, 0644) } diff --git a/cmd/eagle/internal/repo/add/template.go b/cmd/eagle/internal/repo/add/template.go index ffab971844..7b5a12b811 100644 --- a/cmd/eagle/internal/repo/add/template.go +++ b/cmd/eagle/internal/repo/add/template.go @@ -13,24 +13,21 @@ package repository import ( "context" - "fmt" - "strings" "time" + localCache "github.com/go-eagle/eagle/pkg/cache" + "github.com/go-eagle/eagle/pkg/encoding" "github.com/pkg/errors" "github.com/spf13/cast" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/trace" + "golang.org/x/sync/singleflight" "gorm.io/gorm" - "{{.ModName}}/internal/cache" - "{{.ModName}}/internal/model" -) - -var ( - _table{{.Name}}Name = (&model.{{.Name}}Model{}).TableName() - _get{{.Name}}SQL = "SELECT * FROM %s WHERE id = ?" - _batchGet{{.Name}}SQL = "SELECT * FROM %s WHERE id IN (%s)" + "{{.ModName}}/internal/dal" + "{{.ModName}}/internal/dal/cache" + "{{.ModName}}/internal/dal/db/dao" + "{{.ModName}}/internal/dal/db/model" ) var _ {{.Name}}Repo = (*{{.LcName}}Repo)(nil) @@ -44,25 +41,29 @@ type {{.Name}}Repo interface { } type {{.LcName}}Repo struct { - db *gorm.DB - tracer trace.Tracer + db *dal.DBClient + tracer trace.Tracer {{- if eq .WithCache true }} - cache cache.{{.Name}}Cache + cache cache.{{.Name}}Cache {{- end }} + localCache localCache.Cache + sg singleflight.Group } {{- if .WithCache }} // New{{.Name}} new a repository and return -func New{{.Name}}(db *gorm.DB, cache cache.{{.Name}}Cache) {{.Name}}Repo { +func New{{.Name}}(db *dal.DBClient, cache cache.{{.Name}}Cache) {{.Name}}Repo { return &{{.LcName}}Repo{ - db: db, - tracer: otel.Tracer("{{.LcName}}"), - cache: cache, + db: db, + tracer: otel.Tracer("{{.LcName}}"), + cache: cache, + localCache: localCache.NewMemoryCache("local:{{.LcName}}:", encoding.JSONEncoding{}), + sg: singleflight.Group{}, } } {{- else }} // New{{.Name}} new a repository and return -func New{{.Name}}(db *gorm.DB) {{.Name}}Repo { +func New{{.Name}}(db *dal.DBClient) {{.Name}}Repo { return &{{.LcName}}Repo{ db: db, tracer: otel.Tracer("{{.LcName}}Repo"), @@ -72,7 +73,11 @@ func New{{.Name}}(db *gorm.DB) {{.Name}}Repo { // Create{{.Name}} create a item func (r *{{.LcName}}Repo) Create{{.Name}}(ctx context.Context, data *model.{{.Name}}Model) (id int64, err error) { - err = r.db.WithContext(ctx).Create(&data).Error + if data == nil { + return 0, errors.New("[repo] Create{{.Name}} data cannot be nil") + } + + err = dao.{{.Name}}Model.WithContext(ctx).Create(data) if err != nil { return 0, errors.Wrap(err, "[repo] create {{.Name}} err") } @@ -82,11 +87,14 @@ func (r *{{.LcName}}Repo) Create{{.Name}}(ctx context.Context, data *model.{{.Na // Update{{.Name}} update item func (r *{{.LcName}}Repo) Update{{.Name}}(ctx context.Context, id int64, data *model.{{.Name}}Model) error { - item, err := r.Get{{.Name}}(ctx, id) - if err != nil { - return errors.Wrapf(err, "[repo] update {{.Name}} err: %v", err) + if id == 0 { + return errors.New("[repo] Update{{.Name}} id cannot be equal to 0") } - err = r.db.Model(&item).Updates(data).Error + if data == nil { + return errors.New("[repo] Update{{.Name}} data cannot be nil") + } + + _, err := dao.{{.Name}}Model.WithContext(ctx).Where(dao.{{.Name}}Model.ID.Eq(id)).Updates(data) if err != nil { return err } @@ -100,40 +108,78 @@ func (r *{{.LcName}}Repo) Update{{.Name}}(ctx context.Context, id int64, data *m // Get{{.Name}} get a record func (r *{{.LcName}}Repo) Get{{.Name}}(ctx context.Context, id int64) (ret *model.{{.Name}}Model, err error) { + if id == 0 { + return nil, errors.New("[repo] Get{{.Name}} id cannot be equal to 0") + } + {{- if .WithCache }} - // read cache - item, err := r.cache.Get{{.Name}}Cache(ctx, id) + // get data from local cache + err = r.localCache.Get(ctx, cast.ToString(id), &ret) if err != nil { return nil, err } - if item != nil { - return item, nil + if ret != nil && ret.ID > 0 { + return ret, nil } -{{- end }} - // read db - data := new(model.{{.Name}}Model) - err = r.db.WithContext(ctx).Raw(fmt.Sprintf(_get{{.Name}}SQL, _table{{.Name}}Name), id).Scan(&data).Error + + // read redis cache + ret, err = r.cache.Get{{.Name}}Cache(ctx, id) if err != nil { - return + return nil, err + } + if ret != nil && ret.ID > 0 { + return ret, nil } -{{- if .WithCache }} - // write cache - if data.ID > 0 { - err = r.cache.Set{{.Name}}Cache(ctx, id, data, 5*time.Minute) + // get data from db + // 避免缓存击穿(瞬间有大量请求过来) + val, err, _ := r.sg.Do("sg:{{.LcName}}:"+cast.ToString(id), func() (interface{}, error) { + // read db or rpc + data, err := dao.{{.Name}}Model.WithContext(ctx).Where(dao.{{.Name}}Model.ID.Eq(id)).First() if err != nil { - return nil, err + // cache not found and set empty cache to avoid 缓存穿透 + // Note: 如果缓存空数据太多,会大大降低缓存命中率,可以改为使用布隆过滤器 + if errors.Is(err, gorm.ErrRecordNotFound) { + r.cache.SetCacheWithNotFound(ctx, id) + } + return nil, errors.Wrapf(err, "[repo] get {{.Name}} from db error, id: %d", id) } + + // write cache + if data != nil && data.ID > 0 { + // write redis + err = r.cache.Set{{.Name}}Cache(ctx, id, data, 5*time.Minute) + if err != nil { + return nil, errors.WithMessage(err, "[repo] Get{{.Name}} Set{{.Name}}Cache error") + } + + // write local cache + err = r.localCache.Set(ctx, cast.ToString(id), data, 2*time.Minute) + if err != nil { + return nil, errors.WithMessage(err, "[repo] Get{{.Name}} localCache set error") + } + } + return data, nil + }) + if err != nil { + return nil, err + } + + return val.(*model.{{.Name}}Model), nil +{{- else }} + // read db + ret, err = dao.{{.Name}}Model.WithContext(ctx).Where(dao.{{.Name}}Model.ID.In(ids...)).Find() + if err != nil { + return nil, err } + return ret, nil {{- end }} - return data, nil } // BatchGet{{.Name}} batch get items func (r *{{.LcName}}Repo) BatchGet{{.Name}}(ctx context.Context, ids []int64) (ret []*model.{{.Name}}Model, err error) { {{- if .WithCache }} // read cache - idsStr := cast.ToStringSlice(ids) itemMap, err := r.cache.MultiGet{{.Name}}Cache(ctx, ids) if err != nil { return nil, err @@ -149,9 +195,7 @@ func (r *{{.LcName}}Repo) BatchGet{{.Name}}(ctx context.Context, ids []int64) (r } // get missed data if len(missedID) > 0 { - var missedData []*model.{{.Name}}Model - _sql := fmt.Sprintf(_batchGet{{.Name}}SQL, _table{{.Name}}Name, strings.Join(idsStr, ",")) - err = r.db.WithContext(ctx).Raw(_sql).Scan(&missedData).Error + missedData, err := dao.{{.Name}}Model.WithContext(ctx).Where(dao.{{.Name}}Model.ID.In(ids...)).Find() if err != nil { // you can degrade to ignore error return nil, err @@ -169,7 +213,7 @@ func (r *{{.LcName}}Repo) BatchGet{{.Name}}(ctx context.Context, ids []int64) (r {{- else }} // read db items := make([]*model.{{.Name}}Model, 0) - err = r.db.WithContext(ctx).Raw(fmt.Sprintf(_batchGet{{.Name}}SQL, _table{{.Name}}Name), ids).Scan(&items).Error + items, err := dao.{{.Name}}Model.WithContext(ctx).Where(dao.{{.Name}}Model.ID.In(ids...)).Find() if err != nil { return } diff --git a/cmd/eagle/internal/service/add/add.go b/cmd/eagle/internal/service/add/add.go index 26de64e9e6..68efd39765 100644 --- a/cmd/eagle/internal/service/add/add.go +++ b/cmd/eagle/internal/service/add/add.go @@ -12,7 +12,7 @@ import ( var CmdAdd = &cobra.Command{ Use: "add", Short: "Create a svc file by template", - Long: "Create a svc file using the svc template. Example: eagle svc add UserCache", + Long: "Create a svc file using the svc template. Example: eagle svc add User", Run: run, } diff --git a/cmd/eagle/internal/service/add/service.go b/cmd/eagle/internal/service/add/service.go index ff6eb324e7..e7f60e441a 100644 --- a/cmd/eagle/internal/service/add/service.go +++ b/cmd/eagle/internal/service/add/service.go @@ -2,7 +2,6 @@ package add import ( "fmt" - "io/ioutil" "os" "path" @@ -39,5 +38,5 @@ func (s *Service) Generate() error { if _, err := os.Stat(name); !os.IsNotExist(err) { return fmt.Errorf("%s already exists", s.Name) } - return ioutil.WriteFile(name, body, 0644) + return os.WriteFile(name, body, 0644) } diff --git a/cmd/eagle/internal/service/add/template.go b/cmd/eagle/internal/service/add/template.go index c801fd233e..294a4dc414 100644 --- a/cmd/eagle/internal/service/add/template.go +++ b/cmd/eagle/internal/service/add/template.go @@ -22,13 +22,15 @@ type {{.Name}}Service interface { } type {{.LcName}}Service struct { - repo repository.Repository + repo repository.{{.Name}}Repo } var _ {{.Name}}Service = (*{{.LcName}}Service)(nil) -func new{{.Name}}Service(svc *service) *{{.LcName}}Service { - return &{{.LcName}}Service{repo: svc.repo} +func New{{.Name}}Service(repo repository.{{.Name}}Repo) {{.Name}}Service { + return &{{.LcName}}Service{ + repo: repo, + } } // Hello . diff --git a/cmd/eagle/main.go b/cmd/eagle/main.go index 40b7b8a5fb..3e0c667028 100644 --- a/cmd/eagle/main.go +++ b/cmd/eagle/main.go @@ -19,7 +19,7 @@ import ( var ( // Version is the version of the compiled software. - Version = "v0.18.1" + Version = "v1.0.0" rootCmd = &cobra.Command{ Use: "eagle", diff --git a/go.mod b/go.mod index bf2f3752b2..900b951910 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/go-eagle/eagle -go 1.22.3 +go 1.22 require ( github.com/Shopify/sarama v1.19.0