diff --git a/gen/gen_table.go b/gen/gen_table.go new file mode 100644 index 0000000..a1714db --- /dev/null +++ b/gen/gen_table.go @@ -0,0 +1,125 @@ +package gen + +import ( + "fmt" + "gorm.io/gen" + "gorm.io/gen/field" +) + +// GenTable 生成表 +func GenTable(db Database) { + + // 生成配置 + packName := "" + if db.Name != "" { + packName = db.Name + "_" + } + conf := gen.Config{ + // 生成的路径 + OutPath: "./internal/orm/" + packName + "query", + ModelPkgPath: packName + "model", + Mode: gen.WithoutContext | gen.WithDefaultQuery, + } + if db.OutPath != "" { + conf.OutPath = db.OutPath + } + if db.ModelPkgPath != "" { + conf.ModelPkgPath = db.ModelPkgPath + } + if db.config != nil { + conf = *db.config + } + + // 生成商城模型 + g := gen.NewGenerator(conf) + g.UseDB(db.DB) + + // 如果没有指定表则生成全部表 + if len(db.Tables) == 0 { + g.ApplyBasic(g.GenerateAllTable(*db.ComOpts...)...) + g.Execute() + return + } + + var allTables []any + + // 定义递归处理关联表方法 + var handRelate func(relates []TableRelate) []gen.ModelOpt + + // 处理关联表 + handRelate = func(relates []TableRelate) []gen.ModelOpt { + + var opts []gen.ModelOpt + + for _, relate := range relates { + + // 关联表是否已生成 + rTab := findTable(db.Tables, relate.TableName) + fmt.Printf("生成关联表: %s\n", relate.TableName) + + if rTab == nil { + // 如果关联表不存在则生成 + rTab = &Table{Name: relate.TableName} + } + + // 生成关联表的外键 + tag := field.GormTag{} + tag.Set("foreignKey", relate.ForeignKey) + tag.Set("references", relate.LocalKey) + + // 如果有公共参数 + if db.ComOpts != nil { + rTab.Opts = append(rTab.Opts, *db.ComOpts...) + } + + // 如果有关联表的参数 + if relate.Relate != nil { + rTab.Opts = append(rTab.Opts, handRelate(*relate.Relate)...) + } + + // 生成关联表 + relateModel := g.GenerateModelAs(db.TablePrefix+rTab.Name, rTab.GetModelName(db.TablePrefix), rTab.Opts...) + + opts = append(opts, gen.FieldRelate(relate.Type, relate.FieldName, relateModel, &field.RelateConfig{ + GORMTag: tag, + })) + } + return opts + } + + //生成指定表 + for _, tab := range db.Tables { + + // 当前表的所有配置属性 + var tableOpts []gen.ModelOpt + + tableOpts = append(tableOpts, tab.Opts...) + + // 如果有公共参数 + if db.ComOpts != nil { + tableOpts = append(tableOpts, *db.ComOpts...) + } + + // 处理关联表 + if tab.Relate != nil { + tableOpts = append(tableOpts, handRelate(*tab.Relate)...) + } + + newTable := g.GenerateModelAs(db.TablePrefix+tab.Name, tab.GetModelName(db.TablePrefix), tableOpts...) + allTables = append(allTables, newTable) + } + + g.ApplyBasic(allTables...) + + g.Execute() +} + +// 查找表 +func findTable(tabs []Table, name string) *Table { + for _, tab := range tabs { + if tab.Name == name || tab.ModelName == name { + return &tab + } + } + return nil +} diff --git a/gen/types.go b/gen/types.go new file mode 100644 index 0000000..5de5d27 --- /dev/null +++ b/gen/types.go @@ -0,0 +1,46 @@ +package gen + +import ( + "gorm.io/gen" + "gorm.io/gen/field" + "gorm.io/gorm" + "gorm.io/gorm/schema" +) + +type TableRelate struct { + TableName string //关联的表名 + FieldName string //字段名 + ForeignKey string //外键 + LocalKey string //本表键 + Type field.RelationshipType //关联方式 + Relate *[]TableRelate +} + +type Table struct { + Name string //表名 + ModelName string //模型名 + Opts []gen.ModelOpt //表配置选项 + Relate *[]TableRelate //关联表 +} + +type Database struct { + Name string //数据库名 用于生成文件夹 + DB *gorm.DB //数据库连接 + Tables []Table //表 + TablePrefix string //表前缀 + ComOpts *[]gen.ModelOpt //公共配置选项 + OutPath string //生成代码的路径 + ModelPkgPath string //generated model code's package name + config *gen.Config //gen配置 如设置将覆盖 +} + +func (t Table) GetModelName(prefix string) string { + if t.ModelName != "" { + return t.ModelName + } + ns := schema.NamingStrategy{ + SingularTable: true, //单数表名 + TablePrefix: prefix, //表前缀 + } + return ns.SchemaName(t.Name) +} diff --git a/go.mod b/go.mod index bbf9fd9..e8483ae 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,21 @@ module github.com/go-gourd/database go 1.22 + +require ( + gorm.io/gen v0.3.26 + gorm.io/gorm v1.25.11 +) + +require ( + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/tools v0.17.0 // indirect + gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c // indirect + gorm.io/driver/mysql v1.4.4 // indirect + gorm.io/hints v1.1.0 // indirect + gorm.io/plugin/dbresolver v1.5.0 // indirect +)