gen_service.go 3.3 KB

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