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,20 +42,46 @@ 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(),
"lowerType": stringx.From(t).Untitle(),
"Cache": ctx.Cache, "Cache": ctx.Cache,
}, output, false) }, output, false)
if err != nil { if err != nil {
@ -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,6 +16,7 @@ var testTypes = `
` `
func TestDo(t *testing.T) { func TestDo(t *testing.T) {
t.Run("should generate model", func(t *testing.T) {
cfg, err := config.NewConfig(config.DefaultFormat) cfg, err := config.NewConfig(config.DefaultFormat)
assert.Nil(t, err) assert.Nil(t, err)
@ -32,4 +33,36 @@ func TestDo(t *testing.T) {
}) })
assert.Nil(t, err) 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)
})
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)
})
} }

@ -10,11 +10,15 @@ import (
const ( const (
category = "mongo" category = "mongo"
modelTemplateFile = "model.tpl" modelTemplateFile = "model.tpl"
modelCustomTemplateFile = "model_custom.tpl"
modelTypesTemplateFile = "model_types.tpl"
errTemplateFile = "err.tpl" errTemplateFile = "err.tpl"
) )
var templates = map[string]string{ var templates = map[string]string{
modelTemplateFile: template.Text, modelTemplateFile: template.ModelText,
modelCustomTemplateFile: template.ModelCustomText,
modelTypesTemplateFile: template.ModelTypesText,
errTemplateFile: template.Error, errTemplateFile: template.Error,
} }

@ -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
假设我们需要生成一个usermodel.go的代码文件其包含用户信息字段有 ```bahs
$ goctl model mongo -t User -c --dir .
|字段名称|字段类型|
|---|---|
|_id|bson.ObejctId|
|name|string|
### 编写types.go
```shell
$ vim types.go
``` ```
```golang ### 生成示例代码
#### usermodel.go
```go
package model package model
//go:generate goctl model mongo -t User import (
import "github.com/globalsign/mgo/bson" "github.com/zeromicro/go-zero/core/stores/cache"
"github.com/zeromicro/go-zero/core/stores/monc"
)
type User struct { var _ UserModel = (*customUserModel)(nil)
ID bson.ObjectId `bson:"_id"`
Name string `bson:"name"`
}
```
### 生成代码 type (
// UserModel is an interface to be customized, add more methods here,
生成代码的方式有两种 // and implement the added methods in customUserModel.
UserModel interface {
userModel
}
* 命令行生成 在types.go所在文件夹执行命令 customUserModel struct {
```shell *defaultUserModel
$ goctl model mongo -t User -style gozero }
``` )
* 在types.go中添加`//go:generate`,然后点击执行按钮即可生成,内容示例如下:
```golang
//go:generate goctl model mongo -t User
```
### 生成示例代码 // 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),
}
}
* usermodel.go ```
```golang #### usermodelgen.go
package model ```go
// Code generated by goctl. DO NOT EDIT!
package model
import ( import (
"context" "context"
"time"
"github.com/globalsign/mgo/bson" "github.com/zeromicro/go-zero/core/stores/monc"
cachec "github.com/zeromicro/go-zero/core/stores/cache" "go.mongodb.org/mongo-driver/bson"
"github.com/zeromicro/go-zero/core/stores/mongoc" "go.mongodb.org/mongo-driver/bson/primitive"
) )
type UserModel interface { var prefixUserCacheKey = "cache:user:"
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 { type userModel interface {
return &defaultUserModel{ Insert(ctx context.Context, data *User) error
Model: mongoc.MustNewModel(url, collection, c), FindOne(ctx context.Context, id string) (*User, error)
} Update(ctx context.Context, data *User) error
} Delete(ctx context.Context, id string) error
}
func (m *defaultUserModel) Insert(data *User, ctx context.Context) error { type defaultUserModel struct {
if !data.ID.Valid() { conn *monc.Model
data.ID = bson.NewObjectId() }
}
session, err := m.TakeSession() func newDefaultUserModel(conn *monc.Model) *defaultUserModel {
if err != nil { return &defaultUserModel{conn: conn}
return err }
}
defer m.PutSession(session) func (m *defaultUserModel) Insert(ctx context.Context, data *User) error {
return m.GetCollection(session).Insert(data) if !data.ID.IsZero() {
data.ID = primitive.NewObjectID()
data.CreateAt = time.Now()
data.UpdateAt = time.Now()
} }
func (m *defaultUserModel) FindOne(id string, ctx context.Context) (*User, error) { key := prefixUserCacheKey + data.ID.Hex()
if !bson.IsObjectIdHex(id) { _, err := m.conn.InsertOne(ctx, key, data)
return nil, ErrInvalidObjectId return err
} }
session, err := m.TakeSession() func (m *defaultUserModel) FindOne(ctx context.Context, id string) (*User, error) {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil { if err != nil {
return nil, err return nil, ErrInvalidObjectId
} }
defer m.PutSession(session)
var data User var data User
key := prefixUserCacheKey + data.ID.Hex()
err = m.GetCollection(session).FindOneIdNoCache(&data, bson.ObjectIdHex(id)) err = m.conn.FindOne(ctx, key, &data, bson.M{"_id": oid})
switch err { switch err {
case nil: case nil:
return &data, nil return &data, nil
case mongoc.ErrNotFound: case monc.ErrNotFound:
return nil, ErrNotFound return nil, ErrNotFound
default: default:
return nil, err return nil, err
} }
} }
func (m *defaultUserModel) Update(data *User, ctx context.Context) error { func (m *defaultUserModel) Update(ctx context.Context, data *User) error {
session, err := m.TakeSession() data.UpdateAt = time.Now()
if err != nil { key := prefixUserCacheKey + data.ID.Hex()
_, err := m.conn.ReplaceOne(ctx, key, bson.M{"_id": data.ID}, data)
return err return err
}
func (m *defaultUserModel) Delete(ctx context.Context, id string) error {
oid, err := primitive.ObjectIDFromHex(id)
if err != nil {
return ErrInvalidObjectId
} }
key := prefixUserCacheKey + id
_, err = m.conn.DeleteOne(ctx, key, bson.M{"_id": oid})
return err
}
defer m.PutSession(session) ```
return m.GetCollection(session).UpdateIdNoCache(data.ID, data) #### usertypes.go
} ```go
package model
func (m *defaultUserModel) Delete(id string, ctx context.Context) error { import (
session, err := m.TakeSession() "time"
if err != nil {
return err
}
defer m.PutSession(session) "go.mongodb.org/mongo-driver/bson/primitive"
)
return m.GetCollection(session).RemoveIdNoCache(bson.ObjectIdHex(id)) 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"`
}
```
* error.go #### error.go
```go
package model
```golang import (
package model "errors"
import "errors" "github.com/zeromicro/go-zero/core/stores/mon"
)
var ErrNotFound = errors.New("not found") var (
var ErrInvalidObjectId = errors.New("invalid objectId") ErrNotFound = mon.ErrNotFound
``` ErrInvalidObjectId = errors.New("invalid objectId")
)
```
### 文件目录预览 ### 文件目录预览
```text ```text
. .
├── error.go ├── error.go
├── types.go ├── usermodel.go
└── usermodel.go ├── usermodelgen.go
└── usertypes.go
``` ```
## 命令预览 ## 命令预览
```text ```text
NAME: Generate mongo model
goctl model - generate model code
Usage:
USAGE: goctl model mongo [flags]
goctl model command [command options] [arguments...]
Flags:
COMMANDS: --branch string The branch of the remote repo, it does work with --remote
mysql generate mysql model -c, --cache Generate code with cache [optional]
mongo generate mongo model -d, --dir string The target dir
-h, --help help for mongo
OPTIONS: --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
--help, -h show help --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]
```text -t, --type strings Specified model type name
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/zeromicro/go-zero/tree/master/tools/goctl/config/readme.md]
``` ```
> 温馨提示 > 温馨提示
> >
> `--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,16 +1,18 @@
// 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
@ -18,81 +20,58 @@ type {{.Type}}Model interface{
} }
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}}
_, err := m.conn.ReplaceOne(ctx, {{if .Cache}}key, {{end}}bson.M{"_id": data.ID}, data)
return err 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