mirror of
https://github.com/zeromicro/go-zero.git
synced 2025-01-23 09:00:20 +08:00
(goctl)feature/model config (#4062)
Co-authored-by: Kevin Wan <wanjunfeng@gmail.com>
This commit is contained in:
parent
682460c1c8
commit
2a7ada993b
@ -13,6 +13,7 @@ import (
|
|||||||
"github.com/withfig/autocomplete-tools/integrations/cobra"
|
"github.com/withfig/autocomplete-tools/integrations/cobra"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/api"
|
"github.com/zeromicro/go-zero/tools/goctl/api"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/bug"
|
"github.com/zeromicro/go-zero/tools/goctl/bug"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/config"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/docker"
|
"github.com/zeromicro/go-zero/tools/goctl/docker"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/env"
|
"github.com/zeromicro/go-zero/tools/goctl/env"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/gateway"
|
"github.com/zeromicro/go-zero/tools/goctl/gateway"
|
||||||
@ -113,7 +114,7 @@ func init() {
|
|||||||
|
|
||||||
rootCmd.SetUsageTemplate(usageTpl)
|
rootCmd.SetUsageTemplate(usageTpl)
|
||||||
rootCmd.AddCommand(api.Cmd, bug.Cmd, docker.Cmd, kube.Cmd, env.Cmd, gateway.Cmd, model.Cmd)
|
rootCmd.AddCommand(api.Cmd, bug.Cmd, docker.Cmd, kube.Cmd, env.Cmd, gateway.Cmd, model.Cmd)
|
||||||
rootCmd.AddCommand(migrate.Cmd, quickstart.Cmd, rpc.Cmd, tpl.Cmd, upgrade.Cmd)
|
rootCmd.AddCommand(migrate.Cmd, quickstart.Cmd, rpc.Cmd, tpl.Cmd, upgrade.Cmd, config.Cmd)
|
||||||
rootCmd.Command.AddCommand(cobracompletefig.CreateCompletionSpecCommand())
|
rootCmd.Command.AddCommand(cobracompletefig.CreateCompletionSpecCommand())
|
||||||
rootCmd.MustInit()
|
rootCmd.MustInit()
|
||||||
}
|
}
|
||||||
|
59
tools/goctl/config/cmd.go
Normal file
59
tools/goctl/config/cmd.go
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/internal/cobrax"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Cmd describes a bug command.
|
||||||
|
Cmd = cobrax.NewCommand("config")
|
||||||
|
|
||||||
|
initCmd = cobrax.NewCommand("init", cobrax.WithRunE(runConfigInit))
|
||||||
|
cleanCmd = cobrax.NewCommand("clean", cobrax.WithRunE(runConfigClean))
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
Cmd.AddCommand(initCmd, cleanCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func runConfigInit(*cobra.Command, []string) error {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgFile, err := getConfigPath(wd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if pathx.FileExists(cfgFile) {
|
||||||
|
fmt.Printf("%s already exists, path: %s\n", configFile, cfgFile)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err = os.WriteFile(cfgFile, defaultConfig, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("%s generated in %s\n", configFile, cfgFile)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runConfigClean(*cobra.Command, []string) error {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgFile, err := getConfigPath(wd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pathx.RemoveIfExist(cfgFile)
|
||||||
|
}
|
@ -1,25 +1,71 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_ "embed"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/util/ctx"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultFormat defines a default naming style
|
const (
|
||||||
const DefaultFormat = "gozero"
|
// DefaultFormat defines a default naming style
|
||||||
|
DefaultFormat = "gozero"
|
||||||
|
configFile = "goctl.yaml"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
//go:embed default.yaml
|
||||||
|
defaultConfig []byte
|
||||||
|
|
||||||
|
ExternalConfig *External
|
||||||
|
)
|
||||||
|
|
||||||
// Config defines the file naming style
|
// Config defines the file naming style
|
||||||
type Config struct {
|
type (
|
||||||
// NamingFormat is used to define the naming format of the generated file name.
|
Config struct {
|
||||||
// just like time formatting, you can specify the formatting style through the
|
// NamingFormat is used to define the naming format of the generated file name.
|
||||||
// two format characters go, and zero. for example: snake format you can
|
// just like time formatting, you can specify the formatting style through the
|
||||||
// define as go_zero, camel case format you can it is defined as goZero,
|
// two format characters go, and zero. for example: snake format you can
|
||||||
// and even split characters can be specified, such as go#zero. in theory,
|
// define as go_zero, camel case format you can it is defined as goZero,
|
||||||
// any combination can be used, but the prerequisite must meet the naming conventions
|
// and even split characters can be specified, such as go#zero. in theory,
|
||||||
// of each operating system file name.
|
// any combination can be used, but the prerequisite must meet the naming conventions
|
||||||
// Note: NamingFormat is based on snake or camel string
|
// of each operating system file name.
|
||||||
NamingFormat string `yaml:"namingFormat"`
|
// Note: NamingFormat is based on snake or camel string
|
||||||
}
|
NamingFormat string `yaml:"namingFormat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
External struct {
|
||||||
|
// Model is the configuration for the model code generation.
|
||||||
|
Model Model `yaml:"model,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Model defines the configuration for the model code generation.
|
||||||
|
Model struct {
|
||||||
|
// TypesMap: custom Data Type Mapping Table.
|
||||||
|
TypesMap map[string]ModelTypeMapOption `yaml:"types_map,omitempty" `
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModelTypeMapOption custom Type Options.
|
||||||
|
ModelTypeMapOption struct {
|
||||||
|
// Type: valid when not using UnsignedType and NullType.
|
||||||
|
Type string `yaml:"type"`
|
||||||
|
|
||||||
|
// UnsignedType: valid when not using NullType.
|
||||||
|
UnsignedType string `yaml:"unsigned_type,omitempty"`
|
||||||
|
|
||||||
|
// NullType: priority use.
|
||||||
|
NullType string `yaml:"null_type,omitempty"`
|
||||||
|
|
||||||
|
// Pkg defines the package of the custom type.
|
||||||
|
Pkg string `yaml:"pkg,omitempty"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// NewConfig creates an instance for Config
|
// NewConfig creates an instance for Config
|
||||||
func NewConfig(format string) (*Config, error) {
|
func NewConfig(format string) (*Config, error) {
|
||||||
@ -31,6 +77,58 @@ func NewConfig(format string) (*Config, error) {
|
|||||||
return cfg, err
|
return cfg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var cfg External
|
||||||
|
err := loadConfig(&cfg)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err.Error())
|
||||||
|
} else {
|
||||||
|
ExternalConfig = &cfg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadConfig(cfg *External) error {
|
||||||
|
wd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cfgFile, err := getConfigPath(wd)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var content []byte
|
||||||
|
if pathx.FileExists(cfgFile) {
|
||||||
|
content, err = os.ReadFile(cfgFile)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(content) == 0 {
|
||||||
|
content = append(content, defaultConfig...)
|
||||||
|
}
|
||||||
|
return yaml.Unmarshal(content, cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// getConfigPath returns the configuration file path, but not create the file.
|
||||||
|
func getConfigPath(workDir string) (string, error) {
|
||||||
|
abs, err := filepath.Abs(workDir)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pathx.MkdirIfNotExist(abs)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
projectCtx, err := ctx.Prepare(abs)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return filepath.Join(projectCtx.Dir, configFile), nil
|
||||||
|
}
|
||||||
|
|
||||||
func validate(cfg *Config) error {
|
func validate(cfg *Config) error {
|
||||||
if len(strings.TrimSpace(cfg.NamingFormat)) == 0 {
|
if len(strings.TrimSpace(cfg.NamingFormat)) == 0 {
|
||||||
return errors.New("missing namingFormat")
|
return errors.New("missing namingFormat")
|
||||||
|
157
tools/goctl/config/default.yaml
Normal file
157
tools/goctl/config/default.yaml
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
model:
|
||||||
|
types_map:
|
||||||
|
bigint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
dec:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
decimal:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
double:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
float:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
float4:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
float8:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
int:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int1:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int2:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int3:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int4:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int8:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
integer:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
mediumint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
middleint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
smallint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
tinyint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
date:
|
||||||
|
null_type: sql.NullTime
|
||||||
|
type: time.Time
|
||||||
|
datetime:
|
||||||
|
null_type: sql.NullTime
|
||||||
|
type: time.Time
|
||||||
|
timestamp:
|
||||||
|
null_type: sql.NullTime
|
||||||
|
type: time.Time
|
||||||
|
time:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
year:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
bit:
|
||||||
|
null_type: sql.NullByte
|
||||||
|
type: byte
|
||||||
|
unsigned_type: byte
|
||||||
|
bool:
|
||||||
|
null_type: sql.NullBool
|
||||||
|
type: bool
|
||||||
|
boolean:
|
||||||
|
null_type: sql.NullBool
|
||||||
|
type: bool
|
||||||
|
char:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
varchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
nvarchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
nchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
character:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
longvarchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
linestring:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
multilinestring:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
binary:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
varbinary:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
tinytext:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
text:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
mediumtext:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
longtext:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
set:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
json:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
blob:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
longblob:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
mediumblob:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
tinyblob:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
@ -274,6 +274,14 @@
|
|||||||
},
|
},
|
||||||
"upgrade": {
|
"upgrade": {
|
||||||
"short": "Upgrade goctl to latest version"
|
"short": "Upgrade goctl to latest version"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"init": {
|
||||||
|
"short": "Initialize goctl config file"
|
||||||
|
},
|
||||||
|
"clean": {
|
||||||
|
"short": "Clean goctl config file"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"global": {
|
"global": {
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zeromicro/ddl-parser/parser"
|
"github.com/zeromicro/ddl-parser/parser"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/config"
|
||||||
|
"github.com/zeromicro/go-zero/tools/goctl/pkg/env"
|
||||||
)
|
)
|
||||||
|
|
||||||
var unsignedTypeMap = map[string]string{
|
var unsignedTypeMap = map[string]string{
|
||||||
@ -73,6 +75,63 @@ var commonMysqlDataTypeMapInt = map[int]string{
|
|||||||
parser.Boolean: "bool",
|
parser.Boolean: "bool",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var commonMysqlDataTypeMap = map[int]string{
|
||||||
|
// number
|
||||||
|
parser.Bit: "bit",
|
||||||
|
parser.TinyInt: "tinyint",
|
||||||
|
parser.SmallInt: "smallint",
|
||||||
|
parser.MediumInt: "mediumint",
|
||||||
|
parser.Int: "int",
|
||||||
|
parser.MiddleInt: "middleint",
|
||||||
|
parser.Int1: "int1",
|
||||||
|
parser.Int2: "int2",
|
||||||
|
parser.Int3: "int3",
|
||||||
|
parser.Int4: "int4",
|
||||||
|
parser.Int8: "int8",
|
||||||
|
parser.Integer: "integer",
|
||||||
|
parser.BigInt: "bigint",
|
||||||
|
parser.Float: "float",
|
||||||
|
parser.Float4: "float4",
|
||||||
|
parser.Float8: "float8",
|
||||||
|
parser.Double: "double",
|
||||||
|
parser.Decimal: "decimal",
|
||||||
|
parser.Dec: "dec",
|
||||||
|
parser.Fixed: "fixed",
|
||||||
|
parser.Numeric: "numeric",
|
||||||
|
parser.Real: "real",
|
||||||
|
// date&time
|
||||||
|
parser.Date: "date",
|
||||||
|
parser.DateTime: "datetime",
|
||||||
|
parser.Timestamp: "timestamp",
|
||||||
|
parser.Time: "time",
|
||||||
|
parser.Year: "year",
|
||||||
|
// string
|
||||||
|
parser.Char: "char",
|
||||||
|
parser.VarChar: "varchar",
|
||||||
|
parser.NVarChar: "nvarchar",
|
||||||
|
parser.NChar: "nchar",
|
||||||
|
parser.Character: "character",
|
||||||
|
parser.LongVarChar: "longvarchar",
|
||||||
|
parser.LineString: "linestring",
|
||||||
|
parser.MultiLineString: "multilinestring",
|
||||||
|
parser.Binary: "binary",
|
||||||
|
parser.VarBinary: "varbinary",
|
||||||
|
parser.TinyText: "tinytext",
|
||||||
|
parser.Text: "text",
|
||||||
|
parser.MediumText: "mediumtext",
|
||||||
|
parser.LongText: "longtext",
|
||||||
|
parser.Enum: "enum",
|
||||||
|
parser.Set: "set",
|
||||||
|
parser.Json: "json",
|
||||||
|
parser.Blob: "blob",
|
||||||
|
parser.LongBlob: "longblob",
|
||||||
|
parser.MediumBlob: "mediumblob",
|
||||||
|
parser.TinyBlob: "tinyblob",
|
||||||
|
// bool
|
||||||
|
parser.Bool: "bool",
|
||||||
|
parser.Boolean: "boolean",
|
||||||
|
}
|
||||||
|
|
||||||
var commonMysqlDataTypeMapString = map[string]string{
|
var commonMysqlDataTypeMapString = map[string]string{
|
||||||
// For consistency, all integer types are converted to int64
|
// For consistency, all integer types are converted to int64
|
||||||
// bool
|
// bool
|
||||||
@ -144,28 +203,79 @@ var commonMysqlDataTypeMapString = map[string]string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ConvertDataType converts mysql column type into golang type
|
// ConvertDataType converts mysql column type into golang type
|
||||||
func ConvertDataType(dataBaseType int, isDefaultNull, unsigned, strict bool) (string, error) {
|
func ConvertDataType(dataBaseType int, isDefaultNull, unsigned, strict bool) (string, string, error) {
|
||||||
tp, ok := commonMysqlDataTypeMapInt[dataBaseType]
|
if env.UseExperimental() {
|
||||||
if !ok {
|
tp, ok := commonMysqlDataTypeMap[dataBaseType]
|
||||||
return "", fmt.Errorf("unsupported database type: %v", dataBaseType)
|
if !ok {
|
||||||
|
return "", "", fmt.Errorf("unsupported database type: %v", dataBaseType)
|
||||||
|
}
|
||||||
|
|
||||||
|
goType, thirdPkg, _, err := ConvertStringDataType(tp, isDefaultNull, unsigned, strict)
|
||||||
|
return goType, thirdPkg, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return mayConvertNullType(tp, isDefaultNull, unsigned, strict), nil
|
// the following are the old version compatibility code.
|
||||||
|
tp, ok := commonMysqlDataTypeMapInt[dataBaseType]
|
||||||
|
if !ok {
|
||||||
|
return "", "", fmt.Errorf("unsupported database type: %v", dataBaseType)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mayConvertNullType(tp, isDefaultNull, unsigned, strict), "", nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConvertStringDataType converts mysql column type into golang type
|
// ConvertStringDataType converts mysql column type into golang type
|
||||||
func ConvertStringDataType(dataBaseType string, isDefaultNull, unsigned, strict bool) (
|
func ConvertStringDataType(dataBaseType string, isDefaultNull, unsigned, strict bool) (
|
||||||
goType string, isPQArray bool, err error) {
|
goType string, thirdPkg string, isPQArray bool, err error) {
|
||||||
|
if env.UseExperimental() {
|
||||||
|
customTp, thirdImport := convertDatatypeWithConfig(dataBaseType, isDefaultNull, unsigned)
|
||||||
|
if len(customTp) != 0 {
|
||||||
|
return customTp, thirdImport, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tp, ok := commonMysqlDataTypeMapString[strings.ToLower(dataBaseType)]
|
||||||
|
if !ok {
|
||||||
|
return "", "", false, fmt.Errorf("unsupported database type: %s", dataBaseType)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(dataBaseType, "_") {
|
||||||
|
return tp, "", true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return mayConvertNullType(tp, isDefaultNull, unsigned, strict), "", false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following are the old version compatibility code.
|
||||||
tp, ok := commonMysqlDataTypeMapString[strings.ToLower(dataBaseType)]
|
tp, ok := commonMysqlDataTypeMapString[strings.ToLower(dataBaseType)]
|
||||||
if !ok {
|
if !ok {
|
||||||
return "", false, fmt.Errorf("unsupported database type: %s", dataBaseType)
|
return "", "", false, fmt.Errorf("unsupported database type: %s", dataBaseType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(dataBaseType, "_") {
|
if strings.HasPrefix(dataBaseType, "_") {
|
||||||
return tp, true, nil
|
return tp, "", true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return mayConvertNullType(tp, isDefaultNull, unsigned, strict), false, nil
|
return mayConvertNullType(tp, isDefaultNull, unsigned, strict), "", false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertDatatypeWithConfig(dataBaseType string, isDefaultNull, unsigned bool) (string, string) {
|
||||||
|
if config.ExternalConfig == nil {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
opt, ok := config.ExternalConfig.Model.TypesMap[strings.ToLower(dataBaseType)]
|
||||||
|
if !ok || (len(opt.Type) == 0 && len(opt.UnsignedType) == 0 && len(opt.NullType) == 0) {
|
||||||
|
return "", ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if isDefaultNull {
|
||||||
|
if len(opt.NullType) != 0 {
|
||||||
|
return opt.NullType, opt.Pkg
|
||||||
|
}
|
||||||
|
} else if unsigned {
|
||||||
|
if len(opt.UnsignedType) != 0 {
|
||||||
|
return opt.UnsignedType, opt.Pkg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return opt.Type, opt.Pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
func mayConvertNullType(goDataType string, isDefaultNull, unsigned, strict bool) string {
|
func mayConvertNullType(goDataType string, isDefaultNull, unsigned, strict bool) string {
|
||||||
|
@ -8,23 +8,102 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestConvertDataType(t *testing.T) {
|
func TestConvertDataType(t *testing.T) {
|
||||||
v, err := ConvertDataType(parser.TinyInt, false, false, true)
|
v, _, err := ConvertDataType(parser.TinyInt, false, false, true)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "int64", v)
|
assert.Equal(t, "int64", v)
|
||||||
|
|
||||||
v, err = ConvertDataType(parser.TinyInt, false, true, true)
|
v, _, err = ConvertDataType(parser.TinyInt, false, true, true)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "uint64", v)
|
assert.Equal(t, "uint64", v)
|
||||||
|
|
||||||
v, err = ConvertDataType(parser.TinyInt, true, false, true)
|
v, _, err = ConvertDataType(parser.TinyInt, true, false, true)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "sql.NullInt64", v)
|
assert.Equal(t, "sql.NullInt64", v)
|
||||||
|
|
||||||
v, err = ConvertDataType(parser.Timestamp, false, false, true)
|
v, _, err = ConvertDataType(parser.Timestamp, false, false, true)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "time.Time", v)
|
assert.Equal(t, "time.Time", v)
|
||||||
|
|
||||||
v, err = ConvertDataType(parser.Timestamp, true, false, true)
|
v, _, err = ConvertDataType(parser.Timestamp, true, false, true)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, "sql.NullTime", v)
|
assert.Equal(t, "sql.NullTime", v)
|
||||||
|
|
||||||
|
v, _, err = ConvertDataType(parser.Decimal, false, false, true)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, "float64", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestConvertStringDataType(t *testing.T) {
|
||||||
|
type (
|
||||||
|
input struct {
|
||||||
|
dataType string
|
||||||
|
isDefaultNull bool
|
||||||
|
unsigned bool
|
||||||
|
strict bool
|
||||||
|
}
|
||||||
|
result struct {
|
||||||
|
goType string
|
||||||
|
thirdPkg string
|
||||||
|
isPQArray bool
|
||||||
|
}
|
||||||
|
)
|
||||||
|
var testData = []struct {
|
||||||
|
input input
|
||||||
|
want result
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
input: input{
|
||||||
|
dataType: "bigint",
|
||||||
|
isDefaultNull: false,
|
||||||
|
unsigned: false,
|
||||||
|
strict: false,
|
||||||
|
},
|
||||||
|
want: result{
|
||||||
|
goType: "int64",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: input{
|
||||||
|
dataType: "bigint",
|
||||||
|
isDefaultNull: true,
|
||||||
|
unsigned: false,
|
||||||
|
strict: false,
|
||||||
|
},
|
||||||
|
want: result{
|
||||||
|
goType: "sql.NullInt64",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: input{
|
||||||
|
dataType: "bigint",
|
||||||
|
isDefaultNull: false,
|
||||||
|
unsigned: true,
|
||||||
|
strict: false,
|
||||||
|
},
|
||||||
|
want: result{
|
||||||
|
goType: "uint64",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: input{
|
||||||
|
dataType: "_int2",
|
||||||
|
isDefaultNull: false,
|
||||||
|
unsigned: false,
|
||||||
|
strict: false,
|
||||||
|
},
|
||||||
|
want: result{
|
||||||
|
goType: "pq.Int64Array",
|
||||||
|
isPQArray: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, data := range testData {
|
||||||
|
tp, thirdPkg, isPQArray, err := ConvertStringDataType(data.input.dataType, data.input.isDefaultNull, data.input.unsigned, data.input.strict)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, data.want, result{
|
||||||
|
goType: tp,
|
||||||
|
thirdPkg: thirdPkg,
|
||||||
|
isPQArray: isPQArray,
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ CREATE TABLE `user`
|
|||||||
`mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号',
|
`mobile` varchar(255) COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '手机号',
|
||||||
`gender` char(5) COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公\r开',
|
`gender` char(5) COLLATE utf8mb4_general_ci NOT NULL COMMENT '男|女|未公\r开',
|
||||||
`nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称',
|
`nickname` varchar(255) COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '用户昵称',
|
||||||
`type` tinyint(1) COLLATE utf8mb4_general_ci DEFAULT 0 COMMENT '用户类型',
|
`type` tinyint(1) COLLATE utf8mb4_general_ci DEFAULT 0 COMMENT '用户类型',
|
||||||
`create_time` timestamp NULL,
|
`create_time` timestamp NULL,
|
||||||
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
@ -22,12 +22,13 @@ CREATE TABLE `user`
|
|||||||
|
|
||||||
CREATE TABLE `student`
|
CREATE TABLE `student`
|
||||||
(
|
(
|
||||||
`type` bigint NOT NULL,
|
`type` bigint NOT NULL,
|
||||||
`class` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
|
`class` varchar(255) NOT NULL DEFAULT '',
|
||||||
`name` varchar(255) COLLATE utf8mb4_bin NOT NULL DEFAULT '',
|
`name` varchar(255) NOT NULL DEFAULT '',
|
||||||
`age` tinyint DEFAULT NULL,
|
`age` tinyint DEFAULT NULL,
|
||||||
`score` float(10, 0
|
`score` float(10, 0
|
||||||
) DEFAULT NULL,
|
) DEFAULT NULL,
|
||||||
|
`amount` decimal DEFAULT NULL,
|
||||||
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`update_time` timestamp NULL DEFAULT NULL,
|
`update_time` timestamp NULL DEFAULT NULL,
|
||||||
`delete_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
`delete_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
@ -1,12 +1,27 @@
|
|||||||
package gen
|
package gen
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/model/sql/template"
|
"github.com/zeromicro/go-zero/tools/goctl/model/sql/template"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util"
|
"github.com/zeromicro/go-zero/tools/goctl/util"
|
||||||
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
|
||||||
)
|
)
|
||||||
|
|
||||||
func genImports(table Table, withCache, timeImport bool) (string, error) {
|
func genImports(table Table, withCache, timeImport bool) (string, error) {
|
||||||
|
var thirdImports []string
|
||||||
|
var m = map[string]struct{}{}
|
||||||
|
for _, c := range table.Fields {
|
||||||
|
if len(c.ThirdPkg) > 0 {
|
||||||
|
if _, ok := m[c.ThirdPkg]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m[c.ThirdPkg] = struct{}{}
|
||||||
|
thirdImports = append(thirdImports, fmt.Sprintf("%q", c.ThirdPkg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if withCache {
|
if withCache {
|
||||||
text, err := pathx.LoadTemplate(category, importsTemplateFile, template.Imports)
|
text, err := pathx.LoadTemplate(category, importsTemplateFile, template.Imports)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -17,6 +32,7 @@ func genImports(table Table, withCache, timeImport bool) (string, error) {
|
|||||||
"time": timeImport,
|
"time": timeImport,
|
||||||
"containsPQ": table.ContainsPQ,
|
"containsPQ": table.ContainsPQ,
|
||||||
"data": table,
|
"data": table,
|
||||||
|
"third": strings.Join(thirdImports, "\n"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -34,6 +50,7 @@ func genImports(table Table, withCache, timeImport bool) (string, error) {
|
|||||||
"time": timeImport,
|
"time": timeImport,
|
||||||
"containsPQ": table.ContainsPQ,
|
"containsPQ": table.ContainsPQ,
|
||||||
"data": table,
|
"data": table,
|
||||||
|
"third": strings.Join(thirdImports, "\n"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
@ -38,6 +38,7 @@ type (
|
|||||||
Field struct {
|
Field struct {
|
||||||
NameOriginal string
|
NameOriginal string
|
||||||
Name stringx.String
|
Name stringx.String
|
||||||
|
ThirdPkg string
|
||||||
DataType string
|
DataType string
|
||||||
Comment string
|
Comment string
|
||||||
SeqInIndex int
|
SeqInIndex int
|
||||||
@ -219,7 +220,7 @@ func convertColumns(columns []*parser.Column, primaryColumn string, strict bool)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dataType, err := converter.ConvertDataType(column.DataType.Type(), isDefaultNull, column.DataType.Unsigned(), strict)
|
dataType, thirdPkg, err := converter.ConvertDataType(column.DataType.Type(), isDefaultNull, column.DataType.Unsigned(), strict)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Primary{}, nil, err
|
return Primary{}, nil, err
|
||||||
}
|
}
|
||||||
@ -236,6 +237,7 @@ func convertColumns(columns []*parser.Column, primaryColumn string, strict bool)
|
|||||||
|
|
||||||
var field Field
|
var field Field
|
||||||
field.Name = stringx.From(column.Name)
|
field.Name = stringx.From(column.Name)
|
||||||
|
field.ThirdPkg = thirdPkg
|
||||||
field.DataType = dataType
|
field.DataType = dataType
|
||||||
field.Comment = util.TrimNewLine(comment)
|
field.Comment = util.TrimNewLine(comment)
|
||||||
|
|
||||||
@ -267,7 +269,7 @@ func (t *Table) ContainsTime() bool {
|
|||||||
func ConvertDataType(table *model.Table, strict bool) (*Table, error) {
|
func ConvertDataType(table *model.Table, strict bool) (*Table, error) {
|
||||||
isPrimaryDefaultNull := table.PrimaryKey.ColumnDefault == nil && table.PrimaryKey.IsNullAble == "YES"
|
isPrimaryDefaultNull := table.PrimaryKey.ColumnDefault == nil && table.PrimaryKey.IsNullAble == "YES"
|
||||||
isPrimaryUnsigned := strings.Contains(table.PrimaryKey.DbColumn.ColumnType, "unsigned")
|
isPrimaryUnsigned := strings.Contains(table.PrimaryKey.DbColumn.ColumnType, "unsigned")
|
||||||
primaryDataType, containsPQ, err := converter.ConvertStringDataType(table.PrimaryKey.DataType, isPrimaryDefaultNull, isPrimaryUnsigned, strict)
|
primaryDataType, thirdPkg, containsPQ, err := converter.ConvertStringDataType(table.PrimaryKey.DataType, isPrimaryDefaultNull, isPrimaryUnsigned, strict)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -285,6 +287,7 @@ func ConvertDataType(table *model.Table, strict bool) (*Table, error) {
|
|||||||
reply.PrimaryKey = Primary{
|
reply.PrimaryKey = Primary{
|
||||||
Field: Field{
|
Field: Field{
|
||||||
Name: stringx.From(table.PrimaryKey.Name),
|
Name: stringx.From(table.PrimaryKey.Name),
|
||||||
|
ThirdPkg: thirdPkg,
|
||||||
DataType: primaryDataType,
|
DataType: primaryDataType,
|
||||||
Comment: table.PrimaryKey.Comment,
|
Comment: table.PrimaryKey.Comment,
|
||||||
SeqInIndex: seqInIndex,
|
SeqInIndex: seqInIndex,
|
||||||
@ -351,7 +354,7 @@ func getTableFields(table *model.Table, strict bool) (map[string]*Field, error)
|
|||||||
for _, each := range table.Columns {
|
for _, each := range table.Columns {
|
||||||
isDefaultNull := each.ColumnDefault == nil && each.IsNullAble == "YES"
|
isDefaultNull := each.ColumnDefault == nil && each.IsNullAble == "YES"
|
||||||
isPrimaryUnsigned := strings.Contains(each.ColumnType, "unsigned")
|
isPrimaryUnsigned := strings.Contains(each.ColumnType, "unsigned")
|
||||||
dt, containsPQ, err := converter.ConvertStringDataType(each.DataType, isDefaultNull, isPrimaryUnsigned, strict)
|
dt, thirdPkg, containsPQ, err := converter.ConvertStringDataType(each.DataType, isDefaultNull, isPrimaryUnsigned, strict)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -363,6 +366,7 @@ func getTableFields(table *model.Table, strict bool) (map[string]*Field, error)
|
|||||||
field := &Field{
|
field := &Field{
|
||||||
NameOriginal: each.Name,
|
NameOriginal: each.Name,
|
||||||
Name: stringx.From(each.Name),
|
Name: stringx.From(each.Name),
|
||||||
|
ThirdPkg: thirdPkg,
|
||||||
DataType: dt,
|
DataType: dt,
|
||||||
Comment: each.Comment,
|
Comment: each.Comment,
|
||||||
SeqInIndex: columnSeqInIndex,
|
SeqInIndex: columnSeqInIndex,
|
||||||
|
@ -9,4 +9,6 @@ import (
|
|||||||
"github.com/zeromicro/go-zero/core/stores/builder"
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
"github.com/zeromicro/go-zero/core/stringx"
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
|
||||||
|
{{.third}}
|
||||||
)
|
)
|
||||||
|
@ -11,4 +11,6 @@ import (
|
|||||||
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
"github.com/zeromicro/go-zero/core/stringx"
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
|
||||||
|
{{.third}}
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user