cargo-platform/internal/database/database.go
teguh nugroho 39265bfcb1
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
oerubahan
2026-09-05 14:31:03 +07:00

126 lines
3.1 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.New(postgres.Config{
DSN: dsnMaster,
PreferSimpleProtocol: true,
}), &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.New(postgres.Config{
DSN: dsnSlave,
PreferSimpleProtocol: true,
}), &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")
}