diff --git a/tools/goctl/api/gogen/genhandlers.go b/tools/goctl/api/gogen/genhandlers.go index 4dd17f24..f3e0b7a6 100644 --- a/tools/goctl/api/gogen/genhandlers.go +++ b/tools/goctl/api/gogen/genhandlers.go @@ -7,6 +7,7 @@ import ( "github.com/tal-tech/go-zero/tools/goctl/api/spec" "github.com/tal-tech/go-zero/tools/goctl/config" + "github.com/tal-tech/go-zero/tools/goctl/internal/env" "github.com/tal-tech/go-zero/tools/goctl/util" "github.com/tal-tech/go-zero/tools/goctl/util/format" "github.com/tal-tech/go-zero/tools/goctl/vars" @@ -17,6 +18,7 @@ const handlerTemplate = `package handler import ( "net/http" + {{if .After1_1_10}}"github.com/tal-tech/go-zero/rest/httpx"{{end}} {{.ImportPackages}} ) @@ -47,6 +49,7 @@ type handlerInfo struct { Call string HasResp bool HasRequest bool + After1_1_10 bool } func genHandler(dir, rootPkg string, cfg *config.Config, group spec.Group, route spec.Route) error { @@ -55,9 +58,13 @@ func genHandler(dir, rootPkg string, cfg *config.Config, group spec.Group, route handler = strings.Title(handler) } + goctlVersion := env.GetGoctlVersion() + // todo(anqiansong): This will be removed after a certain number of production versions of goctl (probably 5) + after1_1_10 := env.IsVersionGatherThan(goctlVersion, "1.1.10") return doGenToFile(dir, handler, cfg, group, route, handlerInfo{ ImportPackages: genHandlerImports(group, route, rootPkg), HandlerName: handler, + After1_1_10: after1_1_10, RequestType: util.Title(route.RequestTypeName()), LogicType: strings.Title(getLogicName(route)), Call: strings.Title(strings.TrimSuffix(handler, "Handler")), @@ -105,7 +112,12 @@ func genHandlerImports(group spec.Group, route spec.Route, parentPkg string) str if len(route.RequestTypeName()) > 0 { imports = append(imports, fmt.Sprintf("\"%s\"\n", util.JoinPackages(parentPkg, typesDir))) } - imports = append(imports, fmt.Sprintf("\"%s/rest/httpx\"", vars.ProjectOpenSourceURL)) + + currentVersion := env.GetGoctlVersion() + // todo(anqiansong): This will be removed after a certain number of production versions of goctl (probably 5) + if !env.IsVersionGatherThan(currentVersion, "1.1.10") { + imports = append(imports, fmt.Sprintf("\"%s/rest/httpx\"", vars.ProjectOpenSourceURL)) + } return strings.Join(imports, "\n\t") } diff --git a/tools/goctl/goctl.go b/tools/goctl/goctl.go index 108ccd7c..96ac1b29 100644 --- a/tools/goctl/goctl.go +++ b/tools/goctl/goctl.go @@ -32,7 +32,7 @@ import ( ) var ( - buildVersion = "1.1.10" + buildVersion = "1.1.11-beta" commands = []cli.Command{ { Name: "upgrade", @@ -655,3 +655,7 @@ func main() { fmt.Println(aurora.Red("error: " + err.Error())) } } + +func init() { + os.Setenv("GOCTL_VERSION", buildVersion) +} diff --git a/tools/goctl/internal/env/env.go b/tools/goctl/internal/env/env.go new file mode 100644 index 00000000..d0de1cae --- /dev/null +++ b/tools/goctl/internal/env/env.go @@ -0,0 +1,59 @@ +package env + +import ( + "encoding/json" + "os" + "strings" +) + +// GetGoctlVersion obtains from the environment variable GOCTL_VERSION, prior to 1.1.11, +// the goctl version was 1.1.10 by default. +// the goctl version is set at runtime in the environment variable GOCTL_VERSION, +// see the detail at https://github.com/tal-tech/go-zero/blob/master/tools/goctl/goctl.go +func GetGoctlVersion() string { + currentVersion := os.Getenv("GOCTL_VERSION") + if currentVersion == "" { + currentVersion = "1.1.10" + } + return currentVersion +} + +var tag = map[string]int{"pre-alpha": 0, "alpha": 1, "pre-bata": 2, "beta": 3, "released": 4, "": 5} + +// IsVersionGatherThan compares whether the current goctl version +// is gather than the target version +func IsVersionGatherThan(version, target string) bool { + versionNumber, versionTag := convertVersion(version) + targetVersionNumber, targetTag := convertVersion(target) + if versionNumber > targetVersionNumber { + return true + } else if versionNumber < targetVersionNumber { + return false + } else { // unchecked case, in normal, the goctl version does not contains suffix in release. + return tag[versionTag] > tag[targetTag] + } +} + +// version format: number[.number]*(-tag) +func convertVersion(version string) (versionNumber float64, tag string) { + splits := strings.Split(version, "-") + tag = strings.Join(splits[1:], "") + var flag bool + numberStr := strings.Map(func(r rune) rune { + if r >= '0' && r <= '9' { + return r + } + + if r == '.' { + if flag { + return '_' + } + flag = true + return r + } + return '_' + }, splits[0]) + numberStr = strings.ReplaceAll(numberStr, "_", "") + versionNumber, _ = json.Number(numberStr).Float64() + return +} diff --git a/tools/goctl/internal/env/env_test.go b/tools/goctl/internal/env/env_test.go new file mode 100644 index 00000000..308ed043 --- /dev/null +++ b/tools/goctl/internal/env/env_test.go @@ -0,0 +1,33 @@ +package env + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_convertVersion(t *testing.T) { + number, tag := convertVersion("1.1.10") + assert.Equal(t, 1.110, number) + assert.Equal(t, "", tag) + + number, tag = convertVersion("0.1.11") + assert.Equal(t, 0.111, number) + assert.Equal(t, "", tag) + + number, tag = convertVersion("1.11-pre") + assert.Equal(t, 1.11, number) + assert.Equal(t, "pre", tag) + + number, tag = convertVersion("1.11-beta-v1") + assert.Equal(t, 1.11, number) + assert.Equal(t, "betav1", tag) +} + +func Test_IsVersionGatherThan(t *testing.T) { + assert.False(t, IsVersionGatherThan("0.11", "1.1")) + assert.True(t, IsVersionGatherThan("0.112", "0.1")) + assert.True(t, IsVersionGatherThan("1.1.10", "1.0.111")) + assert.True(t, IsVersionGatherThan("1.1.10", "1.1.10-pre")) + assert.True(t, IsVersionGatherThan("1.1.11-pre", "1.1.10")) +} diff --git a/tools/goctl/model/sql/README.MD b/tools/goctl/model/sql/README.MD index 6f98f630..944caaf5 100644 --- a/tools/goctl/model/sql/README.MD +++ b/tools/goctl/model/sql/README.MD @@ -49,10 +49,10 @@ 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"), "=?,") + "=?" - cacheUserPrefix = "cache#User#user#" - cacheUserNamePrefix = "cache#User#name#" - cacheUserMobilePrefix = "cache#User#mobile#" - cacheUserIdPrefix = "cache#User#id#" + cacheUserPrefix = "cache:User:user:" + cacheUserNamePrefix = "cache:User:name:" + cacheUserMobilePrefix = "cache:User:mobile:" + cacheUserIdPrefix = "cache:User:id:" ) type ( @@ -349,7 +349,8 @@ OPTIONS: 目前,我认为除了基本的CURD外,其他的代码均属于业务型代码,这个我觉得开发人员根据业务需要进行编写更好。 # 类型转换规则 -| mysql dataType | golang dataType | golang dataType(if null&&default null) | + +| mysql dataType | golang dataType | golang Null dataType | |----------------|-----------------|----------------------------------------| | bool | int64 | sql.NullInt64 | | boolean | int64 | sql.NullInt64 | diff --git a/tools/goctl/model/sql/example/sql/user.sql b/tools/goctl/model/sql/example/sql/user.sql index f33c097a..3a6b4241 100644 --- a/tools/goctl/model/sql/example/sql/user.sql +++ b/tools/goctl/model/sql/example/sql/user.sql @@ -17,14 +17,16 @@ CREATE TABLE `user` UNIQUE KEY `mobile_index` (`mobile`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; -CREATE TABLE `student` ( - `id` bigint NOT NULL AUTO_INCREMENT, - `class` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '', - `name` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '', - `age` tinyint DEFAULT NULL, - `score` float(10,0) DEFAULT NULL, +CREATE TABLE `student` +( + `id` bigint NOT NULL, + `class` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '', + `name` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '', + `age` tinyint DEFAULT NULL, + `score` float(10, 0 +) DEFAULT NULL, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE, UNIQUE KEY `class_name_index` (`class`,`name`) -) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; \ No newline at end of file diff --git a/tools/goctl/model/sql/parser/parser.go b/tools/goctl/model/sql/parser/parser.go index 4327fc2d..27821024 100644 --- a/tools/goctl/model/sql/parser/parser.go +++ b/tools/goctl/model/sql/parser/parser.go @@ -180,6 +180,7 @@ func convertColumns(columns []*parser.Column, primaryColumn string) (Primary, ma var ( primaryKey Primary fieldM = make(map[string]*Field) + log = console.NewColorConsole() ) for _, column := range columns { @@ -194,8 +195,12 @@ func convertColumns(columns []*parser.Column, primaryColumn string) (Primary, ma if column.Constraint != nil { comment = column.Constraint.Comment - isDefaultNull = !column.Constraint.HasDefaultValue - if column.Name == primaryColumn && column.Constraint.AutoIncrement { + isDefaultNull = !column.Constraint.NotNull + if !column.Constraint.NotNull && column.Constraint.HasDefaultValue { + isDefaultNull = false + } + + if column.Name == primaryColumn { isDefaultNull = false } } @@ -205,6 +210,16 @@ func convertColumns(columns []*parser.Column, primaryColumn string) (Primary, ma return Primary{}, nil, err } + if column.Constraint != nil { + if column.Name == primaryColumn { + if !column.Constraint.AutoIncrement && dataType == "int64" { + log.Warning("%s: The primary key is recommended to add constraint `AUTO_INCREMENT`", column.Name) + } + } else if column.Constraint.NotNull && !column.Constraint.HasDefaultValue { + log.Warning("%s: The column is recommended to add constraint `DEFAULT`", column.Name) + } + } + var field Field field.Name = stringx.From(column.Name) field.DataType = dataType