1
0

command.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. package command
  2. import (
  3. "errors"
  4. "path/filepath"
  5. "strings"
  6. "github.com/go-sql-driver/mysql"
  7. "github.com/tal-tech/go-zero/core/logx"
  8. "github.com/tal-tech/go-zero/core/stores/postgres"
  9. "github.com/tal-tech/go-zero/core/stores/sqlx"
  10. "github.com/tal-tech/go-zero/tools/goctl/config"
  11. "github.com/tal-tech/go-zero/tools/goctl/model/sql/gen"
  12. "github.com/tal-tech/go-zero/tools/goctl/model/sql/model"
  13. "github.com/tal-tech/go-zero/tools/goctl/model/sql/util"
  14. file "github.com/tal-tech/go-zero/tools/goctl/util"
  15. "github.com/tal-tech/go-zero/tools/goctl/util/console"
  16. "github.com/urfave/cli"
  17. )
  18. const (
  19. flagSrc = "src"
  20. flagDir = "dir"
  21. flagCache = "cache"
  22. flagIdea = "idea"
  23. flagURL = "url"
  24. flagTable = "table"
  25. flagStyle = "style"
  26. flagDatabase = "database"
  27. flagSchema = "schema"
  28. )
  29. var errNotMatched = errors.New("sql not matched")
  30. // MysqlDDL generates model code from ddl
  31. func MysqlDDL(ctx *cli.Context) error {
  32. src := ctx.String(flagSrc)
  33. dir := ctx.String(flagDir)
  34. cache := ctx.Bool(flagCache)
  35. idea := ctx.Bool(flagIdea)
  36. style := ctx.String(flagStyle)
  37. database := ctx.String(flagDatabase)
  38. home := ctx.String("home")
  39. if len(home) > 0 {
  40. file.RegisterGoctlHome(home)
  41. }
  42. cfg, err := config.NewConfig(style)
  43. if err != nil {
  44. return err
  45. }
  46. return fromDDl(src, dir, cfg, cache, idea, database)
  47. }
  48. // MySqlDataSource generates model code from datasource
  49. func MySqlDataSource(ctx *cli.Context) error {
  50. url := strings.TrimSpace(ctx.String(flagURL))
  51. dir := strings.TrimSpace(ctx.String(flagDir))
  52. cache := ctx.Bool(flagCache)
  53. idea := ctx.Bool(flagIdea)
  54. style := ctx.String(flagStyle)
  55. home := ctx.String("home")
  56. if len(home) > 0 {
  57. file.RegisterGoctlHome(home)
  58. }
  59. pattern := strings.TrimSpace(ctx.String(flagTable))
  60. cfg, err := config.NewConfig(style)
  61. if err != nil {
  62. return err
  63. }
  64. return fromMysqlDataSource(url, pattern, dir, cfg, cache, idea)
  65. }
  66. // PostgreSqlDataSource generates model code from datasource
  67. func PostgreSqlDataSource(ctx *cli.Context) error {
  68. url := strings.TrimSpace(ctx.String(flagURL))
  69. dir := strings.TrimSpace(ctx.String(flagDir))
  70. cache := ctx.Bool(flagCache)
  71. idea := ctx.Bool(flagIdea)
  72. style := ctx.String(flagStyle)
  73. schema := ctx.String(flagSchema)
  74. home := ctx.String("home")
  75. if len(home) > 0 {
  76. file.RegisterGoctlHome(home)
  77. }
  78. if len(schema) == 0 {
  79. schema = "public"
  80. }
  81. pattern := strings.TrimSpace(ctx.String(flagTable))
  82. cfg, err := config.NewConfig(style)
  83. if err != nil {
  84. return err
  85. }
  86. return fromPostgreSqlDataSource(url, pattern, dir, schema, cfg, cache, idea)
  87. }
  88. func fromDDl(src, dir string, cfg *config.Config, cache, idea bool, database string) error {
  89. log := console.NewConsole(idea)
  90. src = strings.TrimSpace(src)
  91. if len(src) == 0 {
  92. return errors.New("expected path or path globbing patterns, but nothing found")
  93. }
  94. files, err := util.MatchFiles(src)
  95. if err != nil {
  96. return err
  97. }
  98. if len(files) == 0 {
  99. return errNotMatched
  100. }
  101. generator, err := gen.NewDefaultGenerator(dir, cfg, gen.WithConsoleOption(log))
  102. if err != nil {
  103. return err
  104. }
  105. for _, file := range files {
  106. err = generator.StartFromDDL(file, cache, database)
  107. if err != nil {
  108. return err
  109. }
  110. }
  111. return nil
  112. }
  113. func fromMysqlDataSource(url, pattern, dir string, cfg *config.Config, cache, idea bool) error {
  114. log := console.NewConsole(idea)
  115. if len(url) == 0 {
  116. log.Error("%v", "expected data source of mysql, but nothing found")
  117. return nil
  118. }
  119. if len(pattern) == 0 {
  120. log.Error("%v", "expected table or table globbing patterns, but nothing found")
  121. return nil
  122. }
  123. dsn, err := mysql.ParseDSN(url)
  124. if err != nil {
  125. return err
  126. }
  127. logx.Disable()
  128. databaseSource := strings.TrimSuffix(url, "/"+dsn.DBName) + "/information_schema"
  129. db := sqlx.NewMysql(databaseSource)
  130. im := model.NewInformationSchemaModel(db)
  131. tables, err := im.GetAllTables(dsn.DBName)
  132. if err != nil {
  133. return err
  134. }
  135. matchTables := make(map[string]*model.Table)
  136. for _, item := range tables {
  137. match, err := filepath.Match(pattern, item)
  138. if err != nil {
  139. return err
  140. }
  141. if !match {
  142. continue
  143. }
  144. columnData, err := im.FindColumns(dsn.DBName, item)
  145. if err != nil {
  146. return err
  147. }
  148. table, err := columnData.Convert()
  149. if err != nil {
  150. return err
  151. }
  152. matchTables[item] = table
  153. }
  154. if len(matchTables) == 0 {
  155. return errors.New("no tables matched")
  156. }
  157. generator, err := gen.NewDefaultGenerator(dir, cfg, gen.WithConsoleOption(log))
  158. if err != nil {
  159. return err
  160. }
  161. return generator.StartFromInformationSchema(matchTables, cache)
  162. }
  163. func fromPostgreSqlDataSource(url, pattern, dir, schema string, cfg *config.Config, cache, idea bool) error {
  164. log := console.NewConsole(idea)
  165. if len(url) == 0 {
  166. log.Error("%v", "expected data source of postgresql, but nothing found")
  167. return nil
  168. }
  169. if len(pattern) == 0 {
  170. log.Error("%v", "expected table or table globbing patterns, but nothing found")
  171. return nil
  172. }
  173. db := postgres.New(url)
  174. im := model.NewPostgreSqlModel(db)
  175. tables, err := im.GetAllTables(schema)
  176. if err != nil {
  177. return err
  178. }
  179. matchTables := make(map[string]*model.Table)
  180. for _, item := range tables {
  181. match, err := filepath.Match(pattern, item)
  182. if err != nil {
  183. return err
  184. }
  185. if !match {
  186. continue
  187. }
  188. columnData, err := im.FindColumns(schema, item)
  189. if err != nil {
  190. return err
  191. }
  192. table, err := columnData.Convert()
  193. if err != nil {
  194. return err
  195. }
  196. matchTables[item] = table
  197. }
  198. if len(matchTables) == 0 {
  199. return errors.New("no tables matched")
  200. }
  201. generator, err := gen.NewDefaultGenerator(dir, cfg, gen.WithConsoleOption(log), gen.WithPostgreSql())
  202. if err != nil {
  203. return err
  204. }
  205. return generator.StartFromInformationSchema(matchTables, cache)
  206. }