diff --git a/tools/goctl/model/sql/README.MD b/tools/goctl/model/sql/README.MD index 5f6c2bb9..1a9925b7 100644 --- a/tools/goctl/model/sql/README.MD +++ b/tools/goctl/model/sql/README.MD @@ -26,7 +26,8 @@ goctl model 为go-zero下的工具模块中的组件之一,目前支持识别m * 生成代码示例 - ``` go + ```go + package model import ( @@ -48,9 +49,9 @@ goctl model 为go-zero下的工具模块中的组件之一,目前支持识别m userRowsExpectAutoSet = strings.Join(stringx.Remove(userFieldNames, "id", "create_time", "update_time"), ",") userRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, "id", "create_time", "update_time"), "=?,") + "=?" - cacheUserMobilePrefix = "cache#User#mobile#" cacheUserIdPrefix = "cache#User#id#" cacheUserNamePrefix = "cache#User#name#" + cacheUserMobilePrefix = "cache#User#mobile#" ) type ( @@ -71,23 +72,28 @@ goctl model 为go-zero下的工具模块中的组件之一,目前支持识别m } ) - func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf, table string) *UserModel { + func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) *UserModel { return &UserModel{ CachedConn: sqlc.NewConn(conn, c), - table: table, + table: "user", } } func (m *UserModel) Insert(data User) (sql.Result, error) { - query := `insert into ` + m.table + `(` + userRowsExpectAutoSet + `) value (?, ?, ?, ?, ?)` - return m.ExecNoCache(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname) + userNameKey := fmt.Sprintf("%s%v", cacheUserNamePrefix, data.Name) + userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile) + ret, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { + query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?)", m.table, userRowsExpectAutoSet) + return conn.Exec(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname) + }, userNameKey, userMobileKey) + return ret, err } func (m *UserModel) FindOne(id int64) (*User, error) { userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, id) var resp User err := m.QueryRow(&resp, userIdKey, func(conn sqlx.SqlConn, v interface{}) error { - query := `select ` + userRows + ` from ` + m.table + ` where id = ? limit 1` + query := fmt.Sprintf("select %s from %s where id = ? limit 1", userRows, m.table) return conn.QueryRow(v, query, id) }) switch err { @@ -103,18 +109,13 @@ goctl model 为go-zero下的工具模块中的组件之一,目前支持识别m func (m *UserModel) FindOneByName(name string) (*User, error) { userNameKey := fmt.Sprintf("%s%v", cacheUserNamePrefix, name) var resp User - err := m.QueryRowIndex(&resp, userNameKey, func(primary interface{}) string { - return fmt.Sprintf("%s%v", cacheUserIdPrefix, primary) - }, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { - query := `select ` + userRows + ` from ` + m.table + ` where name = ? limit 1` + err := m.QueryRowIndex(&resp, userNameKey, m.formatPrimary, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { + query := fmt.Sprintf("select %s from %s where name = ? limit 1", userRows, m.table) if err := conn.QueryRow(&resp, query, name); err != nil { return nil, err } return resp.Id, nil - }, func(conn sqlx.SqlConn, v, primary interface{}) error { - query := `select ` + userRows + ` from ` + m.table + ` where id = ? limit 1` - return conn.QueryRow(v, query, primary) - }) + }, m.queryPrimary) switch err { case nil: return &resp, nil @@ -128,18 +129,13 @@ goctl model 为go-zero下的工具模块中的组件之一,目前支持识别m func (m *UserModel) FindOneByMobile(mobile string) (*User, error) { userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, mobile) var resp User - err := m.QueryRowIndex(&resp, userMobileKey, func(primary interface{}) string { - return fmt.Sprintf("%s%v", cacheUserIdPrefix, primary) - }, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { - query := `select ` + userRows + ` from ` + m.table + ` where mobile = ? limit 1` + err := m.QueryRowIndex(&resp, userMobileKey, m.formatPrimary, func(conn sqlx.SqlConn, v interface{}) (i interface{}, e error) { + query := fmt.Sprintf("select %s from %s where mobile = ? limit 1", userRows, m.table) if err := conn.QueryRow(&resp, query, mobile); err != nil { return nil, err } return resp.Id, nil - }, func(conn sqlx.SqlConn, v, primary interface{}) error { - query := `select ` + userRows + ` from ` + m.table + ` where id = ? limit 1` - return conn.QueryRow(v, query, primary) - }) + }, m.queryPrimary) switch err { case nil: return &resp, nil @@ -153,7 +149,7 @@ goctl model 为go-zero下的工具模块中的组件之一,目前支持识别m func (m *UserModel) Update(data User) error { userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, data.Id) _, err := m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { - query := `update ` + m.table + ` set ` + userRowsWithPlaceHolder + ` where id = ?` + query := fmt.Sprintf("update %s set %s where id = ?", m.table, userRowsWithPlaceHolder) return conn.Exec(query, data.Name, data.Password, data.Mobile, data.Gender, data.Nickname, data.Id) }, userIdKey) return err @@ -164,16 +160,26 @@ goctl model 为go-zero下的工具模块中的组件之一,目前支持识别m if err != nil { return err } + + userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile) userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, id) userNameKey := fmt.Sprintf("%s%v", cacheUserNamePrefix, data.Name) - userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile) _, err = m.Exec(func(conn sqlx.SqlConn) (result sql.Result, err error) { - query := `delete from ` + m.table + ` where id = ?` + query := fmt.Sprintf("delete from %s where id = ?", m.table) return conn.Exec(query, id) - }, userIdKey, userNameKey, userMobileKey) + }, userMobileKey, userIdKey, userNameKey) return err } - ``` + + func (m *UserModel) formatPrimary(primary interface{}) string { + return fmt.Sprintf("%s%v", cacheUserIdPrefix, primary) + } + + func (m *UserModel) queryPrimary(conn sqlx.SqlConn, v, primary interface{}) error { + query := fmt.Sprintf("select %s from %s where id = ? limit 1", userRows, m.table) + return conn.QueryRow(v, query, primary) + } + ``` ## 用法 @@ -212,16 +218,18 @@ OPTIONS: ``` NAME: - goctl model mysql ddl - generate mysql model from ddl + goctl model mysql ddl - generate mysql model from ddl - USAGE: - goctl model mysql ddl [command options] [arguments...] + USAGE: + goctl model mysql ddl [command options] [arguments...] + + OPTIONS: + --src value, -s value the path or path globbing patterns of the ddl + --dir value, -d value the target dir + --style value the file naming style, lower|camel|underline,default is lower + --cache, -c generate code with cache [optional] + --idea for idea plugin [optional] - OPTIONS: - --src value, -s value the path or path globbing patterns of the ddl - --dir value, -d value the target dir - --cache, -c generate code with cache [optional] - --idea for idea plugin [optional] ``` * datasource @@ -233,22 +241,26 @@ OPTIONS: help ``` - NAME: - goctl model mysql datasource - generate model from datasource + NAME: + goctl model mysql datasource - generate model from datasource - USAGE: - goctl model mysql datasource [command options] [arguments...] + USAGE: + goctl model mysql datasource [command options] [arguments...] + + OPTIONS: + --url value the data source of database,like "root:password@tcp(127.0.0.1:3306)/database + --table value, -t value the table or table globbing patterns in the database + --cache, -c generate code with cache [optional] + --dir value, -d value the target dir + --style value the file naming style, lower|camel|snake, default is lower + --idea for idea plugin [optional] - OPTIONS: - --url value the data source of database,like "root:password@tcp(127.0.0.1:3306)/database - --table value, -t value the table or table globbing patterns in the database - --cache, -c generate code with cache [optional] - --dir value, -d value the target dir - --idea for idea plugin [optional] ``` 示例用法请参考[用法](./example/generator.sh) + > NOTE: goctl model mysql ddl/datasource 均新增了一个`--style`参数,用于标记文件命名风格。 + 目前仅支持redis缓存,如果选择带缓存模式,即生成的`FindOne(ByXxx)`&`Delete`代码会生成带缓存逻辑的代码,目前仅支持单索引字段(除全文索引外),对于联合索引我们默认认为不需要带缓存,且不属于通用型代码,因此没有放在代码生成行列,如example中user表中的`id`、`name`、`mobile`字段均属于单字段索引。 * 不带缓存模式 diff --git a/tools/goctl/rpc/README.md b/tools/goctl/rpc/README.md index d9a35e4f..ba546f55 100644 --- a/tools/goctl/rpc/README.md +++ b/tools/goctl/rpc/README.md @@ -26,26 +26,49 @@ Goctl Rpc是`goctl`脚手架下的一个rpc服务代码生成模块,支持prot ```golang . -├── etc // 配置文件 -│   └── greet.yaml +├── etc // yaml配置文件 +│ └── greet.yaml ├── go.mod -├── greet // client call -│   └── greet.go -├── greet.go // main entry -├── greet.proto -└── internal - ├── config // 配置声明 - │   └── config.go - ├── greet // pb.go - │   └── greet.pb.go - ├── logic // logic - │   └── pinglogic.go - ├── server // pb invoker - │   └── greetserver.go - └── svc // resource dependency +├── greet // pb.go文件夹① +│ └── greet.pb.go +├── greet.go // main函数 +├── greet.proto // proto 文件 +├── greetclient // call logic ② +│ └── greet.go +└── internal + ├── config // yaml配置对应的实体 + │ └── config.go + ├── logic // 业务代码 + │ └── pinglogic.go + ├── server // rpc server + │ └── greetserver.go + └── svc // 依赖资源 └── servicecontext.go ``` +> ① pb文件夹名(老版本文件夹固定为pb)称取自于proto文件中option go_package的值最后一层级按照一定格式进行转换,若无此声明,则取自于package的值,大致代码如下: + +```go + if option.Name == "go_package" { + ret.GoPackage = option.Constant.Source + } + ... + if len(ret.GoPackage) == 0 { + ret.GoPackage = ret.Package.Name + } + ret.PbPackage = GoSanitized(filepath.Base(ret.GoPackage)) + ... +``` +> GoSanitized方法请参考google.golang.org/protobuf@v1.25.0/internal/strs/strings.go:71 + +> ② call 层文件夹名称取自于proto中service的名称,如该sercice的名称和pb文件夹名称相等,则会在srervice后面补充client进行区分,使pb和call分隔。 + +```go +if strings.ToLower(proto.Service.Name) == strings.ToLower(proto.GoPackage) { + callDir = filepath.Join(ctx.WorkDir, strings.ToLower(stringx.From(proto.Service.Name+"_client").ToCamel())) +} +``` + rpc一键生成常见问题解决,见 常见问题解决 ### 方式二:通过指定proto生成rpc服务 @@ -110,8 +133,8 @@ USAGE: OPTIONS: --src value, -s value the file path of the proto source file - --proto_path value, -I value native command of protoc,specify the directory in which to search for imports. [optional] - --dir value, -d value the target path of the code,default path is "${pwd}". [optional] + --proto_path value, -I value native command of protoc, specify the directory in which to search for imports. [optional] + --dir value, -d value the target path of the code --idea whether the command execution environment is from idea plugin. [optional] ```