operations.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. package operations
  2. import (
  3. dbSql "database/sql"
  4. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/sql"
  5. "git.sxidc.com/go-framework/baize/framework/core/infrastructure/logger"
  6. "git.sxidc.com/go-tools/utils/template"
  7. "github.com/pkg/errors"
  8. "gorm.io/gorm"
  9. "time"
  10. )
  11. type Config struct {
  12. UserName string `json:"user_name" yaml:"user_name"`
  13. Password string `json:"password" yaml:"password"`
  14. Address string `json:"address" yaml:"address"`
  15. Port string `json:"port" yaml:"port"`
  16. Database string `json:"database" yaml:"database"`
  17. MaxConnections int `json:"max_connections" yaml:"max_connections"`
  18. MaxIdleConnections int `json:"max_idle_connections" yaml:"max_idle_connections"`
  19. LogLevel string `json:"log_level" yaml:"log_level"`
  20. }
  21. type Operations struct {
  22. db *gorm.DB
  23. stopPingChan chan any
  24. }
  25. func NewOperations(dbConfig *Config) (*Operations, error) {
  26. gormDB, err := newGormDB(dbConfig)
  27. if err != nil {
  28. return nil, err
  29. }
  30. sqlDB, err := gormDB.DB()
  31. if err != nil {
  32. return nil, errors.New(err.Error())
  33. }
  34. if dbConfig.MaxConnections == 0 {
  35. dbConfig.MaxConnections = 50
  36. }
  37. if dbConfig.MaxIdleConnections == 0 {
  38. dbConfig.MaxIdleConnections = 10
  39. }
  40. sqlDB.SetMaxOpenConns(dbConfig.MaxConnections)
  41. sqlDB.SetMaxIdleConns(dbConfig.MaxIdleConnections)
  42. op := &Operations{
  43. db: gormDB,
  44. stopPingChan: make(chan any),
  45. }
  46. op.startBeatHeart(sqlDB)
  47. return op, nil
  48. }
  49. func DestroyOperation(op *Operations) error {
  50. if op == nil {
  51. return nil
  52. }
  53. if op.db == nil {
  54. return nil
  55. }
  56. op.stopBeatHeart()
  57. err := destroyGormDB(op.db)
  58. if err != nil {
  59. return err
  60. }
  61. op = nil
  62. return nil
  63. }
  64. func (op *Operations) startBeatHeart(sqlDB *dbSql.DB) {
  65. go func() {
  66. pingTicker := time.NewTicker(time.Minute * 1)
  67. defer pingTicker.Stop()
  68. for {
  69. select {
  70. case <-op.stopPingChan:
  71. return
  72. case <-pingTicker.C:
  73. err := sqlDB.Ping()
  74. if err != nil {
  75. logger.GetInstance().Error(err)
  76. }
  77. }
  78. }
  79. }()
  80. }
  81. func (op *Operations) stopBeatHeart() {
  82. if op.stopPingChan != nil {
  83. op.stopPingChan <- nil
  84. close(op.stopPingChan)
  85. op.stopPingChan = nil
  86. }
  87. }
  88. func (op *Operations) BeginTransaction() *Operations {
  89. tx := op.db.Begin()
  90. return &Operations{
  91. db: tx,
  92. }
  93. }
  94. func (op *Operations) RollbackTransaction() {
  95. op.db.Rollback()
  96. }
  97. func (op *Operations) CommitTransaction() {
  98. op.db.Commit()
  99. }
  100. func (op *Operations) AutoMigrate(tables ...Table) error {
  101. tx := op.db.Begin()
  102. for _, table := range tables {
  103. dbModel, err := table.ToDBModel()
  104. if err != nil {
  105. tx.Rollback()
  106. return err
  107. }
  108. err = tx.Table(table.TableName).AutoMigrate(dbModel)
  109. if err != nil {
  110. tx.Rollback()
  111. return errors.New(err.Error())
  112. }
  113. }
  114. tx.Commit()
  115. return nil
  116. }
  117. func (op *Operations) ExecuteRawSql(sqlStr string, args ...any) ([]sql.Result, error) {
  118. return op.ExecuteRawSqlTemplate(sqlStr, nil, args...)
  119. }
  120. func (op *Operations) ExecuteRawSqlTemplate(sqlStr string, executeParams map[string]any, args ...any) ([]sql.Result, error) {
  121. parsedSql, err := template.ParseTemplateStringToString(sqlStr, executeParams)
  122. if err != nil {
  123. return nil, errors.New(err.Error())
  124. }
  125. tableRows := make([]map[string]any, 0)
  126. err = op.db.Raw(parsedSql, args...).Scan(&tableRows).Error
  127. if err != nil {
  128. return nil, errors.New(err.Error())
  129. }
  130. results := make([]sql.Result, len(tableRows))
  131. for i, row := range tableRows {
  132. results[i] = row
  133. }
  134. return results, nil
  135. }