feat: Refactor database configuration loading and seeding logic for improved clarity and maintainability
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
"github.com/timetracker/backend/internal/models"
|
||||
"gorm.io/gorm/logger"
|
||||
)
|
||||
|
||||
// Config represents the application configuration
|
||||
type Config struct {
|
||||
Database models.DatabaseConfig
|
||||
}
|
||||
|
||||
// LoadConfig loads configuration from environment variables and .env file
|
||||
func LoadConfig() (*Config, error) {
|
||||
// Try loading .env file, but don't fail if it doesn't exist
|
||||
_ = godotenv.Load()
|
||||
|
||||
cfg := &Config{
|
||||
Database: models.DefaultDatabaseConfig(),
|
||||
}
|
||||
|
||||
// Load database configuration
|
||||
if err := loadDatabaseConfig(cfg); err != nil {
|
||||
return nil, fmt.Errorf("failed to load database config: %w", err)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
// loadDatabaseConfig loads database configuration from environment
|
||||
func loadDatabaseConfig(cfg *Config) error {
|
||||
// Required fields
|
||||
cfg.Database.Host = getEnv("DB_HOST", cfg.Database.Host)
|
||||
cfg.Database.User = getEnv("DB_USER", cfg.Database.User)
|
||||
cfg.Database.Password = getEnv("DB_PASSWORD", cfg.Database.Password)
|
||||
cfg.Database.DBName = getEnv("DB_NAME", cfg.Database.DBName)
|
||||
cfg.Database.SSLMode = getEnv("DB_SSLMODE", cfg.Database.SSLMode)
|
||||
|
||||
// Optional fields with parsing
|
||||
if port := getEnv("DB_PORT", ""); port != "" {
|
||||
portInt, err := strconv.Atoi(port)
|
||||
if err != nil || portInt <= 0 {
|
||||
return errors.New("invalid DB_PORT value")
|
||||
}
|
||||
cfg.Database.Port = portInt
|
||||
}
|
||||
|
||||
// Log level based on environment
|
||||
if os.Getenv("ENVIRONMENT") == "production" {
|
||||
cfg.Database.LogLevel = logger.Error
|
||||
} else {
|
||||
cfg.Database.LogLevel = logger.Info
|
||||
}
|
||||
|
||||
// Validate required fields
|
||||
if cfg.Database.Host == "" || cfg.Database.User == "" ||
|
||||
cfg.Database.Password == "" || cfg.Database.DBName == "" {
|
||||
return errors.New("missing required database configuration")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getEnv gets an environment variable with fallback
|
||||
func getEnv(key, fallback string) string {
|
||||
if value, exists := os.LookupEnv(key); exists {
|
||||
return value
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
// MustLoadConfig loads configuration or panics on failure
|
||||
func MustLoadConfig() *Config {
|
||||
cfg, err := LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load config: %v", err)
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
Reference in New Issue
Block a user