feat: Replace mongo package with monc & mon (#2002)

* Replace mongo package with monc & mon

* Add terminal whitespace

* format code
master
anqiansong 2 years ago committed by GitHub
parent ed1c937998
commit c27e00b45c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,6 +9,7 @@ import (
"github.com/zeromicro/go-zero/tools/goctl/util" "github.com/zeromicro/go-zero/tools/goctl/util"
"github.com/zeromicro/go-zero/tools/goctl/util/format" "github.com/zeromicro/go-zero/tools/goctl/util/format"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx" "github.com/zeromicro/go-zero/tools/goctl/util/pathx"
"github.com/zeromicro/go-zero/tools/goctl/util/stringx"
) )
// Context defines the model generation data what they needs // Context defines the model generation data what they needs
@ -25,8 +26,15 @@ func Do(ctx *Context) error {
return errors.New("missing config") return errors.New("missing config")
} }
err := generateModel(ctx) if err := generateTypes(ctx); err != nil {
if err != nil { return err
}
if err := generateModel(ctx); err != nil {
return err
}
if err := generateCustomModel(ctx); err != nil {
return err return err
} }
@ -34,21 +42,47 @@ func Do(ctx *Context) error {
} }
func generateModel(ctx *Context) error { func generateModel(ctx *Context) error {
for _, t := range ctx.Types {
fn, err := format.FileNamingFormat(ctx.Cfg.NamingFormat, t+"_model_gen")
if err != nil {
return err
}
text, err := pathx.LoadTemplate(category, modelTemplateFile, template.ModelText)
if err != nil {
return err
}
output := filepath.Join(ctx.Output, fn+".go")
if err = util.With("model").Parse(text).GoFmt(true).SaveTo(map[string]interface{}{
"Type": stringx.From(t).Title(),
"lowerType": stringx.From(t).Untitle(),
"Cache": ctx.Cache,
}, output, true); err != nil {
return err
}
}
return nil
}
func generateCustomModel(ctx *Context) error {
for _, t := range ctx.Types { for _, t := range ctx.Types {
fn, err := format.FileNamingFormat(ctx.Cfg.NamingFormat, t+"_model") fn, err := format.FileNamingFormat(ctx.Cfg.NamingFormat, t+"_model")
if err != nil { if err != nil {
return err return err
} }
text, err := pathx.LoadTemplate(category, modelTemplateFile, template.Text) text, err := pathx.LoadTemplate(category, modelCustomTemplateFile, template.ModelCustomText)
if err != nil { if err != nil {
return err return err
} }
output := filepath.Join(ctx.Output, fn+".go") output := filepath.Join(ctx.Output, fn+".go")
err = util.With("model").Parse(text).GoFmt(true).SaveTo(map[string]interface{}{ err = util.With("model").Parse(text).GoFmt(true).SaveTo(map[string]interface{}{
"Type": t, "Type": stringx.From(t).Title(),
"Cache": ctx.Cache, "lowerType": stringx.From(t).Untitle(),
"Cache": ctx.Cache,
}, output, false) }, output, false)
if err != nil { if err != nil {
return err return err
@ -58,6 +92,29 @@ func generateModel(ctx *Context) error {
return nil return nil
} }
func generateTypes(ctx *Context) error {
for _, t := range ctx.Types {
fn, err := format.FileNamingFormat(ctx.Cfg.NamingFormat, t+"types")
if err != nil {
return err
}
text, err := pathx.LoadTemplate(category, modelTypesTemplateFile, template.ModelTypesText)
if err != nil {
return err
}
output := filepath.Join(ctx.Output, fn+".go")
if err = util.With("model").Parse(text).GoFmt(true).SaveTo(map[string]interface{}{
"Type": stringx.From(t).Title(),
}, output, false);err!=nil{
return err
}
}
return nil
}
func generateError(ctx *Context) error { func generateError(ctx *Context) error {
text, err := pathx.LoadTemplate(category, errTemplateFile, template.Error) text, err := pathx.LoadTemplate(category, errTemplateFile, template.Error)
if err != nil { if err != nil {

@ -16,20 +16,53 @@ var testTypes = `
` `
func TestDo(t *testing.T) { func TestDo(t *testing.T) {
cfg, err := config.NewConfig(config.DefaultFormat) t.Run("should generate model", func(t *testing.T) {
assert.Nil(t, err) cfg, err := config.NewConfig(config.DefaultFormat)
assert.Nil(t, err)
tempDir := pathx.MustTempDir()
typesfile := filepath.Join(tempDir, "types.go") tempDir := pathx.MustTempDir()
err = ioutil.WriteFile(typesfile, []byte(testTypes), 0o666) typesfile := filepath.Join(tempDir, "types.go")
assert.Nil(t, err) err = ioutil.WriteFile(typesfile, []byte(testTypes), 0o666)
assert.Nil(t, err)
err = Do(&Context{
Types: []string{"User", "Class"}, err = Do(&Context{
Cache: false, Types: []string{"User", "Class"},
Output: tempDir, Cache: false,
Cfg: cfg, Output: tempDir,
Cfg: cfg,
})
assert.Nil(t, err)
})
t.Run("missing config", func(t *testing.T) {
tempDir := t.TempDir()
typesfile := filepath.Join(tempDir, "types.go")
err := ioutil.WriteFile(typesfile, []byte(testTypes), 0o666)
assert.Nil(t, err)
err = Do(&Context{
Types: []string{"User", "Class"},
Cache: false,
Output: tempDir,
Cfg: nil,
})
assert.Error(t, err)
}) })
assert.Nil(t, err) t.Run("invalid config", func(t *testing.T) {
cfg := &config.Config{NamingFormat: "foo"}
tempDir := t.TempDir()
typesfile := filepath.Join(tempDir, "types.go")
err := ioutil.WriteFile(typesfile, []byte(testTypes), 0o666)
assert.Nil(t, err)
err = Do(&Context{
Types: []string{"User", "Class"},
Cache: false,
Output: tempDir,
Cfg: cfg,
})
assert.Error(t, err)
})
} }

@ -8,14 +8,18 @@ import (
) )
const ( const (
category = "mongo" category = "mongo"
modelTemplateFile = "model.tpl" modelTemplateFile = "model.tpl"
errTemplateFile = "err.tpl" modelCustomTemplateFile = "model_custom.tpl"
modelTypesTemplateFile = "model_types.tpl"
errTemplateFile = "err.tpl"
) )
var templates = map[string]string{ var templates = map[string]string{
modelTemplateFile: template.Text, modelTemplateFile: template.ModelText,
errTemplateFile: template.Error, modelCustomTemplateFile: template.ModelCustomText,
modelTypesTemplateFile: template.ModelTypesText,
errTemplateFile: template.Error,
} }
// Category returns the mongo category. // Category returns the mongo category.

@ -0,0 +1,41 @@
package generate
import (
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
)
func TestTemplate(t *testing.T) {
tempDir := t.TempDir()
pathx.RegisterGoctlHome(tempDir)
t.Cleanup(func() {
pathx.RegisterGoctlHome("")
})
t.Run("Category", func(t *testing.T) {
assert.Equal(t, category, Category())
})
t.Run("Clean", func(t *testing.T) {
err := Clean()
assert.NoError(t, err)
})
t.Run("Templates", func(t *testing.T) {
err := Templates()
assert.NoError(t, err)
assert.True(t, pathx.FileExists(filepath.Join(tempDir, category, modelTemplateFile)))
})
t.Run("RevertTemplate", func(t *testing.T) {
assert.NoError(t, RevertTemplate(modelTemplateFile))
assert.Error(t, RevertTemplate("foo"))
})
t.Run("Update", func(t *testing.T) {
assert.NoError(t, Update())
})
}

@ -38,12 +38,14 @@ func Action(_ *cobra.Command, _ []string) error {
home := VarStringHome home := VarStringHome
remote := VarStringRemote remote := VarStringRemote
branch := VarStringBranch branch := VarStringBranch
if len(remote) > 0 { if len(remote) > 0 {
repo, _ := file.CloneIntoGitHome(remote, branch) repo, _ := file.CloneIntoGitHome(remote, branch)
if len(repo) > 0 { if len(repo) > 0 {
home = repo home = repo
} }
} }
if len(home) > 0 { if len(home) > 0 {
pathx.RegisterGoctlHome(home) pathx.RegisterGoctlHome(home)
} }
@ -62,6 +64,10 @@ func Action(_ *cobra.Command, _ []string) error {
return err return err
} }
if err = pathx.MkdirIfNotExist(a); err != nil {
return err
}
return generate.Do(&generate.Context{ return generate.Do(&generate.Context{
Types: tp, Types: tp,
Cache: c, Cache: c,

@ -15,196 +15,194 @@ mongo的生成不同于mysqlmysql可以从scheme_information库中读取到
而mongo是文档型数据库我们暂时无法从db中读取某一条记录来实现字段信息获取就算有也不一定是完整信息某些字段可能是omitempty修饰可有可无 这里采用type自己编写+代码生成方式实现 而mongo是文档型数据库我们暂时无法从db中读取某一条记录来实现字段信息获取就算有也不一定是完整信息某些字段可能是omitempty修饰可有可无 这里采用type自己编写+代码生成方式实现
## 使用示例 ## 使用示例
为 User 生成 mongo model
```bahs
$ goctl model mongo -t User -c --dir .
```
假设我们需要生成一个usermodel.go的代码文件其包含用户信息字段有 ### 生成示例代码
|字段名称|字段类型| #### usermodel.go
|---|---| ```go
|_id|bson.ObejctId| package model
|name|string|
### 编写types.go import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/monc"
)
var _ UserModel = (*customUserModel)(nil)
type (
// UserModel is an interface to be customized, add more methods here,
// and implement the added methods in customUserModel.
UserModel interface {
userModel
}
customUserModel struct {
*defaultUserModel
}
)
// NewUserModel returns a model for the mongo.
func NewUserModel(url, db, collection string, c cache.CacheConf) UserModel {
conn := monc.MustNewModel(url, db, collection, c)
return &customUserModel{
defaultUserModel: newDefaultUserModel(conn),
}
}
```shell
$ vim types.go
``` ```
```golang #### usermodelgen.go
```go
// Code generated by goctl. DO NOT EDIT!
package model package model
//go:generate goctl model mongo -t User import (
import "github.com/globalsign/mgo/bson" "context"
"time"
type User struct { "github.com/zeromicro/go-zero/core/stores/monc"
ID bson.ObjectId `bson:"_id"` "go.mongodb.org/mongo-driver/bson"
Name string `bson:"name"` "go.mongodb.org/mongo-driver/bson/primitive"
)
var prefixUserCacheKey = "cache:user:"
type userModel interface {
Insert(ctx context.Context, data *User) error
FindOne(ctx context.Context, id string) (*User, error)
Update(ctx context.Context, data *User) error
Delete(ctx context.Context, id string) error
} }
```
### 生成代码 type defaultUserModel struct {
conn *monc.Model
}
生成代码的方式有两种 func newDefaultUserModel(conn *monc.Model) *defaultUserModel {
return &defaultUserModel{conn: conn}
}
* 命令行生成 在types.go所在文件夹执行命令 func (m *defaultUserModel) Insert(ctx context.Context, data *User) error {
```shell if !data.ID.IsZero() {
$ goctl model mongo -t User -style gozero data.ID = primitive.NewObjectID()
``` data.CreateAt = time.Now()
* 在types.go中添加`//go:generate`,然后点击执行按钮即可生成,内容示例如下: data.UpdateAt = time.Now()
```golang }
//go:generate goctl model mongo -t User
```
### 生成示例代码 key := prefixUserCacheKey + data.ID.Hex()
_, err := m.conn.InsertOne(ctx, key, data)
return err
}
* usermodel.go func (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {
oid, err := primitive.ObjectIDFromHex(id)
```golang if err != nil {
package model return nil, ErrInvalidObjectId
}
import (
"context" var data User
key := prefixUserCacheKey + data.ID.Hex()
"github.com/globalsign/mgo/bson" err = m.conn.FindOne(ctx, key, &data, bson.M{"_id": oid})
cachec "github.com/zeromicro/go-zero/core/stores/cache" switch err {
"github.com/zeromicro/go-zero/core/stores/mongoc" case nil:
) return &data, nil
case monc.ErrNotFound:
type UserModel interface { return nil, ErrNotFound
Insert(data *User, ctx context.Context) error default:
FindOne(id string, ctx context.Context) (*User, error) return nil, err
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")
```
### 文件目录预览 func (m *defaultUserModel) Update(ctx context.Context, data *User) error {
data.UpdateAt = time.Now()
key := prefixUserCacheKey + data.ID.Hex()
_, err := m.conn.ReplaceOne(ctx, key, bson.M{"_id": data.ID}, data)
return err
}
```text func (m *defaultUserModel) Delete(ctx context.Context, id string) error {
. oid, err := primitive.ObjectIDFromHex(id)
├── error.go if err != nil {
├── types.go return ErrInvalidObjectId
└── usermodel.go }
key := prefixUserCacheKey + id
_, err = m.conn.DeleteOne(ctx, key, bson.M{"_id": oid})
return err
}
``` ```
## 命令预览 #### usertypes.go
```go
package model
```text import (
NAME: "time"
goctl model - generate model code
"go.mongodb.org/mongo-driver/bson/primitive"
)
type User struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
// TODO: Fill your own fields
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
}
```
USAGE: #### error.go
goctl model command [command options] [arguments...] ```go
package model
import (
"errors"
COMMANDS: "github.com/zeromicro/go-zero/core/stores/mon"
mysql generate mysql model )
mongo generate mongo model
OPTIONS: var (
--help, -h show help ErrNotFound = mon.ErrNotFound
ErrInvalidObjectId = errors.New("invalid objectId")
)
``` ```
### 文件目录预览
```text ```text
NAME: .
goctl model mongo - generate mongo model ├── error.go
├── usermodel.go
├── usermodelgen.go
└── usertypes.go
```
USAGE: ## 命令预览
goctl model mongo [command options] [arguments...]
OPTIONS: ```text
--type value, -t value specified model type name Generate mongo model
--cache, -c generate code with cache [optional]
--dir value, -d value the target dir Usage:
--style value the file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md] goctl model mongo [flags]
Flags:
--branch string The branch of the remote repo, it does work with --remote
-c, --cache Generate code with cache [optional]
-d, --dir string The target dir
-h, --help help for mongo
--home string The goctl home path of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
--remote string The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure
--style string The file naming format, see [https://github.com/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
-t, --type strings Specified model type name
``` ```
> 温馨提示 > 温馨提示
> >
> `--type` 支持slice传值示例 `goctl model mongo -t=User -t=Class` > `--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名称和模板中一致就行。

@ -1,6 +1,12 @@
package model package model
import "errors" import (
"errors"
var ErrNotFound = errors.New("not found") "github.com/zeromicro/go-zero/core/stores/mon"
var ErrInvalidObjectId = errors.New("invalid objectId") )
var (
ErrNotFound = mon.ErrNotFound
ErrInvalidObjectId = errors.New("invalid objectId")
)

@ -1,98 +1,77 @@
// Code generated by goctl. DO NOT EDIT!
package model package model
import ( import (
"context" "context"
"time"
"github.com/globalsign/mgo/bson" {{if .Cache}}"github.com/zeromicro/go-zero/core/stores/monc"{{else}}"github.com/zeromicro/go-zero/core/stores/mon"{{end}}
{{if .Cache}}cachec "github.com/zeromicro/go-zero/core/stores/cache" "go.mongodb.org/mongo-driver/bson"
"github.com/zeromicro/go-zero/core/stores/mongoc"{{else}}"github.com/zeromicro/go-zero/core/stores/mongo"{{end}} "go.mongodb.org/mongo-driver/bson/primitive"
) )
{{if .Cache}}var prefix{{.Type}}CacheKey = "cache:{{.Type}}:"{{end}} {{if .Cache}}var prefix{{.Type}}CacheKey = "cache:{{.lowerType}}:"{{end}}
type {{.Type}}Model interface{ type {{.lowerType}}Model interface{
Insert(ctx context.Context,data *{{.Type}}) error Insert(ctx context.Context,data *{{.Type}}) error
FindOne(ctx context.Context,id string) (*{{.Type}}, error) FindOne(ctx context.Context,id string) (*{{.Type}}, error)
Update(ctx context.Context,data *{{.Type}}) error Update(ctx context.Context,data *{{.Type}}) error
Delete(ctx context.Context,id string) error Delete(ctx context.Context,id string) error
} }
type default{{.Type}}Model struct { type default{{.Type}}Model struct {
{{if .Cache}}*mongoc.Model{{else}}*mongo.Model{{end}} conn {{if .Cache}}*monc.Model{{else}}*mon.Model{{end}}
} }
func New{{.Type}}Model(url, collection string{{if .Cache}}, c cachec.CacheConf{{end}}) {{.Type}}Model { func newDefault{{.Type}}Model(conn {{if .Cache}}*monc.Model{{else}}*mon.Model{{end}}) *default{{.Type}}Model {
return &default{{.Type}}Model{ return &default{{.Type}}Model{conn: conn}
Model: {{if .Cache}}mongoc.MustNewModel(url, collection, c){{else}}mongo.MustNewModel(url, collection){{end}},
}
} }
func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error { func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error {
if !data.ID.Valid() { if !data.ID.IsZero() {
data.ID = bson.NewObjectId() data.ID = primitive.NewObjectID()
data.CreateAt = time.Now()
data.UpdateAt = time.Now()
} }
session, err := m.TakeSession() {{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex(){{end}}
if err != nil { _, err := m.conn.InsertOne(ctx, {{if .Cache}}key, {{end}} data)
return err 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) { func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) {
if !bson.IsObjectIdHex(id) { oid, err := primitive.ObjectIDFromHex(id)
return nil, ErrInvalidObjectId
}
session, err := m.TakeSession()
if err != nil { if err != nil {
return nil, err return nil, ErrInvalidObjectId
} }
defer m.PutSession(session)
var data {{.Type}} var data {{.Type}}
{{if .Cache}}key := prefix{{.Type}}CacheKey + id {{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex(){{end}}
err = m.GetCollection(session).FindOneId(&data, key, bson.ObjectIdHex(id)) err = m.conn.FindOne(ctx, {{if .Cache}}key, {{end}}&data, bson.M{"_id": oid})
{{- else}}
err = m.GetCollection(session).FindId(bson.ObjectIdHex(id)).One(&data)
{{- end}}
switch err { switch err {
case nil: case nil:
return &data,nil return &data, nil
case {{if .Cache}}mongoc.ErrNotFound{{else}}mongo.ErrNotFound{{end}}: case {{if .Cache}}monc{{else}}mon{{end}}.ErrNotFound:
return nil,ErrNotFound return nil, ErrNotFound
default: default:
return nil,err return nil, err
} }
} }
func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) error { func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) error {
session, err := m.TakeSession() data.UpdateAt = time.Now()
if err != nil { {{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex(){{end}}
return err _, err := m.conn.ReplaceOne(ctx, {{if .Cache}}key, {{end}}bson.M{"_id": data.ID}, data)
} 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).UpdateId(data.ID, data)
{{- end}}
} }
func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) error { func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) error {
session, err := m.TakeSession() oid, err := primitive.ObjectIDFromHex(id)
if err != nil { if err != nil {
return err return ErrInvalidObjectId
} }
{{if .Cache}}key := prefix{{.Type}}CacheKey +id{{end}}
defer m.PutSession(session) _, err = m.conn.DeleteOne(ctx, {{if .Cache}}key, {{end}}bson.M{"_id": oid})
{{if .Cache}}key := prefix{{.Type}}CacheKey + id return err
return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id), key)
{{- else}}
return m.GetCollection(session).RemoveId(bson.ObjectIdHex(id))
{{- end}}
} }

@ -0,0 +1,28 @@
package model
{{if .Cache}}import (
"github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/monc"
){{else}}import "github.com/zeromicro/go-zero/core/stores/mon"{{end}}
var _ {{.Type}}Model = (*custom{{.Type}}Model)(nil)
type (
// {{.Type}}Model is an interface to be customized, add more methods here,
// and implement the added methods in custom{{.Type}}Model.
{{.Type}}Model interface {
{{.lowerType}}Model
}
custom{{.Type}}Model struct {
*default{{.Type}}Model
}
)
// New{{.Type}}Model returns a model for the mongo.
func New{{.Type}}Model(url, db, collection string{{if .Cache}}, c cache.CacheConf{{end}}) {{.Type}}Model {
conn := {{if .Cache}}monc{{else}}mon{{end}}.MustNewModel(url, db, collection{{if .Cache}}, c{{end}})
return &custom{{.Type}}Model{
default{{.Type}}Model: newDefault{{.Type}}Model(conn),
}
}

@ -2,10 +2,20 @@ package template
import _ "embed" import _ "embed"
// Text provides the default template for model to generate. var (
//go:embed model.tpl // ModelText provides the default template for model to generate.
var Text string //go:embed model.tpl
ModelText string
// Error provides the default template for error definition in mongo code generation. // ModelCustomText provides the default template for model to generate.
//go:embed error.tpl //go:embed model_custom.tpl
var Error string ModelCustomText string
// ModelTypesText provides the default template for model to generate.
//go:embed types.tpl
ModelTypesText string
// Error provides the default template for error definition in mongo code generation.
//go:embed error.tpl
Error string
)

@ -0,0 +1,14 @@
package model
import (
"time"
"go.mongodb.org/mongo-driver/bson/primitive"
)
type {{.Type}} struct {
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
// TODO: Fill your own fields
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
}

@ -0,0 +1,25 @@
#!/bin/bash
function console_red() {
echo -e "\033[31m "$*" \033[0m"
}
function console_green() {
echo -e "\033[32m "$*" \033[0m"
}
function console_yellow() {
echo -e "\033[33m "$*" \033[0m"
}
function console_blue() {
echo -e "\033[34m "$*" \033[0m"
}
function console_tip() {
console_blue "========================== $* =============================="
}
function console_step() {
console_blue "<<<<<<<<<<<<<<<< $* >>>>>>>>>>>>>>>>"
}

@ -0,0 +1,12 @@
FROM golang:1.18
ENV TZ Asia/Shanghai
ENV GOPROXY https://goproxy.cn,direct
WORKDIR /app
ADD goctl /usr/bin/goctl
ADD cmd.sh .
RUN chmod +x /usr/bin/goctl
RUN chmod +x cmd.sh
CMD ["/bin/bash", "cmd.sh"]

@ -0,0 +1,32 @@
#!/bin/bash
wd=$(dirname $0)
project=test
testDir=$wd/$project
mkdir -p $testDir
cd $testDir
# go mod init
go mod init $project
# generate cache code
goctl model mongo -t User -c --dir cache
if [ $? -ne 0 ]; then
exit 1
fi
# generate non-cache code
goctl model mongo -t User --dir nocache
if [ $? -ne 0 ]; then
exit 1
fi
# go mod tidy
GOPROXY=https://goproxy.cn && go mod tidy
# code inspection
go test -race ./...
if [ $? -ne 0 ]; then
echo
fi

@ -0,0 +1,38 @@
#!/bin/bash
cd $(dirname $0)
# source functions
source ../../../common/echo.sh
console_tip "mongo test"
# build goctl
console_step "goctl building"
buildFile=goctl
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $buildFile ../../../../goctl.go
image=goctl-mongo:latest
# docker build
console_step "docker building"
docker build -t $image .
if [ $? -ne 0 ]; then
rm -f $buildFile
console_red "docker build failed"
exit 1
fi
# run docker image
console_step "docker running"
docker run $image
if [ $? -ne 0 ]; then
rm -f $buildFile
console_red "docker run failed"
docker image rm -f $image
exit 1
fi
rm -f $buildFile
console_green "PASS"
docker image rm -f $image > /dev/null 2>&1

@ -0,0 +1,6 @@
#!/bin/bash
# main.sh is the entry point for the goctl tests.
# testing mongo code generation.
/bin/bash integration/model/mongo/mongo.sh
Loading…
Cancel
Save