All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
120 lines
2.9 KiB
Go
120 lines
2.9 KiB
Go
package database
|
|
|
|
import (
|
|
"cargo-erp-backend/internal/config"
|
|
"cargo-erp-backend/internal/logger"
|
|
"fmt"
|
|
"net/url"
|
|
"sync"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type DatabaseInterface interface {
|
|
Connect()
|
|
Close()
|
|
Get(key string) *gorm.DB
|
|
RegisterCallback()
|
|
}
|
|
type Database struct {
|
|
Config config.ConfigInterface
|
|
DB map[string]*gorm.DB
|
|
dbLock sync.RWMutex
|
|
Logger *zap.Logger
|
|
AppLogger *zap.Logger
|
|
}
|
|
|
|
func NewDatabase(config config.ConfigInterface, logger *zap.Logger, app_logger *zap.Logger) DatabaseInterface {
|
|
return &Database{
|
|
Config: config,
|
|
Logger: logger,
|
|
AppLogger: app_logger,
|
|
}
|
|
}
|
|
func (d *Database) Connect() {
|
|
d.dbLock.Lock()
|
|
defer d.dbLock.Unlock()
|
|
db := make(map[string]*gorm.DB)
|
|
username := d.Config.Get("database.username").(string)
|
|
password := d.Config.Get("database.password").(string)
|
|
dbname := d.Config.Get("database.database").(string)
|
|
host_master := fmt.Sprintf("%v", d.Config.Get("database.master.host"))
|
|
port_master := fmt.Sprintf("%v", d.Config.Get("database.master.port"))
|
|
ssl_master := d.Config.Get("database.master.ssl")
|
|
dsnMaster := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s",
|
|
url.PathEscape(username),
|
|
url.PathEscape(password),
|
|
host_master,
|
|
port_master,
|
|
dbname,
|
|
ssl_master,
|
|
)
|
|
d.AppLogger.Info("Connect To Master DB")
|
|
gormLogger := logger.NewGormZapLogger(d.Logger, 5*time.Second)
|
|
dbMaster, err := gorm.Open(postgres.Open(dsnMaster), &gorm.Config{
|
|
Logger: gormLogger,
|
|
})
|
|
if err != nil {
|
|
d.AppLogger.Fatal(err.Error())
|
|
return
|
|
}
|
|
db["master"] = dbMaster
|
|
d.AppLogger.Info("DB Master Connected")
|
|
|
|
host_slave := fmt.Sprintf("%v", d.Config.Get("database.slave.host"))
|
|
port_slave := fmt.Sprintf("%v", d.Config.Get("database.slave.port"))
|
|
ssl_slave := d.Config.Get("database.slave.ssl")
|
|
dsnSlave := fmt.Sprintf("postgres://%s:%s@%s:%s/%s?sslmode=%s",
|
|
url.PathEscape(username),
|
|
url.PathEscape(password),
|
|
host_slave,
|
|
port_slave,
|
|
dbname,
|
|
ssl_slave,
|
|
)
|
|
d.AppLogger.Info("Connect To Slave DB")
|
|
dbSlave, err := gorm.Open(postgres.Open(dsnSlave), &gorm.Config{
|
|
Logger: gormLogger,
|
|
})
|
|
if err != nil {
|
|
d.AppLogger.Fatal(err.Error())
|
|
return
|
|
}
|
|
db["slave"] = dbSlave
|
|
d.DB = db
|
|
d.AppLogger.Info("DB Connection Done")
|
|
}
|
|
func (d *Database) RegisterCallback() {
|
|
d.Config.RegisterOnChangeCallback(d.ReloadDB)
|
|
}
|
|
func (d *Database) Get(key string) *gorm.DB {
|
|
d.dbLock.RLock()
|
|
defer d.dbLock.RUnlock()
|
|
if v, ok := d.DB[key]; ok {
|
|
return v
|
|
}
|
|
return nil
|
|
}
|
|
func (d *Database) Close() {
|
|
d.dbLock.Lock()
|
|
defer d.dbLock.Unlock()
|
|
d.AppLogger.Info("Close Database Connection Start")
|
|
for k, db := range d.DB {
|
|
if db != nil {
|
|
sqlDb, _ := db.DB()
|
|
sqlDb.Close()
|
|
d.AppLogger.Info(fmt.Sprintf("Close Database Connection %s", k))
|
|
}
|
|
}
|
|
d.AppLogger.Info("Close Database Connection Done")
|
|
}
|
|
func (d *Database) ReloadDB() {
|
|
d.AppLogger.Info("Reload Connecting Database")
|
|
d.Close()
|
|
d.Connect()
|
|
d.AppLogger.Info("Reload Connecting Database Done")
|
|
}
|