Skip to content

Commit

Permalink
feat(generate): sync table with name strategy (go-gorm#303)
Browse files Browse the repository at this point in the history
* feat(generat): format struct

* feat(generate): sync table with name strategy
  • Loading branch information
tr1v3r authored Dec 20, 2021
1 parent 961ca43 commit bd8e6ca
Show file tree
Hide file tree
Showing 19 changed files with 287 additions and 239 deletions.
4 changes: 2 additions & 2 deletions README.ZH_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ FieldNewTag // append new tag
FieldNewTagWithNS // specify new tag with name strategy
FieldTrimPrefix // trim column prefix
FieldTrimSuffix // trim column suffix
FieldAddPrefix // add prefix to struct member's name
FieldAddSuffix // add suffix to struct member's name
FieldAddPrefix // add prefix to struct field's name
FieldAddSuffix // add suffix to struct field's name
FieldRelate // specify relationship with other tables
FieldRelateModel // specify relationship with exist models
```
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@ FieldNewTag // append new tag
FieldNewTagWithNS // specify new tag with name strategy
FieldTrimPrefix // trim column prefix
FieldTrimSuffix // trim column suffix
FieldAddPrefix // add prefix to struct member's name
FieldAddSuffix // add suffix to struct member's name
FieldAddPrefix // add prefix to struct field's name
FieldAddSuffix // add suffix to struct field's name
FieldRelate // specify relationship with other tables
FieldRelateModel // specify relationship with exist models
```
Expand Down
32 changes: 28 additions & 4 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,17 @@ type Config struct {

Mode GenerateMode // generate mode

queryPkgName string // generated query code's package name
dbNameOpts []model.SchemaNameOpt
queryPkgName string // generated query code's package name
dbNameOpts []model.SchemaNameOpt

// name strategy for syncing table from db
tableNameNS func(tableName string) (targetTableName string)
modelNameNS func(tableName string) (modelName string)
fileNameNS func(tableName string) (fielName string)

dataTypeMap map[string]func(detailType string) (dataType string)
fieldJSONTagNS func(columnName string) string
fieldNewTagNS func(columnName string) string
fieldJSONTagNS func(columnName string) (tagContent string)
fieldNewTagNS func(columnName string) (tagContent string)
}

// WithDbNameOpts set get database name function
Expand All @@ -53,14 +59,32 @@ func (cfg *Config) WithDbNameOpts(opts ...model.SchemaNameOpt) {
}
}

// WithTableNameStrategy specify table name naming strategy, only work when syncing table from db
func (cfg *Config) WithTableNameStrategy(ns func(tableName string) (targetTableName string)) {
cfg.tableNameNS = ns
}

// WithModelNameStrategy specify model struct name naming strategy, only work when syncing table from db
func (cfg *Config) WithModelNameStrategy(ns func(tableName string) (modelName string)) {
cfg.modelNameNS = ns
}

// WithFileNameStrategy specify file name naming strategy, only work when syncing table from db
func (cfg *Config) WithFileNameStrategy(ns func(tableName string) (fielName string)) {
cfg.fileNameNS = ns
}

// WithDataTypeMap specify data type mapping relationship, only work when syncing table from db
func (cfg *Config) WithDataTypeMap(newMap map[string]func(detailType string) (dataType string)) {
cfg.dataTypeMap = newMap
}

// WithJSONTagNameStrategy specify json tag naming strategy
func (cfg *Config) WithJSONTagNameStrategy(ns func(columnName string) (tagContent string)) {
cfg.fieldJSONTagNS = ns
}

// WithNewTagNameStrategy specify new tag naming strategy
func (cfg *Config) WithNewTagNameStrategy(ns func(columnName string) (tagContent string)) {
cfg.fieldNewTagNS = ns
}
Expand Down
21 changes: 10 additions & 11 deletions field/association.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ var ns = schema.NamingStrategy{}
type RelationField interface {
Name() string
Path() string
Field(member ...string) Expr
Field(fields ...string) Expr

On(conds ...Expr) RelationField
Order(columns ...Expr) RelationField
Expand Down Expand Up @@ -66,9 +66,9 @@ func (r Relation) RelationshipName() string { return ns.SchemaName(string(r.rela

func (r Relation) ChildRelations() []Relation { return r.childRelations }

func (r Relation) Field(member ...string) Expr {
if len(member) > 0 {
return NewString("", r.fieldName+"."+strings.Join(member, ".")).appendBuildOpts(WithoutQuote)
func (r Relation) Field(fields ...string) Expr {
if len(fields) > 0 {
return NewString("", r.fieldName+"."+strings.Join(fields, ".")).appendBuildOpts(WithoutQuote)
}
return NewString("", r.fieldName).appendBuildOpts(WithoutQuote)
}
Expand Down Expand Up @@ -103,19 +103,18 @@ func (r *Relation) GetOrderCol() []Expr { return r.order }
func (r *Relation) GetClauses() []clause.Expression { return r.clauses }
func (r *Relation) GetPage() (offset, limit int) { return r.offset, r.limit }

func (r *Relation) StructMember() string {
var memberStr string
func (r *Relation) StructField() (fieldStr string) {
for _, relation := range r.childRelations {
memberStr += relation.fieldName + " struct {\nfield.RelationField\n" + relation.StructMember() + "}\n"
fieldStr += relation.fieldName + " struct {\nfield.RelationField\n" + relation.StructField() + "}\n"
}
return memberStr
return fieldStr
}

func (r *Relation) StructMemberInit() string {
func (r *Relation) StructFieldInit() string {
initStr := fmt.Sprintf("RelationField: field.NewRelation(%q, %q),\n", r.fieldPath, r.fieldType)
for _, relation := range r.childRelations {
initStr += relation.fieldName + ": struct {\nfield.RelationField\n" + strings.TrimSpace(relation.StructMember()) + "}"
initStr += "{\n" + relation.StructMemberInit() + "},\n"
initStr += relation.fieldName + ": struct {\nfield.RelationField\n" + strings.TrimSpace(relation.StructField()) + "}"
initStr += "{\n" + relation.StructFieldInit() + "},\n"
}
return initStr
}
Expand Down
12 changes: 6 additions & 6 deletions field/external_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func BenchmarkExpr_Count(b *testing.B) {
}
}

func TestRelation_StructMember(t *testing.T) {
func TestRelation_StructField(t *testing.T) {
var testdatas = []struct {
relation *field.Relation
expectedValue string
Expand All @@ -411,13 +411,13 @@ func TestRelation_StructMember(t *testing.T) {
}

for _, testdata := range testdatas {
if result := testdata.relation.StructMember(); result != testdata.expectedValue {
t.Errorf("StructMember fail: except %q, got %q", testdata.expectedValue, result)
if result := testdata.relation.StructField(); result != testdata.expectedValue {
t.Errorf("StructField fail: except %q, got %q", testdata.expectedValue, result)
}
}
}

func TestRelation_StructMemberInit(t *testing.T) {
func TestRelation_StructFieldInit(t *testing.T) {
var testdatas = []struct {
relation *field.Relation
expectedValue string
Expand All @@ -438,8 +438,8 @@ func TestRelation_StructMemberInit(t *testing.T) {
}

for _, testdata := range testdatas {
if result := testdata.relation.StructMemberInit(); result != testdata.expectedValue {
t.Errorf("StructMember fail: except %q, got %q", testdata.expectedValue, result)
if result := testdata.relation.StructFieldInit(); result != testdata.expectedValue {
t.Errorf("StructField fail: except %q, got %q", testdata.expectedValue, result)
}
}
}
Expand Down
78 changes: 39 additions & 39 deletions field_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ var ns = schema.NamingStrategy{}

var (
// FieldNew add new field (any type your want)
FieldNew = func(fieldName, fieldType, fieldTag string) model.CreateMemberOpt {
return func(*model.Member) *model.Member {
return &model.Member{
FieldNew = func(fieldName, fieldType, fieldTag string) model.CreateFieldOpt {
return func(*model.Field) *model.Field {
return &model.Field{
Name: fieldName,
Type: fieldType,
OverwriteTag: fieldTag,
}
}
}
// FieldIgnore ignore some columns by name
FieldIgnore = func(columnNames ...string) model.FilterMemberOpt {
return func(m *model.Member) *model.Member {
FieldIgnore = func(columnNames ...string) model.FilterFieldOpt {
return func(m *model.Field) *model.Field {
for _, name := range columnNames {
if m.ColumnName == name {
return nil
Expand All @@ -37,12 +37,12 @@ var (
}
}
// FieldIgnoreReg ignore some columns by RegExp
FieldIgnoreReg = func(columnNameRegs ...string) model.FilterMemberOpt {
FieldIgnoreReg = func(columnNameRegs ...string) model.FilterFieldOpt {
regs := make([]regexp.Regexp, len(columnNameRegs))
for i, reg := range columnNameRegs {
regs[i] = *regexp.MustCompile(reg)
}
return func(m *model.Member) *model.Member {
return func(m *model.Field) *model.Field {
for _, reg := range regs {
if reg.MatchString(m.ColumnName) {
return nil
Expand All @@ -52,81 +52,81 @@ var (
}
}
// FieldRename specify field name in generated struct
FieldRename = func(columnName string, newName string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldRename = func(columnName string, newName string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if m.ColumnName == columnName {
m.Name = newName
}
return m
}
}
// FieldType specify field type in generated struct
FieldType = func(columnName string, newType string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldType = func(columnName string, newType string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if m.ColumnName == columnName {
m.Type = newType
}
return m
}
}
// FieldIgnoreType ignore some columns by RegExp
FieldTypeReg = func(columnNameReg string, newType string) model.ModifyMemberOpt {
FieldTypeReg = func(columnNameReg string, newType string) model.ModifyFieldOpt {
reg := regexp.MustCompile(columnNameReg)
return func(m *model.Member) *model.Member {
return func(m *model.Field) *model.Field {
if reg.MatchString(m.ColumnName) {
m.Type = newType
}
return m
}
}
// FieldTag specify GORM tag and JSON tag
FieldTag = func(columnName string, gormTag, jsonTag string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldTag = func(columnName string, gormTag, jsonTag string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if m.ColumnName == columnName {
m.GORMTag, m.JSONTag = gormTag, jsonTag
}
return m
}
}
// FieldJSONTag specify JSON tag
FieldJSONTag = func(columnName string, jsonTag string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldJSONTag = func(columnName string, jsonTag string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if m.ColumnName == columnName {
m.JSONTag = jsonTag
}
return m
}
}
// FieldJSONTagWithNS specify JSON tag with name strategy
FieldJSONTagWithNS = func(schemaName func(columnName string) (tagContent string)) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldJSONTagWithNS = func(schemaName func(columnName string) (tagContent string)) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if schemaName != nil {
m.JSONTag = schemaName(m.ColumnName)
}
return m
}
}
// FieldGORMTag specify GORM tag
FieldGORMTag = func(columnName string, gormTag string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldGORMTag = func(columnName string, gormTag string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if m.ColumnName == columnName {
m.GORMTag = gormTag
}
return m
}
}
// FieldNewTag add new tag
FieldNewTag = func(columnName string, newTag string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldNewTag = func(columnName string, newTag string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if m.ColumnName == columnName {
m.NewTag += " " + newTag
}
return m
}
}
// FieldNewTagWithNS add new tag with name strategy
FieldNewTagWithNS = func(tagName string, schemaName func(columnName string) string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldNewTagWithNS = func(tagName string, schemaName func(columnName string) string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
if schemaName == nil {
schemaName = func(name string) string { return name }
}
Expand All @@ -135,43 +135,43 @@ var (
}
}
// FieldTrimPrefix trim column name's prefix
FieldTrimPrefix = func(prefix string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldTrimPrefix = func(prefix string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
m.Name = strings.TrimPrefix(m.Name, prefix)
return m
}
}
// FieldTrimSuffix trim column name's suffix
FieldTrimSuffix = func(suffix string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldTrimSuffix = func(suffix string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
m.Name = strings.TrimSuffix(m.Name, suffix)
return m
}
}
// FieldAddPrefix add prefix to struct's memeber name
FieldAddPrefix = func(prefix string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldAddPrefix = func(prefix string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
m.Name = prefix + m.Name
return m
}
}
// FieldAddSuffix add suffix to struct's memeber name
FieldAddSuffix = func(suffix string) model.ModifyMemberOpt {
return func(m *model.Member) *model.Member {
FieldAddSuffix = func(suffix string) model.ModifyFieldOpt {
return func(m *model.Field) *model.Field {
m.Name += suffix
return m
}
}
// FieldRelate relate to table in database
FieldRelate = func(relationship field.RelationshipType, fieldName string, table *check.BaseStruct, config *field.RelateConfig) model.CreateMemberOpt {
FieldRelate = func(relationship field.RelationshipType, fieldName string, table *check.BaseStruct, config *field.RelateConfig) model.CreateFieldOpt {
if config == nil {
config = &field.RelateConfig{}
}
if config.JSONTag == "" {
config.JSONTag = ns.ColumnName("", fieldName)
}
return func(*model.Member) *model.Member {
return &model.Member{
return func(*model.Field) *model.Field {
return &model.Field{
Name: fieldName,
Type: config.RelateFieldPrefix(relationship) + table.StructInfo.Type,
JSONTag: config.JSONTag,
Expand All @@ -186,7 +186,7 @@ var (
}
}
// FieldRelateModel relate to exist table model
FieldRelateModel = func(relationship field.RelationshipType, fieldName string, relModel interface{}, config *field.RelateConfig) model.CreateMemberOpt {
FieldRelateModel = func(relationship field.RelationshipType, fieldName string, relModel interface{}, config *field.RelateConfig) model.CreateFieldOpt {
st := reflect.TypeOf(relModel)
if st.Kind() == reflect.Ptr {
st = st.Elem()
Expand All @@ -200,8 +200,8 @@ var (
config.JSONTag = ns.ColumnName("", fieldName)
}

return func(*model.Member) *model.Member {
return &model.Member{
return func(*model.Field) *model.Field {
return &model.Field{
Name: fieldName,
Type: config.RelateFieldPrefix(relationship) + fieldType,
JSONTag: config.JSONTag,
Expand Down
Loading

0 comments on commit bd8e6ca

Please sign in to comment.