Feature mongo gen (#546)
* add feature: mongo code generation * upgrade version * update doc * format code * update update.tpl of mysqlmaster
parent
c954568b61
commit
dda7666097
@ -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)
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
@ -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)
|
||||||
|
}
|
@ -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,
|
||||||
|
})
|
||||||
|
}
|
@ -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")
|
||||||
|
`
|
Loading…
Reference in New Issue