Feature mongo gen (#546)
* add feature: mongo code generation * upgrade version * update doc * format code * update update.tpl of mysql
This commit is contained in:
@@ -19,6 +19,7 @@ import (
|
|||||||
"github.com/tal-tech/go-zero/tools/goctl/configgen"
|
"github.com/tal-tech/go-zero/tools/goctl/configgen"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/docker"
|
"github.com/tal-tech/go-zero/tools/goctl/docker"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/kube"
|
"github.com/tal-tech/go-zero/tools/goctl/kube"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/model/mongo"
|
||||||
model "github.com/tal-tech/go-zero/tools/goctl/model/sql/command"
|
model "github.com/tal-tech/go-zero/tools/goctl/model/sql/command"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/plugin"
|
"github.com/tal-tech/go-zero/tools/goctl/plugin"
|
||||||
rpc "github.com/tal-tech/go-zero/tools/goctl/rpc/cli"
|
rpc "github.com/tal-tech/go-zero/tools/goctl/rpc/cli"
|
||||||
@@ -28,7 +29,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
buildVersion = "1.1.5"
|
buildVersion = "1.1.6"
|
||||||
commands = []cli.Command{
|
commands = []cli.Command{
|
||||||
{
|
{
|
||||||
Name: "upgrade",
|
Name: "upgrade",
|
||||||
@@ -447,6 +448,29 @@ var (
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "mongo",
|
||||||
|
Usage: `generate mongo model`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringSliceFlag{
|
||||||
|
Name: "type, t",
|
||||||
|
Usage: "specified model type name",
|
||||||
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "cache, c",
|
||||||
|
Usage: "generate code with cache [optional]",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "dir, d",
|
||||||
|
Usage: "the target dir",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "style",
|
||||||
|
Usage: "the file naming format, see [https://github.com/tal-tech/go-zero/tree/master/tools/goctl/config/readme.md]",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: mongo.Action,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
69
tools/goctl/model/mongo/generate/generate.go
Normal file
69
tools/goctl/model/mongo/generate/generate.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/config"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/model/mongo/template"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/util/format"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Context defines the model generation data what they needs
|
||||||
|
type Context struct {
|
||||||
|
Types []string
|
||||||
|
Cache bool
|
||||||
|
Output string
|
||||||
|
Cfg *config.Config
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do executes model template and output the result into the specified file path
|
||||||
|
func Do(ctx *Context) error {
|
||||||
|
if ctx.Cfg == nil {
|
||||||
|
return errors.New("missing config")
|
||||||
|
}
|
||||||
|
|
||||||
|
err := generateModel(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return generateError(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateModel(ctx *Context) error {
|
||||||
|
for _, t := range ctx.Types {
|
||||||
|
fn, err := format.FileNamingFormat(ctx.Cfg.NamingFormat, t+"_model")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
text, err := util.LoadTemplate(category, modelTemplateFile, template.Text)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
output := filepath.Join(ctx.Output, fn+".go")
|
||||||
|
err = util.With("model").Parse(text).GoFmt(true).SaveTo(map[string]interface{}{
|
||||||
|
"Type": t,
|
||||||
|
"Cache": ctx.Cache,
|
||||||
|
}, output, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateError(ctx *Context) error {
|
||||||
|
text, err := util.LoadTemplate(category, errTemplateFile, template.Error)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
output := filepath.Join(ctx.Output, "error.go")
|
||||||
|
|
||||||
|
return util.With("error").Parse(text).GoFmt(true).SaveTo(ctx, output, false)
|
||||||
|
}
|
||||||
34
tools/goctl/model/mongo/generate/generate_test.go
Normal file
34
tools/goctl/model/mongo/generate/generate_test.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
var testTypes = `
|
||||||
|
type User struct{}
|
||||||
|
type Class struct{}
|
||||||
|
`
|
||||||
|
|
||||||
|
func TestDo(t *testing.T) {
|
||||||
|
cfg, err := config.NewConfig(config.DefaultFormat)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
tempDir := t.TempDir()
|
||||||
|
typesfile := filepath.Join(tempDir, "types.go")
|
||||||
|
err = ioutil.WriteFile(typesfile, []byte(testTypes), 0666)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
|
||||||
|
err = Do(&Context{
|
||||||
|
Types: []string{"User", "Class"},
|
||||||
|
Cache: false,
|
||||||
|
Output: tempDir,
|
||||||
|
Cfg: cfg,
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
50
tools/goctl/model/mongo/generate/template.go
Normal file
50
tools/goctl/model/mongo/generate/template.go
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package generate
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/model/mongo/template"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
category = "mongo"
|
||||||
|
modelTemplateFile = "model.tpl"
|
||||||
|
errTemplateFile = "err.tpl"
|
||||||
|
)
|
||||||
|
|
||||||
|
var templates = map[string]string{
|
||||||
|
modelTemplateFile: template.Text,
|
||||||
|
errTemplateFile: template.Error,
|
||||||
|
}
|
||||||
|
|
||||||
|
func Category() string {
|
||||||
|
return category
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clean() error {
|
||||||
|
return util.Clean(category)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Templates(_ *cli.Context) error {
|
||||||
|
return util.InitTemplates(category, templates)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RevertTemplate(name string) error {
|
||||||
|
content, ok := templates[name]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("%s: no such file name", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.CreateTemplate(category, name, content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Update() error {
|
||||||
|
err := Clean()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return util.InitTemplates(category, templates)
|
||||||
|
}
|
||||||
39
tools/goctl/model/mongo/mongo.go
Normal file
39
tools/goctl/model/mongo/mongo.go
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
package mongo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/config"
|
||||||
|
"github.com/tal-tech/go-zero/tools/goctl/model/mongo/generate"
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Command provides the entry for goctl
|
||||||
|
func Action(ctx *cli.Context) error {
|
||||||
|
tp := ctx.StringSlice("type")
|
||||||
|
c := ctx.Bool("cache")
|
||||||
|
o := strings.TrimSpace(ctx.String("dir"))
|
||||||
|
s := ctx.String("style")
|
||||||
|
if len(tp) == 0 {
|
||||||
|
return errors.New("missing type")
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := config.NewConfig(s)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
a, err := filepath.Abs(o)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return generate.Do(&generate.Context{
|
||||||
|
Types: tp,
|
||||||
|
Cache: c,
|
||||||
|
Output: a,
|
||||||
|
Cfg: cfg,
|
||||||
|
})
|
||||||
|
}
|
||||||
210
tools/goctl/model/mongo/readme.md
Normal file
210
tools/goctl/model/mongo/readme.md
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
# mongo生成model
|
||||||
|
|
||||||
|
## 背景
|
||||||
|
|
||||||
|
在业务务开发中,model(dao)数据访问层是一个服务必不可缺的一层,因此数据库访问的CURD也是必须要对外提供的访问方法, 而CURD在go-zero中就仅存在两种情况
|
||||||
|
|
||||||
|
* 带缓存model
|
||||||
|
* 不带缓存model
|
||||||
|
|
||||||
|
从代码结构上来看,C-U-R-D四个方法就是固定的结构,因此我们可以将其交给goctl工具去完成,帮助我们提升开发效率。
|
||||||
|
|
||||||
|
## 方案设计
|
||||||
|
|
||||||
|
mongo的生成不同于mysql,mysql可以从scheme_information库中读取到一张表的信息(字段名称,数据类型,索引等),
|
||||||
|
而mongo是文档型数据库,我们暂时无法从db中读取某一条记录来实现字段信息获取,就算有也不一定是完整信息(某些字段可能是omitempty修饰,可有可无), 这里采用type自己编写+代码生成方式实现
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
假设我们需要生成一个usermodel.go的代码文件,其包含用户信息字段有
|
||||||
|
|
||||||
|
|字段名称|字段类型|
|
||||||
|
|---|---|
|
||||||
|
|_id|bson.ObejctId|
|
||||||
|
|name|string|
|
||||||
|
|
||||||
|
### 编写types.go
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ vim types.go
|
||||||
|
```
|
||||||
|
|
||||||
|
```golang
|
||||||
|
package model
|
||||||
|
|
||||||
|
//go:generate goctl model mongo -t User
|
||||||
|
import "github.com/globalsign/mgo/bson"
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
ID bson.ObjectId `bson:"_id"`
|
||||||
|
Name string `bson:"name"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生成代码
|
||||||
|
|
||||||
|
生成代码的方式有两种
|
||||||
|
|
||||||
|
* 命令行生成 在types.go所在文件夹执行命令
|
||||||
|
```shell
|
||||||
|
$ goctl model mongo -t User -style gozero
|
||||||
|
```
|
||||||
|
* 在types.go中添加`//go:generate`,然后点击执行按钮即可生成,内容示例如下:
|
||||||
|
```golang
|
||||||
|
//go:generate goctl model mongo -t User
|
||||||
|
```
|
||||||
|
|
||||||
|
### 生成示例代码
|
||||||
|
|
||||||
|
* usermodel.go
|
||||||
|
|
||||||
|
```golang
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/globalsign/mgo/bson"
|
||||||
|
cachec "github.com/tal-tech/go-zero/core/stores/cache"
|
||||||
|
"github.com/tal-tech/go-zero/core/stores/mongoc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UserModel interface {
|
||||||
|
Insert(data *User, ctx context.Context) error
|
||||||
|
FindOne(id string, ctx context.Context) (*User, error)
|
||||||
|
Update(data *User, ctx context.Context) error
|
||||||
|
Delete(id string, ctx context.Context) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type defaultUserModel struct {
|
||||||
|
*mongoc.Model
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUserModel(url, collection string, c cachec.CacheConf) UserModel {
|
||||||
|
return &defaultUserModel{
|
||||||
|
Model: mongoc.MustNewModel(url, collection, c),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) Insert(data *User, ctx context.Context) error {
|
||||||
|
if !data.ID.Valid() {
|
||||||
|
data.ID = bson.NewObjectId()
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
return m.GetCollection(session).Insert(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindOne(id string, ctx context.Context) (*User, error) {
|
||||||
|
if !bson.IsObjectIdHex(id) {
|
||||||
|
return nil, ErrInvalidObjectId
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
var data User
|
||||||
|
|
||||||
|
err = m.GetCollection(session).FindOneIdNoCache(&data, bson.ObjectIdHex(id))
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &data, nil
|
||||||
|
case mongoc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) Update(data *User, ctx context.Context) error {
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
|
||||||
|
return m.GetCollection(session).UpdateIdNoCache(data.ID, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) Delete(id string, ctx context.Context) error {
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
|
||||||
|
return m.GetCollection(session).RemoveIdNoCache(bson.ObjectIdHex(id))
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* error.go
|
||||||
|
|
||||||
|
```golang
|
||||||
|
package model
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var ErrNotFound = errors.New("not found")
|
||||||
|
var ErrInvalidObjectId = errors.New("invalid objectId")
|
||||||
|
```
|
||||||
|
|
||||||
|
### 文件目录预览
|
||||||
|
|
||||||
|
```text
|
||||||
|
.
|
||||||
|
├── error.go
|
||||||
|
├── types.go
|
||||||
|
└── usermodel.go
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 命令预览
|
||||||
|
|
||||||
|
```text
|
||||||
|
NAME:
|
||||||
|
goctl model - generate model code
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
goctl model command [command options] [arguments...]
|
||||||
|
|
||||||
|
COMMANDS:
|
||||||
|
mysql generate mysql model
|
||||||
|
mongo generate mongo model
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--help, -h show help
|
||||||
|
```
|
||||||
|
|
||||||
|
```text
|
||||||
|
NAME:
|
||||||
|
goctl model mongo - generate mongo model
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
goctl model mongo [command options] [arguments...]
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--type value, -t value specified model type name
|
||||||
|
--cache, -c generate code with cache [optional]
|
||||||
|
--dir value, -d value the target dir
|
||||||
|
--style value the file naming format, see [https://github.com/tal-tech/go-zero/tree/master/tools/goctl/config/readme.md]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
> 温馨提示
|
||||||
|
>
|
||||||
|
> `--type` 支持slice传值,示例 `goctl model mongo -t=User -t=Class`
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
types.go本质上与xxxmodel.go无关,只是将type定义部分交给开发人员自己编写了,在xxxmodel.go中,mongo文档的存储结构必须包含
|
||||||
|
`_id`字段,对应到types中的field为`ID`,model中的findOne,update均以data.ID来进行操作的,当然,如果不符合你的命名风格,你也 可以修改模板,只要保证`id`
|
||||||
|
在types中的field名称和模板中一致就行。
|
||||||
111
tools/goctl/model/mongo/template/template.go
Normal file
111
tools/goctl/model/mongo/template/template.go
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
package template
|
||||||
|
|
||||||
|
// Text provides the default template for model to generate
|
||||||
|
var Text = `package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/globalsign/mgo/bson"
|
||||||
|
cachec "github.com/tal-tech/go-zero/core/stores/cache"
|
||||||
|
"github.com/tal-tech/go-zero/core/stores/mongoc"
|
||||||
|
)
|
||||||
|
|
||||||
|
{{if .Cache}}var prefix{{.Type}}CacheKey = "cache#{{.Type}}#"{{end}}
|
||||||
|
|
||||||
|
type {{.Type}}Model interface{
|
||||||
|
Insert(ctx context.Context,data *{{.Type}}) error
|
||||||
|
FindOne(ctx context.Context,id string) (*{{.Type}}, error)
|
||||||
|
Update(ctx context.Context,data *{{.Type}}) error
|
||||||
|
Delete(ctx context.Context,id string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type default{{.Type}}Model struct {
|
||||||
|
*mongoc.Model
|
||||||
|
}
|
||||||
|
|
||||||
|
func New{{.Type}}Model(url, collection string, c cachec.CacheConf) {{.Type}}Model {
|
||||||
|
return &default{{.Type}}Model{
|
||||||
|
Model: mongoc.MustNewModel(url, collection, c),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error {
|
||||||
|
if !data.ID.Valid() {
|
||||||
|
data.ID = bson.NewObjectId()
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
return m.GetCollection(session).Insert(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) {
|
||||||
|
if !bson.IsObjectIdHex(id) {
|
||||||
|
return nil, ErrInvalidObjectId
|
||||||
|
}
|
||||||
|
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
var data {{.Type}}
|
||||||
|
{{if .Cache}}key := prefix{{.Type}}CacheKey + id
|
||||||
|
err = m.GetCollection(session).FindOneId(&data, key, bson.ObjectIdHex(id))
|
||||||
|
{{- else}}
|
||||||
|
err = m.GetCollection(session).FindOneIdNoCache(&data, bson.ObjectIdHex(id))
|
||||||
|
{{- end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &data,nil
|
||||||
|
case mongoc.ErrNotFound:
|
||||||
|
return nil,ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) error {
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
{{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex()
|
||||||
|
return m.GetCollection(session).UpdateId(data.ID, data, key)
|
||||||
|
{{- else}}
|
||||||
|
return m.GetCollection(session).UpdateIdNoCache(data.ID, data)
|
||||||
|
{{- end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) error {
|
||||||
|
session, err := m.TakeSession()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer m.PutSession(session)
|
||||||
|
{{if .Cache}}key := prefix{{.Type}}CacheKey + id
|
||||||
|
return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id), key)
|
||||||
|
{{- else}}
|
||||||
|
return m.GetCollection(session).RemoveIdNoCache(bson.ObjectIdHex(id))
|
||||||
|
{{- end}}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
var Error = `
|
||||||
|
package model
|
||||||
|
|
||||||
|
import "errors"
|
||||||
|
|
||||||
|
var ErrNotFound = errors.New("not found")
|
||||||
|
var ErrInvalidObjectId = errors.New("invalid objectId")
|
||||||
|
`
|
||||||
@@ -3,6 +3,7 @@ package gen
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/tal-tech/go-zero/core/collection"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/model/sql/template"
|
"github.com/tal-tech/go-zero/tools/goctl/model/sql/template"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
"github.com/tal-tech/go-zero/tools/goctl/util/stringx"
|
||||||
@@ -23,6 +24,15 @@ func genUpdate(table Table, withCache bool) (string, string, error) {
|
|||||||
expressionValues = append(expressionValues, "data."+camel)
|
expressionValues = append(expressionValues, "data."+camel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
keySet := collection.NewSet()
|
||||||
|
keyVariableSet := collection.NewSet()
|
||||||
|
keySet.AddStr(table.PrimaryCacheKey.DataKeyExpression)
|
||||||
|
keyVariableSet.AddStr(table.PrimaryCacheKey.KeyLeft)
|
||||||
|
for _, key := range table.UniqueCacheKey {
|
||||||
|
keySet.AddStr(key.DataKeyExpression)
|
||||||
|
keyVariableSet.AddStr(key.KeyLeft)
|
||||||
|
}
|
||||||
|
|
||||||
expressionValues = append(expressionValues, "data."+table.PrimaryKey.Name.ToCamel())
|
expressionValues = append(expressionValues, "data."+table.PrimaryKey.Name.ToCamel())
|
||||||
camelTableName := table.Name.ToCamel()
|
camelTableName := table.Name.ToCamel()
|
||||||
text, err := util.LoadTemplate(category, updateTemplateFile, template.Update)
|
text, err := util.LoadTemplate(category, updateTemplateFile, template.Update)
|
||||||
@@ -35,6 +45,8 @@ func genUpdate(table Table, withCache bool) (string, string, error) {
|
|||||||
Execute(map[string]interface{}{
|
Execute(map[string]interface{}{
|
||||||
"withCache": withCache,
|
"withCache": withCache,
|
||||||
"upperStartCamelObject": camelTableName,
|
"upperStartCamelObject": camelTableName,
|
||||||
|
"keys": strings.Join(keySet.KeysStr(), "\n"),
|
||||||
|
"keyValues": strings.Join(keyVariableSet.KeysStr(), ", "),
|
||||||
"primaryCacheKey": table.PrimaryCacheKey.DataKeyExpression,
|
"primaryCacheKey": table.PrimaryCacheKey.DataKeyExpression,
|
||||||
"primaryKeyVariable": table.PrimaryCacheKey.KeyLeft,
|
"primaryKeyVariable": table.PrimaryCacheKey.KeyLeft,
|
||||||
"lowerStartCamelObject": stringx.From(camelTableName).Untitle(),
|
"lowerStartCamelObject": stringx.From(camelTableName).Untitle(),
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ package template
|
|||||||
// Update defines a template for generating update codes
|
// Update defines a template for generating update codes
|
||||||
var Update = `
|
var Update = `
|
||||||
func (m *default{{.upperStartCamelObject}}Model) Update(data {{.upperStartCamelObject}}) error {
|
func (m *default{{.upperStartCamelObject}}Model) Update(data {{.upperStartCamelObject}}) error {
|
||||||
{{if .withCache}}{{.primaryCacheKey}}
|
{{if .withCache}}{{.keys}}
|
||||||
_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {
|
_, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = ?", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = ?", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
||||||
return conn.Exec(query, {{.expressionValues}})
|
return conn.Exec(query, {{.expressionValues}})
|
||||||
}, {{.primaryKeyVariable}}){{else}}query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = ?", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
}, {{.keyValues}}){{else}}query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = ?", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
||||||
_,err:=m.conn.Exec(query, {{.expressionValues}}){{end}}
|
_,err:=m.conn.Exec(query, {{.expressionValues}}){{end}}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"github.com/tal-tech/go-zero/tools/goctl/api/gogen"
|
"github.com/tal-tech/go-zero/tools/goctl/api/gogen"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/docker"
|
"github.com/tal-tech/go-zero/tools/goctl/docker"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/kube"
|
"github.com/tal-tech/go-zero/tools/goctl/kube"
|
||||||
|
mongogen "github.com/tal-tech/go-zero/tools/goctl/model/mongo/generate"
|
||||||
modelgen "github.com/tal-tech/go-zero/tools/goctl/model/sql/gen"
|
modelgen "github.com/tal-tech/go-zero/tools/goctl/model/sql/gen"
|
||||||
rpcgen "github.com/tal-tech/go-zero/tools/goctl/rpc/generator"
|
rpcgen "github.com/tal-tech/go-zero/tools/goctl/rpc/generator"
|
||||||
"github.com/tal-tech/go-zero/tools/goctl/util"
|
"github.com/tal-tech/go-zero/tools/goctl/util"
|
||||||
@@ -34,6 +35,9 @@ func GenTemplates(ctx *cli.Context) error {
|
|||||||
func() error {
|
func() error {
|
||||||
return kube.GenTemplates(ctx)
|
return kube.GenTemplates(ctx)
|
||||||
},
|
},
|
||||||
|
func() error {
|
||||||
|
return mongogen.Templates(ctx)
|
||||||
|
},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -61,6 +65,15 @@ func CleanTemplates(_ *cli.Context) error {
|
|||||||
func() error {
|
func() error {
|
||||||
return rpcgen.Clean()
|
return rpcgen.Clean()
|
||||||
},
|
},
|
||||||
|
func() error {
|
||||||
|
return docker.Clean()
|
||||||
|
},
|
||||||
|
func() error {
|
||||||
|
return kube.Clean()
|
||||||
|
},
|
||||||
|
func() error {
|
||||||
|
return mongogen.Clean()
|
||||||
|
},
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -90,6 +103,8 @@ func UpdateTemplates(ctx *cli.Context) (err error) {
|
|||||||
return rpcgen.Update()
|
return rpcgen.Update()
|
||||||
case modelgen.Category():
|
case modelgen.Category():
|
||||||
return modelgen.Update()
|
return modelgen.Update()
|
||||||
|
case mongogen.Category():
|
||||||
|
return mongogen.Update()
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("unexpected category: %s", category)
|
err = fmt.Errorf("unexpected category: %s", category)
|
||||||
return
|
return
|
||||||
@@ -116,6 +131,8 @@ func RevertTemplates(ctx *cli.Context) (err error) {
|
|||||||
return rpcgen.RevertTemplate(filename)
|
return rpcgen.RevertTemplate(filename)
|
||||||
case modelgen.Category():
|
case modelgen.Category():
|
||||||
return modelgen.RevertTemplate(filename)
|
return modelgen.RevertTemplate(filename)
|
||||||
|
case mongogen.Category():
|
||||||
|
return mongogen.RevertTemplate(filename)
|
||||||
default:
|
default:
|
||||||
err = fmt.Errorf("unexpected category: %s", category)
|
err = fmt.Errorf("unexpected category: %s", category)
|
||||||
return
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user