gen_service.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. package services
  2. import (
  3. "flag"
  4. "fmt"
  5. "github.com/pkg/errors"
  6. "gorm.io/driver/mysql"
  7. "gorm.io/gen"
  8. "gorm.io/gorm"
  9. "gorm.io/gorm/logger"
  10. "jollia.cn/jolib/jokode"
  11. "jollia.cn/jolib/jokode/log"
  12. "strings"
  13. )
  14. const (
  15. defCfgFilePath = "conf/db.yaml"
  16. )
  17. type GenService struct {
  18. dbInstance *gorm.DB
  19. tables []string
  20. }
  21. func (s *GenService) Init() error {
  22. log.Warn("Enter: GenService.Init")
  23. defer log.Warn("Leave: GenService.Init")
  24. if !flag.Parsed() {
  25. flag.Parse()
  26. }
  27. var (
  28. dbCfg *DbConfig
  29. cfgFilePath string
  30. force bool
  31. )
  32. if cfgFilePathFlag != "" {
  33. cfgFilePath = cfgFilePathFlag
  34. force = true
  35. } else {
  36. cfgFilePath = defCfgFilePath
  37. force = false
  38. }
  39. if cfg, err := loadConfigFromFile(cfgFilePath, force); err != nil {
  40. return errors.Wrapf(err, "try load db config from file '%s' fail", cfgFilePath)
  41. } else if cfg == nil {
  42. return errors.New("load db config returns nil")
  43. } else {
  44. dbCfg = cfg
  45. if len(cfg.Tables) > 0 {
  46. s.tables = cfg.Tables
  47. }
  48. }
  49. if !dbConfigFlag.IsZero() {
  50. if dbConfigFlag.Host != "" {
  51. dbCfg.Host = dbConfigFlag.Host
  52. }
  53. if dbConfigFlag.Port != 0 {
  54. dbCfg.Port = dbConfigFlag.Port
  55. }
  56. if dbConfigFlag.Schema != "" {
  57. dbCfg.Schema = dbConfigFlag.Schema
  58. }
  59. if dbConfigFlag.User != "" {
  60. dbCfg.User = dbConfigFlag.User
  61. }
  62. if dbConfigFlag.Pwd != "" {
  63. dbCfg.Pwd = dbConfigFlag.Pwd
  64. }
  65. }
  66. if err := s.initDatabase(dbCfg); err != nil {
  67. return errors.Wrap(err, "try init database fail")
  68. }
  69. return nil
  70. }
  71. func (s *GenService) initDatabase(dbCfg *DbConfig) error {
  72. if dbCfg == nil {
  73. return errors.New("can not init database with nil db config")
  74. }
  75. if err := dbCfg.FixDefaultValues(); err != nil {
  76. return errors.Wrap(err, "try fix default values of database config fail")
  77. }
  78. dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
  79. dbCfg.User,
  80. dbCfg.Pwd,
  81. dbCfg.Host,
  82. dbCfg.Port,
  83. dbCfg.Schema)
  84. if db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
  85. Logger: logger.Default.LogMode(logger.Info),
  86. }); err != nil {
  87. return errors.Wrapf(err, "try open database with dsn '%s' fail", dsn)
  88. } else {
  89. s.dbInstance = db
  90. }
  91. return nil
  92. }
  93. func loadConfigFromFile(filePath string, force bool) (*DbConfig, error) {
  94. cfg := &DbConfig{}
  95. if err := jokode.LoadConfigFromFile(cfg, filePath); err != nil {
  96. if force {
  97. return nil, errors.Wrapf(err, "try load config from file '%s' fail", filePath)
  98. }
  99. }
  100. return cfg, nil
  101. }
  102. func (s *GenService) Start() error {
  103. log.Warn("Enter: GenService.Start")
  104. defer log.Warn("Leave: GenService.Start")
  105. if s.dbInstance == nil {
  106. return errors.New("try start gen service with nil database instance")
  107. }
  108. g := gen.NewGenerator(gen.Config{
  109. OutPath: "model",
  110. WithUnitTest: false,
  111. FieldNullable: true,
  112. FieldCoverable: true,
  113. FieldSignable: true,
  114. FieldWithIndexTag: true,
  115. FieldWithTypeTag: true,
  116. Mode: gen.WithDefaultQuery | gen.WithQueryInterface,
  117. })
  118. g.WithDataTypeMap(map[string]func(columnType gorm.ColumnType) (dataType string){
  119. "tinyint": func(filedType gorm.ColumnType) string {
  120. if ct, ok := filedType.ColumnType(); ok {
  121. if strings.HasPrefix(strings.ToLower(ct), "tinyint(1)") {
  122. return "int8"
  123. }
  124. return "int16"
  125. } else {
  126. return "int32"
  127. }
  128. },
  129. })
  130. g.UseDB(s.dbInstance)
  131. if len(s.tables) > 0 {
  132. for _, tableName := range s.tables {
  133. g.GenerateModel(tableName)
  134. }
  135. } else {
  136. g.GenerateAllTable()
  137. }
  138. g.Execute()
  139. return nil
  140. }
  141. func (s *GenService) Stop() {
  142. // do nothing
  143. }
  144. func (s *GenService) GetName() string {
  145. return "GenService"
  146. }
  147. func (s *GenService) GetInitOrder() int {
  148. return 0
  149. }