initiate repo
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
func LoadConfig() *Config {
|
||||
errLoadEnv := godotenv.Load()
|
||||
if errLoadEnv != nil {
|
||||
log.Println("error loading .env")
|
||||
}
|
||||
|
||||
config := &Config{
|
||||
Server: ServerConfig{
|
||||
Port: getEnvAsInt("PORT", 8080),
|
||||
Mode: getEnv("GIN_MODE", "debug"),
|
||||
},
|
||||
Databases: make(map[string]DatabaseConfig),
|
||||
}
|
||||
|
||||
config.loadCustomDatabaseConfigs()
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
func (c *Config) loadCustomDatabaseConfigs() {
|
||||
envVars := os.Environ()
|
||||
dbConfigs := make(map[string]map[string]string)
|
||||
|
||||
// Parse database configurations from environment variables
|
||||
for _, envVar := range envVars {
|
||||
parts := strings.SplitN(envVar, "=", 2)
|
||||
if len(parts) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
key := parts[0]
|
||||
value := parts[1]
|
||||
|
||||
// Parse specific database configurations
|
||||
if strings.HasSuffix(key, "_CONNECTION") || strings.HasSuffix(key, "_HOST") ||
|
||||
strings.HasSuffix(key, "_DATABASE") || strings.HasSuffix(key, "_USERNAME") ||
|
||||
strings.HasSuffix(key, "_PASSWORD") || strings.HasSuffix(key, "_PORT") ||
|
||||
strings.HasSuffix(key, "_NAME") {
|
||||
|
||||
segments := strings.Split(key, "_")
|
||||
if len(segments) >= 2 {
|
||||
dbName := strings.ToLower(strings.Join(segments[:len(segments)-1], "_"))
|
||||
property := strings.ToLower(segments[len(segments)-1])
|
||||
|
||||
if dbConfigs[dbName] == nil {
|
||||
dbConfigs[dbName] = make(map[string]string)
|
||||
}
|
||||
dbConfigs[dbName][property] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create DatabaseConfig from parsed configurations for additional databases
|
||||
for name, config := range dbConfigs {
|
||||
// Skip empty configurations or system configurations
|
||||
if name == "" || strings.Contains(name, "chrome_crashpad_pipe") || name == "primary" {
|
||||
continue
|
||||
}
|
||||
|
||||
dbType := getEnvFromMap(config, "connection", getEnvFromMap(config, "type", "postgres"))
|
||||
|
||||
// Skip if username is empty and it's not a system config
|
||||
username := getEnvFromMap(config, "username", "")
|
||||
if username == "" && !strings.HasPrefix(name, "chrome") {
|
||||
continue
|
||||
}
|
||||
|
||||
dbConfig := DatabaseConfig{
|
||||
Name: name,
|
||||
Type: dbType,
|
||||
Host: getEnvFromMap(config, "host", "localhost"),
|
||||
Port: getEnvAsIntFromMap(config, "port", getDefaultPort(dbType)),
|
||||
Username: username,
|
||||
Password: getEnvFromMap(config, "password", ""),
|
||||
Database: getEnvFromMap(config, "database", getEnvFromMap(config, "name", name)),
|
||||
Schema: getEnvFromMap(config, "schema", getDefaultSchema(dbType)),
|
||||
SSLMode: getEnvFromMap(config, "sslmode", getDefaultSSLMode(dbType)),
|
||||
Path: getEnvFromMap(config, "path", ""),
|
||||
Options: getEnvFromMap(config, "options", ""),
|
||||
MaxOpenConns: getEnvAsIntFromMap(config, "max_open_conns", getDefaultMaxOpenConns(dbType)),
|
||||
MaxIdleConns: getEnvAsIntFromMap(config, "max_idle_conns", getDefaultMaxIdleConns(dbType)),
|
||||
ConnMaxLifetime: parseDuration(getEnvFromMap(config, "conn_max_lifetime", getDefaultConnMaxLifetime(dbType))),
|
||||
// Security settings
|
||||
RequireSSL: getEnvAsBoolFromMap(config, "require_ssl", false),
|
||||
SSLRootCert: getEnvFromMap(config, "ssl_root_cert", ""),
|
||||
SSLCert: getEnvFromMap(config, "ssl_cert", ""),
|
||||
SSLKey: getEnvFromMap(config, "ssl_key", ""),
|
||||
Timeout: parseDuration(getEnvFromMap(config, "timeout", "30s")),
|
||||
ConnectTimeout: parseDuration(getEnvFromMap(config, "connect_timeout", "10s")),
|
||||
ReadTimeout: parseDuration(getEnvFromMap(config, "read_timeout", "30s")),
|
||||
WriteTimeout: parseDuration(getEnvFromMap(config, "write_timeout", "30s")),
|
||||
StatementTimeout: parseDuration(getEnvFromMap(config, "statement_timeout", "360s")),
|
||||
// Connection pool settings
|
||||
MaxLifetime: parseDuration(getEnvFromMap(config, "max_lifetime", "1h")),
|
||||
MaxIdleTime: parseDuration(getEnvFromMap(config, "max_idle_time", "5m")),
|
||||
HealthCheckPeriod: parseDuration(getEnvFromMap(config, "health_check_period", "1m")),
|
||||
}
|
||||
|
||||
c.Databases[name] = dbConfig
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
func getEnv(key, defaultValue string) string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getEnvAsInt(key string, defaultValue int) int {
|
||||
valueStr := getEnv(key, "")
|
||||
if value, err := strconv.Atoi(valueStr); err == nil {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getEnvFromMap(config map[string]string, key, defaultValue string) string {
|
||||
if value, exists := config[key]; exists {
|
||||
return value
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getEnvAsIntFromMap(config map[string]string, key string, defaultValue int) int {
|
||||
if value, exists := config[key]; exists {
|
||||
if intValue, err := strconv.Atoi(value); err == nil {
|
||||
return intValue
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getEnvAsBoolFromMap(config map[string]string, key string, defaultValue bool) bool {
|
||||
if value, exists := config[key]; exists {
|
||||
if boolValue, err := strconv.ParseBool(value); err == nil {
|
||||
return boolValue
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
// Helper functions for getting default values based on database type
|
||||
func getDefaultPort(dbType string) int {
|
||||
switch dbType {
|
||||
case "postgres":
|
||||
return 5432
|
||||
case "mysql":
|
||||
return 3306
|
||||
case "sqlserver":
|
||||
return 1433
|
||||
case "mongodb":
|
||||
return 27017
|
||||
case "sqlite":
|
||||
return 0 // SQLite doesn't use port
|
||||
default:
|
||||
return 5432
|
||||
}
|
||||
}
|
||||
|
||||
func getDefaultSchema(dbType string) string {
|
||||
switch dbType {
|
||||
case "postgres":
|
||||
return "public"
|
||||
case "mysql":
|
||||
return ""
|
||||
case "sqlserver":
|
||||
return "dbo"
|
||||
case "mongodb":
|
||||
return ""
|
||||
case "sqlite":
|
||||
return ""
|
||||
default:
|
||||
return "public"
|
||||
}
|
||||
}
|
||||
|
||||
func getDefaultSSLMode(dbType string) string {
|
||||
switch dbType {
|
||||
case "postgres":
|
||||
return "disable"
|
||||
case "mysql":
|
||||
return "false"
|
||||
case "sqlserver":
|
||||
return "false"
|
||||
case "mongodb":
|
||||
return "false"
|
||||
case "sqlite":
|
||||
return ""
|
||||
default:
|
||||
return "disable"
|
||||
}
|
||||
}
|
||||
|
||||
func getDefaultMaxOpenConns(dbType string) int {
|
||||
switch dbType {
|
||||
case "postgres":
|
||||
return 25
|
||||
case "mysql":
|
||||
return 25
|
||||
case "sqlserver":
|
||||
return 25
|
||||
case "mongodb":
|
||||
return 100
|
||||
case "sqlite":
|
||||
return 1 // SQLite only supports one writer at a time
|
||||
default:
|
||||
return 25
|
||||
}
|
||||
}
|
||||
|
||||
func getDefaultMaxIdleConns(dbType string) int {
|
||||
switch dbType {
|
||||
case "postgres":
|
||||
return 25
|
||||
case "mysql":
|
||||
return 25
|
||||
case "sqlserver":
|
||||
return 25
|
||||
case "mongodb":
|
||||
return 10
|
||||
case "sqlite":
|
||||
return 1 // SQLite only supports one writer at a time
|
||||
default:
|
||||
return 25
|
||||
}
|
||||
}
|
||||
|
||||
func getDefaultConnMaxLifetime(dbType string) string {
|
||||
switch dbType {
|
||||
case "postgres":
|
||||
return "5m"
|
||||
case "mysql":
|
||||
return "5m"
|
||||
case "sqlserver":
|
||||
return "5m"
|
||||
case "mongodb":
|
||||
return "30m"
|
||||
case "sqlite":
|
||||
return "5m"
|
||||
default:
|
||||
return "5m"
|
||||
}
|
||||
}
|
||||
|
||||
func parseDuration(durationStr string) time.Duration {
|
||||
if duration, err := time.ParseDuration(durationStr); err == nil {
|
||||
return duration
|
||||
}
|
||||
return 5 * time.Minute
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package config
|
||||
|
||||
import "time"
|
||||
|
||||
type Config struct {
|
||||
Server ServerConfig
|
||||
Databases map[string]DatabaseConfig
|
||||
ReadReplicas map[string][]DatabaseConfig
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
Port int
|
||||
Mode string
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
Name string
|
||||
Type string // postgres, mysql, sqlserver, sqlite, mongodb
|
||||
Host string
|
||||
Port int
|
||||
Username string
|
||||
Password string
|
||||
Database string
|
||||
Schema string
|
||||
SSLMode string
|
||||
Path string // For SQLite
|
||||
Options string // Additional connection options
|
||||
MaxOpenConns int // Max open connections
|
||||
MaxIdleConns int // Max idle connections
|
||||
ConnMaxLifetime time.Duration // Connection max lifetime
|
||||
// Security settings
|
||||
RequireSSL bool // Require SSL connection
|
||||
SSLRootCert string // Path to SSL root certificate
|
||||
SSLCert string // Path to SSL client certificate
|
||||
SSLKey string // Path to SSL client key
|
||||
Timeout time.Duration // Connection timeout
|
||||
ConnectTimeout time.Duration // Connect timeout
|
||||
ReadTimeout time.Duration // Read timeout
|
||||
WriteTimeout time.Duration // Write timeout
|
||||
StatementTimeout time.Duration // Statement timeout for PostgreSQL
|
||||
// Connection pool settings
|
||||
MaxLifetime time.Duration // Maximum amount of time a connection may be reused
|
||||
MaxIdleTime time.Duration // Maximum amount of time a connection may be idle
|
||||
HealthCheckPeriod time.Duration // Health check period
|
||||
}
|
||||
Reference in New Issue
Block a user