From 6e817a8bd265432b41333e1ccb9dca1e3bbffea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Benouarets?= Date: Tue, 30 Sep 2025 11:44:25 +0200 Subject: [PATCH] feat: implement database connection and configuration management - Add database configuration with environment variable support - Support both PostgreSQL and SQLite database drivers - Implement connection pooling and timeout configuration - Add automatic database migration system - Include connection health checks and error handling - Configure SSL mode and connection parameters - Add utility functions for environment variable management --- config/database.go | 26 +++++++++++ database/connection.go | 103 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) create mode 100644 config/database.go create mode 100644 database/connection.go diff --git a/config/database.go b/config/database.go new file mode 100644 index 0000000..f37d51f --- /dev/null +++ b/config/database.go @@ -0,0 +1,26 @@ +package config + +import "git.secnex.io/secnex/certman/utils" + +// Config holds database configuration +type Config struct { + Host string + Port string + User string + Password string + DBName string + SSLMode string + Driver string // "postgres" or "sqlite" +} + +func GetConfig() *Config { + return &Config{ + Host: utils.GetEnv("DB_HOST", "localhost"), + Port: utils.GetEnv("DB_PORT", "5432"), + User: utils.GetEnv("DB_USER", "postgres"), + Password: utils.GetEnv("DB_PASSWORD", "password"), + DBName: utils.GetEnv("DB_NAME", "certman"), + SSLMode: utils.GetEnv("DB_SSLMODE", "disable"), + Driver: utils.GetEnv("DB_DRIVER", "postgres"), + } +} diff --git a/database/connection.go b/database/connection.go new file mode 100644 index 0000000..cc3c5de --- /dev/null +++ b/database/connection.go @@ -0,0 +1,103 @@ +package database + +import ( + "fmt" + "log" + "time" + + "git.secnex.io/secnex/certman/config" + "git.secnex.io/secnex/certman/models" + "gorm.io/driver/postgres" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +// DB is the global database instance +var DB *gorm.DB + +// Connect establishes database connection and runs migrations +func Connect() error { + config := config.GetConfig() + + var err error + var dsn string + + switch config.Driver { + case "postgres": + dsn = fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=%s", + config.Host, config.Port, config.User, config.Password, config.DBName, config.SSLMode) + DB, err = gorm.Open(postgres.Open(dsn), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Info), + }) + case "sqlite": + dsn = config.DBName + ".db" + DB, err = gorm.Open(sqlite.Open(dsn), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Info), + }) + default: + return fmt.Errorf("unsupported database driver: %s", config.Driver) + } + + if err != nil { + return fmt.Errorf("failed to connect to database: %w", err) + } + + // Configure connection pool + sqlDB, err := DB.DB() + if err != nil { + return fmt.Errorf("failed to get underlying sql.DB: %w", err) + } + + // Set connection pool settings + sqlDB.SetMaxIdleConns(10) + sqlDB.SetMaxOpenConns(100) + sqlDB.SetConnMaxLifetime(time.Hour) + + log.Printf("Successfully connected to %s database", config.Driver) + + // Run migrations + if err := Migrate(); err != nil { + return fmt.Errorf("failed to run migrations: %w", err) + } + + return nil +} + +// Migrate runs database migrations for all models +func Migrate() error { + log.Println("🚀 Running database migrations...") + + err := DB.AutoMigrate( + &models.CertificateAuthority{}, + &models.Certificate{}, + &models.CertificateRequest{}, + &models.CertificateRevocationList{}, + &models.Organization{}, + &models.User{}, + ) + + if err != nil { + return fmt.Errorf("migration failed: %w", err) + } + + log.Println("✅ Database migrations completed successfully") + return nil +} + +// Close closes the database connection +func Close() error { + if DB != nil { + sqlDB, err := DB.DB() + if err != nil { + return fmt.Errorf("failed to get underlying sql.DB: %w", err) + } + return sqlDB.Close() + } + return nil +} + +// GetDB returns the database instance +func GetDB() *gorm.DB { + return DB +}