diff --git a/tools/goctl/model/sql/gen/customized.go b/tools/goctl/model/sql/gen/customized.go new file mode 100644 index 00000000..77872837 --- /dev/null +++ b/tools/goctl/model/sql/gen/customized.go @@ -0,0 +1,108 @@ +package gen + +import ( + "fmt" + "sort" + "strings" + + "github.com/zeromicro/go-zero/core/collection" + "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/pathx" + "github.com/zeromicro/go-zero/tools/goctl/util/stringx" +) + +// Field describes a table field +type Field struct { + NameOriginal string + UpperName string + LowerName string + DataType string + Comment string + SeqInIndex int + OrdinalPosition int +} + +func genCustomized(table Table, withCache, postgreSql bool) (string, error) { + expressions := make([]string, 0) + expressionValues := make([]string, 0) + fields := make([]Field, 0) + var count int + for _, field := range table.Fields { + camel := util.SafeString(field.Name.ToCamel()) + if table.isIgnoreColumns(field.Name.Source()) { + continue + } + + if field.Name.Source() == table.PrimaryKey.Name.Source() { + if table.PrimaryKey.AutoIncrement { + continue + } + } + + count += 1 + if postgreSql { + expressions = append(expressions, fmt.Sprintf("$%d", count)) + } else { + expressions = append(expressions, "?") + } + expressionValues = append(expressionValues, "data."+camel) + + f := Field{ + NameOriginal: field.NameOriginal, + UpperName: camel, + LowerName: stringx.From(camel).Untitle(), + DataType: field.DataType, + Comment: field.Comment, + SeqInIndex: field.SeqInIndex, + OrdinalPosition: field.OrdinalPosition, + } + fields = append(fields, f) + } + + keySet := collection.NewSet() + keyVariableSet := collection.NewSet() + keySet.AddStr(table.PrimaryCacheKey.KeyExpression) + keyVariableSet.AddStr(table.PrimaryCacheKey.KeyLeft) + for _, key := range table.UniqueCacheKey { + keySet.AddStr(key.DataKeyExpression) + keyVariableSet.AddStr(key.KeyLeft) + } + keys := keySet.KeysStr() + sort.Strings(keys) + keyVars := keyVariableSet.KeysStr() + sort.Strings(keyVars) + + camel := table.Name.ToCamel() + text, err := pathx.LoadTemplate(category, customizedTemplateFile, template.Customized) + if err != nil { + return "", err + } + + output, err := util.With("customized"). + Parse(text). + Execute(map[string]any{ + "withCache": withCache, + "containsIndexCache": table.ContainsUniqueCacheKey, + "upperStartCamelObject": camel, + "lowerStartCamelObject": stringx.From(camel).Untitle(), + "lowerStartCamelPrimaryKey": util.EscapeGolangKeyword(stringx.From(table.PrimaryKey.Name.ToCamel()).Untitle()), + "upperStartCamelPrimaryKey": table.PrimaryKey.Name.ToCamel(), + "primaryKeyDataType": table.PrimaryKey.DataType, + "originalPrimaryKey": wrapWithRawString(table.PrimaryKey.Name.Source(), postgreSql), + "primaryCacheKey": table.PrimaryCacheKey.DataKeyExpression, + "primaryKeyVariable": table.PrimaryCacheKey.KeyLeft, + "keys": strings.Join(keys, "\n"), + "keyValues": strings.Join(keyVars, ", "), + "expression": strings.Join(expressions, ", "), + "expressionValues": strings.Join(expressionValues, ", "), + "postgreSql": postgreSql, + "fields": fields, + "data": table, + }) + if err != nil { + return "", err + } + + return output.String(), nil +} diff --git a/tools/goctl/model/sql/gen/gen.go b/tools/goctl/model/sql/gen/gen.go index 34a07517..37b9e725 100644 --- a/tools/goctl/model/sql/gen/gen.go +++ b/tools/goctl/model/sql/gen/gen.go @@ -36,16 +36,17 @@ type ( Option func(generator *defaultGenerator) code struct { - importsCode string - varsCode string - typesCode string - newCode string - insertCode string - findCode []string - updateCode string - deleteCode string - cacheExtra string - tableName string + importsCode string + varsCode string + typesCode string + newCode string + insertCode string + findCode []string + updateCode string + deleteCode string + cacheExtra string + tableName string + customizedCode string } codeTuple struct { @@ -323,17 +324,23 @@ func (g *defaultGenerator) genModel(in parser.Table, withCache bool) (string, er return "", err } + customizedCode, err := genCustomized(table, withCache, g.isPostgreSql) + if err != nil { + return "", err + } + code := &code{ - importsCode: importsCode, - varsCode: varsCode, - typesCode: typesCode, - newCode: newCode, - insertCode: insertCode, - findCode: findCode, - updateCode: updateCode, - deleteCode: deleteCode, - cacheExtra: ret.cacheExtra, - tableName: tableName, + importsCode: importsCode, + varsCode: varsCode, + typesCode: typesCode, + newCode: newCode, + insertCode: insertCode, + findCode: findCode, + updateCode: updateCode, + deleteCode: deleteCode, + cacheExtra: ret.cacheExtra, + tableName: tableName, + customizedCode: customizedCode, } output, err := g.executeModel(table, code) @@ -387,6 +394,7 @@ func (g *defaultGenerator) executeModel(table Table, code *code) (*bytes.Buffer, "extraMethod": code.cacheExtra, "tableName": code.tableName, "data": table, + "customized": code.customizedCode, }) if err != nil { return nil, err diff --git a/tools/goctl/model/sql/gen/template.go b/tools/goctl/model/sql/gen/template.go index 19513ffc..0f5c3e8d 100644 --- a/tools/goctl/model/sql/gen/template.go +++ b/tools/goctl/model/sql/gen/template.go @@ -9,6 +9,7 @@ import ( const ( category = "model" + customizedTemplateFile = "customized.tpl" deleteTemplateFile = "delete.tpl" deleteMethodTemplateFile = "interface-delete.tpl" fieldTemplateFile = "field.tpl" @@ -34,6 +35,7 @@ const ( ) var templates = map[string]string{ + customizedTemplateFile: template.Customized, deleteTemplateFile: template.Delete, deleteMethodTemplateFile: template.DeleteMethod, fieldTemplateFile: template.Field, diff --git a/tools/goctl/model/sql/template/template.go b/tools/goctl/model/sql/template/template.go index 71b15445..99cb3b19 100644 --- a/tools/goctl/model/sql/template/template.go +++ b/tools/goctl/model/sql/template/template.go @@ -7,6 +7,11 @@ import ( "github.com/zeromicro/go-zero/tools/goctl/util" ) +// Customized defines a template for customized in model +// +//go:embed tpl/customized.tpl +var Customized string + // Vars defines a template for var block in model // //go:embed tpl/var.tpl @@ -51,6 +56,7 @@ package {{.pkg}} {{.update}} {{.extraMethod}} {{.tableName}} +{{.customized}} `, util.DoNotEditHead) // Insert defines a template for insert code in model diff --git a/tools/goctl/model/sql/template/tpl/customized.tpl b/tools/goctl/model/sql/template/tpl/customized.tpl new file mode 100644 index 00000000..e69de29b