package config import ( "fmt" "os" "strconv" "time" "github.com/jackc/pgx/v5/pgxpool" ) // DatabaseConfig holds database configuration type DatabaseConfig struct { Host string Port int User string Password string Database string SSLMode string MaxConnections int MaxIdleTime time.Duration ConnMaxLifetime time.Duration } // LoadDatabaseConfig loads database configuration from environment variables func LoadDatabaseConfig() *DatabaseConfig { maxConns, _ := strconv.Atoi(getEnv("DB_MAX_CONNECTIONS", "25")) maxIdle, _ := time.ParseDuration(getEnv("DB_MAX_IDLE_TIME", "5m")) maxLifetime, _ := time.ParseDuration(getEnv("DB_CONN_MAX_LIFETIME", "1h")) return &DatabaseConfig{ Host: getEnv("DB_HOST", "localhost"), Port: getIntEnv("DB_PORT", 5432), User: getEnv("DB_USER", "explorer"), Password: getEnv("DB_PASSWORD", ""), Database: getEnv("DB_NAME", "explorer"), SSLMode: getEnv("DB_SSLMODE", "disable"), MaxConnections: maxConns, MaxIdleTime: maxIdle, ConnMaxLifetime: maxLifetime, } } // ConnectionString returns PostgreSQL connection string func (c *DatabaseConfig) ConnectionString() string { return fmt.Sprintf( "host=%s port=%d user=%s password=%s dbname=%s sslmode=%s", c.Host, c.Port, c.User, c.Password, c.Database, c.SSLMode, ) } // PoolConfig returns pgxpool configuration func (c *DatabaseConfig) PoolConfig() (*pgxpool.Config, error) { config, err := pgxpool.ParseConfig(c.ConnectionString()) if err != nil { return nil, err } config.MaxConns = int32(c.MaxConnections) config.MaxConnIdleTime = c.MaxIdleTime config.MaxConnLifetime = c.ConnMaxLifetime return config, nil } // ReadReplicaConfig holds read replica configuration type ReadReplicaConfig struct { Host string Port int User string Password string Database string SSLMode string } // LoadReadReplicaConfig loads read replica configuration func LoadReadReplicaConfig() *ReadReplicaConfig { return &ReadReplicaConfig{ Host: getEnv("DB_REPLICA_HOST", ""), Port: getIntEnv("DB_REPLICA_PORT", 5432), User: getEnv("DB_REPLICA_USER", ""), Password: getEnv("DB_REPLICA_PASSWORD", ""), Database: getEnv("DB_REPLICA_NAME", ""), SSLMode: getEnv("DB_REPLICA_SSLMODE", "disable"), } } func getEnv(key, defaultValue string) string { if value := os.Getenv(key); value != "" { return value } return defaultValue } func getIntEnv(key string, defaultValue int) int { if value := os.Getenv(key); value != "" { if intValue, err := strconv.Atoi(value); err == nil { return intValue } } return defaultValue }