github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/gormgen/tools/gentool/gentool.go (about) 1 package main 2 3 import ( 4 "flag" 5 "fmt" 6 "log" 7 "os" 8 "strings" 9 10 "github.com/unionj-cloud/go-doudou/v2/toolkit/gormgen" 11 "gopkg.in/yaml.v3" 12 "gorm.io/driver/clickhouse" 13 "gorm.io/driver/mysql" 14 "gorm.io/driver/postgres" 15 "gorm.io/driver/sqlite" 16 "gorm.io/driver/sqlserver" 17 "gorm.io/gorm" 18 ) 19 20 // DBType database type 21 type DBType string 22 23 const ( 24 // dbMySQL Gorm Drivers mysql || postgres || sqlite || sqlserver 25 dbMySQL DBType = "mysql" 26 dbPostgres DBType = "postgres" 27 dbSQLite DBType = "sqlite" 28 dbSQLServer DBType = "sqlserver" 29 dbClickHouse DBType = "clickhouse" 30 ) 31 32 // CmdParams is command line parameters 33 type CmdParams struct { 34 DSN string `yaml:"dsn"` // consult[https://gorm.io/docs/connecting_to_the_database.html]" 35 DB string `yaml:"db"` // input mysql or postgres or sqlite or sqlserver. consult[https://gorm.io/docs/connecting_to_the_database.html] 36 Tables []string `yaml:"tables"` // enter the required data table or leave it blank 37 OnlyModel bool `yaml:"onlyModel"` // only generate model 38 OutPath string `yaml:"outPath"` // specify a directory for output 39 OutFile string `yaml:"outFile"` // query code file name, default: gen.go 40 WithUnitTest bool `yaml:"withUnitTest"` // generate unit test for query code 41 ModelPkgName string `yaml:"modelPkgName"` // generated model code's package name 42 FieldNullable bool `yaml:"fieldNullable"` // generate with pointer when field is nullable 43 FieldWithIndexTag bool `yaml:"fieldWithIndexTag"` // generate field with gorm index tag 44 FieldWithTypeTag bool `yaml:"fieldWithTypeTag"` // generate field with gorm column type tag 45 FieldSignable bool `yaml:"fieldSignable"` // detect integer field's unsigned type, adjust generated data type 46 } 47 48 // YamlConfig is yaml config struct 49 type YamlConfig struct { 50 Version string `yaml:"version"` // 51 Database *CmdParams `yaml:"database"` // 52 } 53 54 // connectDB choose db type for connection to database 55 func connectDB(t DBType, dsn string) (*gorm.DB, error) { 56 if dsn == "" { 57 return nil, fmt.Errorf("dsn cannot be empty") 58 } 59 60 switch t { 61 case dbMySQL: 62 return gorm.Open(mysql.Open(dsn)) 63 case dbPostgres: 64 return gorm.Open(postgres.Open(dsn)) 65 case dbSQLite: 66 return gorm.Open(sqlite.Open(dsn)) 67 case dbSQLServer: 68 return gorm.Open(sqlserver.Open(dsn)) 69 case dbClickHouse: 70 return gorm.Open(clickhouse.Open(dsn)) 71 default: 72 return nil, fmt.Errorf("unknow db %q (support mysql || postgres || sqlite || sqlserver for now)", t) 73 } 74 } 75 76 // genModels is gorm/gen generated models 77 func genModels(g *gormgen.Generator, db *gorm.DB, tables []string) (models []interface{}, err error) { 78 var tablesList []string 79 if len(tables) == 0 { 80 // Execute tasks for all tables in the database 81 tablesList, err = db.Migrator().GetTables() 82 if err != nil { 83 return nil, fmt.Errorf("GORM migrator get all tables fail: %w", err) 84 } 85 } else { 86 tablesList = tables 87 } 88 89 // Execute some data table tasks 90 models = make([]interface{}, len(tablesList)) 91 for i, tableName := range tablesList { 92 models[i] = g.GenerateModel(tableName) 93 } 94 return models, nil 95 } 96 97 // loadConfigFile load config file from path 98 func loadConfigFile(path string) (*CmdParams, error) { 99 file, err := os.Open(path) 100 if err != nil { 101 return nil, err 102 } 103 defer file.Close() // nolint 104 var yamlConfig YamlConfig 105 if cmdErr := yaml.NewDecoder(file).Decode(&yamlConfig); cmdErr != nil { 106 return nil, cmdErr 107 } 108 return yamlConfig.Database, nil 109 } 110 111 // argParse is parser for cmd 112 func argParse() *CmdParams { 113 // choose is file or flag 114 genPath := flag.String("c", "", "is path for gen.yml") 115 dsn := flag.String("dsn", "", "consult[https://gorm.io/docs/connecting_to_the_database.html]") 116 db := flag.String("db", "mysql", "input mysql|postgres|sqlite|sqlserver|clickhouse. consult[https://gorm.io/docs/connecting_to_the_database.html]") 117 tableList := flag.String("tables", "", "enter the required data table or leave it blank") 118 onlyModel := flag.Bool("onlyModel", false, "only generate models (without query file)") 119 outPath := flag.String("outPath", "./dao/query", "specify a directory for output") 120 outFile := flag.String("outFile", "", "query code file name, default: gen.go") 121 withUnitTest := flag.Bool("withUnitTest", false, "generate unit test for query code") 122 modelPkgName := flag.String("modelPkgName", "", "generated model code's package name") 123 fieldNullable := flag.Bool("fieldNullable", false, "generate with pointer when field is nullable") 124 fieldWithIndexTag := flag.Bool("fieldWithIndexTag", false, "generate field with gorm index tag") 125 fieldWithTypeTag := flag.Bool("fieldWithTypeTag", false, "generate field with gorm column type tag") 126 fieldSignable := flag.Bool("fieldSignable", false, "detect integer field's unsigned type, adjust generated data type") 127 flag.Parse() 128 var cmdParse CmdParams 129 if *genPath != "" { 130 if configFileParams, err := loadConfigFile(*genPath); err == nil && configFileParams != nil { 131 cmdParse = *configFileParams 132 } else if err != nil { 133 log.Fatalf("loadConfigFile fail %s", err.Error()) 134 } 135 } 136 // cmd first 137 if *dsn != "" { 138 cmdParse.DSN = *dsn 139 } 140 if *db != "" { 141 cmdParse.DB = *db 142 } 143 if *tableList != "" { 144 cmdParse.Tables = strings.Split(*tableList, ",") 145 } 146 if *onlyModel { 147 cmdParse.OnlyModel = true 148 } 149 if *outPath != "" { 150 cmdParse.OutPath = *outPath 151 } 152 if *outFile != "" { 153 cmdParse.OutFile = *outFile 154 } 155 if *withUnitTest { 156 cmdParse.WithUnitTest = *withUnitTest 157 } 158 if *modelPkgName != "" { 159 cmdParse.ModelPkgName = *modelPkgName 160 } 161 if *fieldNullable { 162 cmdParse.FieldNullable = *fieldNullable 163 } 164 if *fieldWithIndexTag { 165 cmdParse.FieldWithIndexTag = *fieldWithIndexTag 166 } 167 if *fieldWithTypeTag { 168 cmdParse.FieldWithTypeTag = *fieldWithTypeTag 169 } 170 if *fieldSignable { 171 cmdParse.FieldSignable = *fieldSignable 172 } 173 return &cmdParse 174 } 175 176 func main() { 177 // cmdParse 178 config := argParse() 179 if config == nil { 180 log.Fatalln("parse config fail") 181 } 182 db, err := connectDB(DBType(config.DB), config.DSN) 183 if err != nil { 184 log.Fatalln("connect db server fail:", err) 185 } 186 187 g := gormgen.NewGenerator(gormgen.Config{ 188 OutPath: config.OutPath, 189 OutFile: config.OutFile, 190 ModelPkgPath: config.ModelPkgName, 191 WithUnitTest: config.WithUnitTest, 192 FieldNullable: config.FieldNullable, 193 FieldWithIndexTag: config.FieldWithIndexTag, 194 FieldWithTypeTag: config.FieldWithTypeTag, 195 FieldSignable: config.FieldSignable, 196 }) 197 198 g.UseDB(db) 199 200 models, err := genModels(g, db, config.Tables) 201 if err != nil { 202 log.Fatalln("get tables info fail:", err) 203 } 204 205 if !config.OnlyModel { 206 g.ApplyBasic(models...) 207 } 208 209 g.Execute() 210 }