85 lines
2.1 KiB
Go
85 lines
2.1 KiB
Go
package db
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"time"
|
|
|
|
"github.com/timetracker/backend/internal/config"
|
|
"gorm.io/driver/postgres"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
)
|
|
|
|
// Global variable for the DB connection
|
|
var db *gorm.DB
|
|
|
|
// InitDB initializes the database connection (once at startup)
|
|
// with the provided configuration
|
|
func InitDB(config config.DatabaseConfig) error {
|
|
// Create DSN (Data Source Name)
|
|
dsn := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
|
|
config.Host, config.Port, config.User, config.Password, config.DBName, config.SSLMode)
|
|
|
|
// Configure GORM logger
|
|
gormLogger := logger.New(
|
|
log.New(log.Writer(), "\r\n", log.LstdFlags), // io writer
|
|
logger.Config{
|
|
SlowThreshold: 200 * time.Millisecond, // Slow SQL threshold
|
|
LogLevel: config.LogLevel, // Log level
|
|
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
|
|
Colorful: true, // Enable color
|
|
},
|
|
)
|
|
|
|
// Establish database connection with custom logger
|
|
var err error
|
|
db, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
|
|
Logger: gormLogger,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("error connecting to the database: %w", err)
|
|
}
|
|
|
|
// Configure connection pool
|
|
sqlDB, err := db.DB()
|
|
if err != nil {
|
|
return fmt.Errorf("error getting database connection: %w", err)
|
|
}
|
|
|
|
// Set connection pool parameters
|
|
sqlDB.SetMaxIdleConns(config.MaxIdleConns)
|
|
sqlDB.SetMaxOpenConns(config.MaxOpenConns)
|
|
sqlDB.SetConnMaxLifetime(config.MaxLifetime)
|
|
|
|
return nil
|
|
}
|
|
|
|
// GetEngine returns the DB instance, possibly with context
|
|
func GetEngine(ctx context.Context) *gorm.DB {
|
|
if db == nil {
|
|
panic("database not initialized")
|
|
}
|
|
// If a special transaction is in ctx, you could check it here
|
|
return db.WithContext(ctx)
|
|
}
|
|
|
|
// CloseDB closes the database connection
|
|
func CloseDB() error {
|
|
if db == nil {
|
|
return nil
|
|
}
|
|
|
|
sqlDB, err := db.DB()
|
|
if err != nil {
|
|
return fmt.Errorf("error getting database connection: %w", err)
|
|
}
|
|
|
|
if err := sqlDB.Close(); err != nil {
|
|
return fmt.Errorf("error closing database connection: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|