Generate caches that support custom key prefix. (#4643)

This commit is contained in:
kesonan
2025-02-12 23:31:30 +08:00
committed by GitHub
parent 48d0709ca6
commit 7a4818da59
9 changed files with 60 additions and 45 deletions

View File

@@ -151,6 +151,7 @@
"short": "Generate mysql model", "short": "Generate mysql model",
"strict": "Generate model in strict mode", "strict": "Generate model in strict mode",
"ignore-columns": "Ignore columns while creating or updating rows", "ignore-columns": "Ignore columns while creating or updating rows",
"prefix": "The cache prefix, effective when --cache is true",
"datasource": { "datasource": {
"short": "Generate model from datasource", "short": "Generate model from datasource",
"url": "The data source of database,like \"root:password@tcp(127.0.0.1:3306)/database", "url": "The data source of database,like \"root:password@tcp(127.0.0.1:3306)/database",

View File

@@ -71,6 +71,7 @@ func init() {
mysqlCmd.PersistentFlags().BoolVar(&command.VarBoolStrict, "strict") mysqlCmd.PersistentFlags().BoolVar(&command.VarBoolStrict, "strict")
mysqlCmd.PersistentFlags().StringSliceVarPWithDefaultValue(&command.VarStringSliceIgnoreColumns, mysqlCmd.PersistentFlags().StringSliceVarPWithDefaultValue(&command.VarStringSliceIgnoreColumns,
"ignore-columns", "i", []string{"create_at", "created_at", "create_time", "update_at", "updated_at", "update_time"}) "ignore-columns", "i", []string{"create_at", "created_at", "create_time", "update_at", "updated_at", "update_time"})
mysqlCmd.PersistentFlags().StringVarPWithDefaultValue(&command.VarStringCachePrefix, "prefix", "p", "cache")
mysqlCmd.AddCommand(datasourceCmd, ddlCmd) mysqlCmd.AddCommand(datasourceCmd, ddlCmd)
pgCmd.AddCommand(pgDatasourceCmd) pgCmd.AddCommand(pgDatasourceCmd)

View File

@@ -50,6 +50,8 @@ var (
VarBoolStrict bool VarBoolStrict bool
// VarStringSliceIgnoreColumns represents the columns which are ignored. // VarStringSliceIgnoreColumns represents the columns which are ignored.
VarStringSliceIgnoreColumns []string VarStringSliceIgnoreColumns []string
// VarStringCachePrefix describes the prefix of cache.
VarStringCachePrefix string
) )
var errNotMatched = errors.New("sql not matched") var errNotMatched = errors.New("sql not matched")
@@ -57,6 +59,9 @@ var errNotMatched = errors.New("sql not matched")
// MysqlDDL generates model code from ddl // MysqlDDL generates model code from ddl
func MysqlDDL(_ *cobra.Command, _ []string) error { func MysqlDDL(_ *cobra.Command, _ []string) error {
migrationnotes.BeforeCommands(VarStringDir, VarStringStyle) migrationnotes.BeforeCommands(VarStringDir, VarStringStyle)
if VarBoolCache && len(VarStringCachePrefix) == 0 {
return errors.New("cache prefix is empty")
}
src := VarStringSrc src := VarStringSrc
dir := VarStringDir dir := VarStringDir
cache := VarBoolCache cache := VarBoolCache
@@ -89,6 +94,7 @@ func MysqlDDL(_ *cobra.Command, _ []string) error {
database: database, database: database,
strict: VarBoolStrict, strict: VarBoolStrict,
ignoreColumns: mergeColumns(VarStringSliceIgnoreColumns), ignoreColumns: mergeColumns(VarStringSliceIgnoreColumns),
prefix: VarStringCachePrefix,
} }
return fromDDL(arg) return fromDDL(arg)
} }
@@ -96,6 +102,9 @@ func MysqlDDL(_ *cobra.Command, _ []string) error {
// MySqlDataSource generates model code from datasource // MySqlDataSource generates model code from datasource
func MySqlDataSource(_ *cobra.Command, _ []string) error { func MySqlDataSource(_ *cobra.Command, _ []string) error {
migrationnotes.BeforeCommands(VarStringDir, VarStringStyle) migrationnotes.BeforeCommands(VarStringDir, VarStringStyle)
if VarBoolCache && len(VarStringCachePrefix) == 0 {
return errors.New("cache prefix is empty")
}
url := strings.TrimSpace(VarStringURL) url := strings.TrimSpace(VarStringURL)
dir := strings.TrimSpace(VarStringDir) dir := strings.TrimSpace(VarStringDir)
cache := VarBoolCache cache := VarBoolCache
@@ -130,6 +139,7 @@ func MySqlDataSource(_ *cobra.Command, _ []string) error {
idea: idea, idea: idea,
strict: VarBoolStrict, strict: VarBoolStrict,
ignoreColumns: mergeColumns(VarStringSliceIgnoreColumns), ignoreColumns: mergeColumns(VarStringSliceIgnoreColumns),
prefix: VarStringCachePrefix,
} }
return fromMysqlDataSource(arg) return fromMysqlDataSource(arg)
} }
@@ -225,6 +235,7 @@ type ddlArg struct {
database string database string
strict bool strict bool
ignoreColumns []string ignoreColumns []string
prefix string
} }
func fromDDL(arg ddlArg) error { func fromDDL(arg ddlArg) error {
@@ -243,7 +254,7 @@ func fromDDL(arg ddlArg) error {
return errNotMatched return errNotMatched
} }
generator, err := gen.NewDefaultGenerator(arg.dir, arg.cfg, generator, err := gen.NewDefaultGenerator(arg.prefix, arg.dir, arg.cfg,
gen.WithConsoleOption(log), gen.WithIgnoreColumns(arg.ignoreColumns)) gen.WithConsoleOption(log), gen.WithIgnoreColumns(arg.ignoreColumns))
if err != nil { if err != nil {
return err return err
@@ -266,6 +277,7 @@ type dataSourceArg struct {
cache, idea bool cache, idea bool
strict bool strict bool
ignoreColumns []string ignoreColumns []string
prefix string
} }
func fromMysqlDataSource(arg dataSourceArg) error { func fromMysqlDataSource(arg dataSourceArg) error {
@@ -318,7 +330,7 @@ func fromMysqlDataSource(arg dataSourceArg) error {
return errors.New("no tables matched") return errors.New("no tables matched")
} }
generator, err := gen.NewDefaultGenerator(arg.dir, arg.cfg, generator, err := gen.NewDefaultGenerator(arg.prefix, arg.dir, arg.cfg,
gen.WithConsoleOption(log), gen.WithIgnoreColumns(arg.ignoreColumns)) gen.WithConsoleOption(log), gen.WithIgnoreColumns(arg.ignoreColumns))
if err != nil { if err != nil {
return err return err
@@ -369,7 +381,7 @@ func fromPostgreSqlDataSource(url string, pattern pattern, dir, schema string, c
return errors.New("no tables matched") return errors.New("no tables matched")
} }
generator, err := gen.NewDefaultGenerator(dir, cfg, gen.WithConsoleOption(log), gen.WithPostgreSql(), gen.WithIgnoreColumns(ignoreColumns)) generator, err := gen.NewDefaultGenerator("", dir, cfg, gen.WithConsoleOption(log), gen.WithPostgreSql(), gen.WithIgnoreColumns(ignoreColumns))
if err != nil { if err != nil {
return err return err
} }

View File

@@ -3,15 +3,15 @@
# generate model with cache from ddl # generate model with cache from ddl
fromDDLWithCache: fromDDLWithCache:
goctl template clean goctl template clean
goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/cache" -cache goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/cache" -cache --prefix gozero
fromDDLWithCacheAndIgnoreColumns: fromDDLWithCacheAndIgnoreColumns:
goctl template clean goctl template clean
goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/ignore_columns/cache" -cache -i 'gmt_create,create_at' -i 'gmt_modified,update_at' goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/ignore_columns/cache" -cache -i 'gmt_create,create_at' -i 'gmt_modified,update_at' --prefix gozero
fromDDLWithCacheAndDb: fromDDLWithCacheAndDb:
goctl template clean goctl template clean
goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/cache_db" -database="1gozero" -cache goctl model mysql ddl -src="./sql/*.sql" -dir="./sql/model/cache_db" -database="1gozero" -cache --prefix gozero
fromDDLWithoutCache: fromDDLWithoutCache:
goctl template clean; goctl template clean;
@@ -19,11 +19,11 @@ fromDDLWithoutCache:
# generate model with cache from data source # generate model with cache from data source
user=root user=app_user
password=password password=PLO75FbcfmFYRuQEGmygZ9PyQCQbmgeD5
datasource=127.0.0.1:3306 datasource=k8s-istiosys-unifydev-2cdcebd306-b64e09be84220820.elb.ap-southeast-1.amazonaws.com:3306
database=gozero database=db_fiat
fromDataSource: fromDataSource:
goctl template clean goctl template clean
goctl model mysql datasource -url="$(user):$(password)@tcp($(datasource))/$(database)" -table="*" -dir ./model/cache -c -style gozero goctl model mysql datasource -url="$(user):$(password)@tcp($(datasource))/$(database)" -table="biz_switch" -dir ./model/cache -c -style gozero --prefix gozero

View File

@@ -30,6 +30,7 @@ type (
cfg *config.Config cfg *config.Config
isPostgreSql bool isPostgreSql bool
ignoreColumns []string ignoreColumns []string
prefix string
} }
// Option defines a function with argument defaultGenerator // Option defines a function with argument defaultGenerator
@@ -56,7 +57,7 @@ type (
) )
// NewDefaultGenerator creates an instance for defaultGenerator // NewDefaultGenerator creates an instance for defaultGenerator
func NewDefaultGenerator(dir string, cfg *config.Config, opt ...Option) (*defaultGenerator, error) { func NewDefaultGenerator(prefix, dir string, cfg *config.Config, opt ...Option) (*defaultGenerator, error) {
if dir == "" { if dir == "" {
dir = pwd dir = pwd
} }
@@ -72,7 +73,7 @@ func NewDefaultGenerator(dir string, cfg *config.Config, opt ...Option) (*defaul
return nil, err return nil, err
} }
generator := &defaultGenerator{dir: dir, cfg: cfg, pkg: pkg} generator := &defaultGenerator{dir: dir, cfg: cfg, pkg: pkg, prefix: prefix}
var optionList []Option var optionList []Option
optionList = append(optionList, newDefaultOption()) optionList = append(optionList, newDefaultOption())
optionList = append(optionList, opt...) optionList = append(optionList, opt...)
@@ -260,7 +261,7 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er
return "", fmt.Errorf("table %s: missing primary key", in.Name.Source()) return "", fmt.Errorf("table %s: missing primary key", in.Name.Source())
} }
primaryKey, uniqueKey := genCacheKeys(in) primaryKey, uniqueKey := genCacheKeys(g.prefix, in)
var table Table var table Table
table.Table = in table.Table = in

View File

@@ -34,7 +34,7 @@ func TestCacheModel(t *testing.T) {
dir := filepath.Join(pathx.MustTempDir(), "./testmodel") dir := filepath.Join(pathx.MustTempDir(), "./testmodel")
cacheDir := filepath.Join(dir, "cache") cacheDir := filepath.Join(dir, "cache")
noCacheDir := filepath.Join(dir, "nocache") noCacheDir := filepath.Join(dir, "nocache")
g, err := NewDefaultGenerator(cacheDir, &config.Config{ g, err := NewDefaultGenerator("cache", cacheDir, &config.Config{
NamingFormat: "GoZero", NamingFormat: "GoZero",
}) })
assert.Nil(t, err) assert.Nil(t, err)
@@ -45,7 +45,7 @@ func TestCacheModel(t *testing.T) {
_, err := os.Stat(filepath.Join(cacheDir, "TestUserModel.go")) _, err := os.Stat(filepath.Join(cacheDir, "TestUserModel.go"))
return err == nil return err == nil
}()) }())
g, err = NewDefaultGenerator(noCacheDir, &config.Config{ g, err = NewDefaultGenerator("cache", noCacheDir, &config.Config{
NamingFormat: "gozero", NamingFormat: "gozero",
}) })
assert.Nil(t, err) assert.Nil(t, err)
@@ -72,7 +72,7 @@ func TestNamingModel(t *testing.T) {
defer func() { defer func() {
_ = os.RemoveAll(dir) _ = os.RemoveAll(dir)
}() }()
g, err := NewDefaultGenerator(camelDir, &config.Config{ g, err := NewDefaultGenerator("cache", camelDir, &config.Config{
NamingFormat: "GoZero", NamingFormat: "GoZero",
}) })
assert.Nil(t, err) assert.Nil(t, err)
@@ -83,7 +83,7 @@ func TestNamingModel(t *testing.T) {
_, err := os.Stat(filepath.Join(camelDir, "TestUserModel.go")) _, err := os.Stat(filepath.Join(camelDir, "TestUserModel.go"))
return err == nil return err == nil
}()) }())
g, err = NewDefaultGenerator(snakeDir, &config.Config{ g, err = NewDefaultGenerator("cache", snakeDir, &config.Config{
NamingFormat: "go_zero", NamingFormat: "go_zero",
}) })
assert.Nil(t, err) assert.Nil(t, err)
@@ -110,7 +110,7 @@ func TestFolderName(t *testing.T) {
defer func() { defer func() {
_ = os.RemoveAll(dir) _ = os.RemoveAll(dir)
}() }()
g, err := NewDefaultGenerator(camelDir, &config.Config{ g, err := NewDefaultGenerator("cache", camelDir, &config.Config{
NamingFormat: "GoZero", NamingFormat: "GoZero",
}) })
assert.Nil(t, err) assert.Nil(t, err)
@@ -125,7 +125,7 @@ func TestFolderName(t *testing.T) {
}()) }())
assert.Equal(t, pkg, g.pkg) assert.Equal(t, pkg, g.pkg)
g, err = NewDefaultGenerator(snakeDir, &config.Config{ g, err = NewDefaultGenerator("cache", snakeDir, &config.Config{
NamingFormat: "go_zero", NamingFormat: "go_zero",
}) })
assert.Nil(t, err) assert.Nil(t, err)
@@ -180,7 +180,7 @@ func Test_genPublicModel(t *testing.T) {
err = os.WriteFile(modelFilename, []byte(source), 0o777) err = os.WriteFile(modelFilename, []byte(source), 0o777)
require.NoError(t, err) require.NoError(t, err)
g, err := NewDefaultGenerator(modelDir, &config.Config{ g, err := NewDefaultGenerator("cache", modelDir, &config.Config{
NamingFormat: config.DefaultFormat, NamingFormat: config.DefaultFormat,
}) })
require.NoError(t, err) require.NoError(t, err)

View File

@@ -37,12 +37,12 @@ type Key struct {
// Join describes an alias of string slice // Join describes an alias of string slice
type Join []string type Join []string
func genCacheKeys(table parser.Table) (Key, []Key) { func genCacheKeys(prefix string, table parser.Table) (Key, []Key) {
var primaryKey Key var primaryKey Key
var uniqueKey []Key var uniqueKey []Key
primaryKey = genCacheKey(table.Db, table.Name, []*parser.Field{&table.PrimaryKey.Field}) primaryKey = genCacheKey(prefix, table.Db, table.Name, []*parser.Field{&table.PrimaryKey.Field})
for _, each := range table.UniqueIndex { for _, each := range table.UniqueIndex {
uniqueKey = append(uniqueKey, genCacheKey(table.Db, table.Name, each)) uniqueKey = append(uniqueKey, genCacheKey(prefix, table.Db, table.Name, each))
} }
sort.Slice(uniqueKey, func(i, j int) bool { sort.Slice(uniqueKey, func(i, j int) bool {
return uniqueKey[i].VarLeft < uniqueKey[j].VarLeft return uniqueKey[i].VarLeft < uniqueKey[j].VarLeft
@@ -51,7 +51,7 @@ func genCacheKeys(table parser.Table) (Key, []Key) {
return primaryKey, uniqueKey return primaryKey, uniqueKey
} }
func genCacheKey(db, table stringx.String, in []*parser.Field) Key { func genCacheKey(prefix string, db, table stringx.String, in []*parser.Field) Key {
var ( var (
varLeftJoin, varRightJoin, fieldNameJoin Join varLeftJoin, varRightJoin, fieldNameJoin Join
varLeft, varRight, varExpression string varLeft, varRight, varExpression string
@@ -62,12 +62,12 @@ func genCacheKey(db, table stringx.String, in []*parser.Field) Key {
dbName, tableName := util.SafeString(db.Source()), util.SafeString(table.Source()) dbName, tableName := util.SafeString(db.Source()), util.SafeString(table.Source())
if len(dbName) > 0 { if len(dbName) > 0 {
varLeftJoin = append(varLeftJoin, "cache", dbName, tableName) varLeftJoin = append(varLeftJoin, prefix, dbName, tableName)
varRightJoin = append(varRightJoin, "cache", dbName, tableName) varRightJoin = append(varRightJoin, prefix, dbName, tableName)
keyLeftJoin = append(keyLeftJoin, dbName, tableName) keyLeftJoin = append(keyLeftJoin, dbName, tableName)
} else { } else {
varLeftJoin = append(varLeftJoin, "cache", tableName) varLeftJoin = append(varLeftJoin, prefix, tableName)
varRightJoin = append(varRightJoin, "cache", tableName) varRightJoin = append(varRightJoin, prefix, tableName)
keyLeftJoin = append(keyLeftJoin, tableName) keyLeftJoin = append(keyLeftJoin, tableName)
} }

View File

@@ -34,7 +34,7 @@ func TestGenCacheKeys(t *testing.T) {
Comment: "姓名", Comment: "姓名",
SeqInIndex: 2, SeqInIndex: 2,
} }
primariCacheKey, uniqueCacheKey := genCacheKeys(parser.Table{ primariCacheKey, uniqueCacheKey := genCacheKeys("cache", parser.Table{
Name: stringx.From("user"), Name: stringx.From("user"),
Db: stringx.From("go_zero"), Db: stringx.From("go_zero"),
PrimaryKey: parser.Primary{ PrimaryKey: parser.Primary{
@@ -129,7 +129,7 @@ func TestGenCacheKeys(t *testing.T) {
}()) }())
}) })
t.Run("no database name", func(t *testing.T) { t.Run("no database name", func(t *testing.T) {
primariCacheKey, _ = genCacheKeys(parser.Table{ primariCacheKey, _ = genCacheKeys("cache", parser.Table{
Name: stringx.From("user"), Name: stringx.From("user"),
Db: stringx.From(""), Db: stringx.From(""),
PrimaryKey: parser.Primary{ PrimaryKey: parser.Primary{

View File

@@ -101,54 +101,54 @@ func Test_getRealModule(t *testing.T) {
{ {
name: "go work duplicate prefix", name: "go work duplicate prefix",
args: args{ args: args{
workDir: "D:\\code\\company\\core-ee\\service", workDir: "/code/company/core-ee/service",
execRun: func(arg, dir string, in ...*bytes.Buffer) (string, error) { execRun: func(arg, dir string, in ...*bytes.Buffer) (string, error) {
return ` return `
{ {
"Path": "gitee.com/unitedrhino/core", "Path": "gitee.com/unitedrhino/core",
"Dir": "D:\\code\\company\\core", "Dir": "/code/company/core",
"GoMod": "D:\\code\\company\\core\\go.mod", "GoMod": "/code/company/core/go.mod",
"GoVersion": "1.21.4" "GoVersion": "1.21.4"
} }
{ {
"Path": "gitee.com/unitedrhino/core-ee", "Path": "gitee.com/unitedrhino/core-ee",
"Dir": "D:\\code\\company\\core-ee", "Dir": "/code/company/core-ee",
"GoMod": "D:\\code\\company\\core-ee\\go.mod", "GoMod": "/code/company/core-ee/go.mod",
"GoVersion": "1.21.4" "GoVersion": "1.21.4"
}`, nil }`, nil
}, },
}, },
want: &Module{ want: &Module{
Path: "gitee.com/unitedrhino/core-ee", Path: "gitee.com/unitedrhino/core-ee",
Dir: "D:\\code\\company\\core-ee", Dir: "/code/company/core-ee",
GoMod: "D:\\code\\company\\core-ee\\go.mod", GoMod: "/code/company/core-ee/go.mod",
GoVersion: "1.21.4", GoVersion: "1.21.4",
}, },
}, },
{ {
name: "go work duplicate prefix2", name: "go work duplicate prefix2",
args: args{ args: args{
workDir: "D:\\code\\company\\core-ee", workDir: "/code/company/core-ee",
execRun: func(arg, dir string, in ...*bytes.Buffer) (string, error) { execRun: func(arg, dir string, in ...*bytes.Buffer) (string, error) {
return ` return `
{ {
"Path": "gitee.com/unitedrhino/core", "Path": "gitee.com/unitedrhino/core",
"Dir": "D:\\code\\company\\core", "Dir": "/code/company/core",
"GoMod": "D:\\code\\company\\core\\go.mod", "GoMod": "/code/company/core/go.mod",
"GoVersion": "1.21.4" "GoVersion": "1.21.4"
} }
{ {
"Path": "gitee.com/unitedrhino/core-ee", "Path": "gitee.com/unitedrhino/core-ee",
"Dir": "D:\\code\\company\\core-ee", "Dir": "/code/company/core-ee",
"GoMod": "D:\\code\\company\\core-ee\\go.mod", "GoMod": "/code/company/core-ee/go.mod",
"GoVersion": "1.21.4" "GoVersion": "1.21.4"
}`, nil }`, nil
}, },
}, },
want: &Module{ want: &Module{
Path: "gitee.com/unitedrhino/core-ee", Path: "gitee.com/unitedrhino/core-ee",
Dir: "D:\\code\\company\\core-ee", Dir: "/code/company/core-ee",
GoMod: "D:\\code\\company\\core-ee\\go.mod", GoMod: "/code/company/core-ee/go.mod",
GoVersion: "1.21.4", GoVersion: "1.21.4",
}, },
}, },