From f953f6d64666c6be314b637cfdf169782e4dc4d0 Mon Sep 17 00:00:00 2001 From: Meninjar Date: Mon, 18 Aug 2025 14:08:18 +0700 Subject: [PATCH] FIX THEMPLATE DATA BASE MULTY --- example.env | 64 ++++++- internal/config/config.go | 229 +++++++++++++++++++++-- internal/database/database.go | 14 +- internal/handlers/retribusi/retribusi.go | 12 +- 4 files changed, 280 insertions(+), 39 deletions(-) diff --git a/example.env b/example.env index 830a9e3..547d2fe 100644 --- a/example.env +++ b/example.env @@ -2,15 +2,61 @@ PORT=8080 GIN_MODE=debug -# Primary Database Configuration (PostgreSQL) -SATUDATA_CONNECTION=postgres -SATUDATA_USERNAME=stim -SATUDATA_PASSWORD=stim*RS54 -SATUDATA_HOST=10.10.123.165 -SATUDATA_DATABASE=satu_db -SATUDATA_NAME=satu_db -SATUDATA_PORT=5000 -SATUDATA_SSLMODE=disable +# Default Database Configuration (PostgreSQL) +DB_CONNECTION=postgres +DB_USERNAME=stim +DB_PASSWORD=stim*RS54 +DB_HOST=10.10.123.165 +DB_DATABASE=satu_db +DB_PORT=5000 +DB_SSLMODE=disable + +# satudata Database Configuration (PostgreSQL) +# POSTGRES_CONNECTION=postgres +# POSTGRES_USERNAME=stim +# POSTGRES_PASSWORD=stim*RS54 +# POSTGRES_HOST=10.10.123.165 +# POSTGRES_DATABASE=satu_db +# POSTGRES_NAME=satu_db +# POSTGRES_PORT=5000 +# POSTGRES_SSLMODE=disable + + +POSTGRES_SATUDATA_CONNECTION=postgres +POSTGRES_SATUDATA_USERNAME=stim +POSTGRES_SATUDATA_PASSWORD=stim*RS54 +POSTGRES_SATUDATA_HOST=10.10.123.165 +POSTGRES_SATUDATA_DATABASE=satu_db +POSTGRES_SATUDATA_PORT=5000 +POSTGRES_SATUDATA_SSLMODE=disable + +# Mongo Database +MONGODB_MONGOHL7_CONNECTION=mongodb +MONGODB_MONGOHL7_HOST=10.10.123.206 +MONGODB_MONGOHL7_PORT=27017 +MONGODB_MONGOHL7_USER=admin +MONGODB_MONGOHL7_PASS=stim*rs54 +MONGODB_MONGOHL7_MASTER=master +MONGODB_MONGOHL7_LOCAL=local +MONGODB_MONGOHL7_SSLMODE=disable + +# MYSQL Antrian Database +# MYSQL_ANTRIAN_CONNECTION=mysql +# MYSQL_ANTRIAN_HOST=10.10.123.163 +# MYSQL_ANTRIAN_USERNAME=www-data +# MYSQL_ANTRIAN_PASSWORD=www-data +# MYSQL_ANTRIAN_DATABASE=antrian_rssa +# MYSQL_ANTRIAN_PORT=5432 +# MYSQL_ANTRIAN_SSLMODE=disable + + +MYSQL_MEDICAL_CONNECTION=mysql +MYSQL_MEDICAL_HOST=10.10.123.147 +MYSQL_MEDICAL_USERNAME=meninjardev +MYSQL_MEDICAL_PASSWORD=meninjar*RS54 +MYSQL_MEDICAL_DATABASE=healtcare_database +MYSQL_MEDICAL_PORT=3306 +MYSQL_MEDICAL_SSLMODE=disable # Keycloak Configuration (optional) KEYCLOAK_ISSUER=https://auth.rssa.top/realms/sandbox diff --git a/internal/config/config.go b/internal/config/config.go index 155f170..fd94038 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -74,8 +74,8 @@ func (c *Config) loadDatabaseConfigs() { // This ensures we get the exact values specified in .env // Primary database configuration - c.Databases["primary"] = DatabaseConfig{ - Name: "primary", + c.Databases["default"] = DatabaseConfig{ + Name: "default", Type: getEnv("DB_CONNECTION", "postgres"), Host: getEnv("DB_HOST", "localhost"), Port: getEnvAsInt("DB_PORT", 5432), @@ -90,20 +90,10 @@ func (c *Config) loadDatabaseConfigs() { } // SATUDATA database configuration - c.Databases["satudata"] = DatabaseConfig{ - Name: "satudata", - Type: getEnv("SATUDATA_CONNECTION", "postgres"), - Host: getEnv("SATUDATA_HOST", "localhost"), - Port: getEnvAsInt("SATUDATA_PORT", 5432), - Username: getEnv("SATUDATA_USERNAME", ""), - Password: getEnv("SATUDATA_PASSWORD", ""), - Database: getEnv("SATUDATA_DATABASE", "satu_db"), - Schema: getEnv("SATUDATA_SCHEMA", "public"), - SSLMode: getEnv("SATUDATA_SSLMODE", "disable"), - MaxOpenConns: getEnvAsInt("SATUDATA_MAX_OPEN_CONNS", 25), - MaxIdleConns: getEnvAsInt("SATUDATA_MAX_IDLE_CONNS", 25), - ConnMaxLifetime: parseDuration(getEnv("SATUDATA_CONN_MAX_LIFETIME", "5m")), - } + c.addPostgreSQLConfigs() + + // MongoDB database configuration + c.addMongoDBConfigs() // Legacy support for backward compatibility envVars := os.Environ() @@ -141,7 +131,7 @@ func (c *Config) loadDatabaseConfigs() { // 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" || name == "satudata" { + if name == "" || strings.Contains(name, "chrome_crashpad_pipe") || name == "primary" { continue } @@ -275,6 +265,211 @@ func (c *Config) addSpecificDatabase(prefix, defaultType string) { c.Databases[prefix] = dbConfig } } +// PostgreSQL database +func (c *Config) addPostgreSQLConfigs() { + // SATUDATA database configuration + // defaultPOSTGRESHost := getEnv("POSTGRES_HOST", "localhost") + // if defaultPOSTGRESHost != "" { + // c.Databases["postgres"] = DatabaseConfig{ + // Name: "postgres", + // Type: getEnv("POSTGRES_CONNECTION", "postgres"), + // Host: defaultPOSTGRESHost, + // Port: getEnvAsInt("POSTGRES_PORT", 5432), + // Username: getEnv("POSTGRES_USERNAME", ""), + // Password: getEnv("POSTGRES_PASSWORD", ""), + // Database: getEnv("POSTGRES_DATABASE", "postgres"), + // Schema: getEnv("POSTGRES_SCHEMA", "public"), + // SSLMode: getEnv("POSTGRES_SSLMODE", "disable"), + // MaxOpenConns: getEnvAsInt("POSTGRES_MAX_OPEN_CONNS", 25), + // MaxIdleConns: getEnvAsInt("POSTGRES_MAX_IDLE_CONNS", 25), + // ConnMaxLifetime: parseDuration(getEnv("POSTGRES_CONN_MAX_LIFETIME", "5m")), + // } + // } + + // Support for custom PostgreSQL configurations with POSTGRES_ prefix + envVars := os.Environ() + for _, envVar := range envVars { + parts := strings.SplitN(envVar, "=", 2) + if len(parts) != 2 { + continue + } + + key := parts[0] + // Parse PostgreSQL configurations (format: POSTGRES_[NAME]_[PROPERTY]) + if strings.HasPrefix(key, "POSTGRES_") && strings.Contains(key, "_") { + segments := strings.Split(key, "_") + if len(segments) >= 3 { + dbName := strings.ToLower(strings.Join(segments[1:len(segments)-1], "_")) + + // Skip if it's a standard PostgreSQL configuration + if dbName == "connection" || dbName == "dev" || dbName == "default" || dbName == "satudata" { + continue + } + + // Create or update PostgreSQL configuration + if _, exists := c.Databases[dbName]; !exists { + c.Databases[dbName] = DatabaseConfig{ + Name: dbName, + Type: "postgres", + Host: getEnv("POSTGRES_"+strings.ToUpper(dbName)+"_HOST", "localhost"), + Port: getEnvAsInt("POSTGRES_"+strings.ToUpper(dbName)+"_PORT", 5432), + Username: getEnv("POSTGRES_"+strings.ToUpper(dbName)+"_USERNAME", ""), + Password: getEnv("POSTGRES_"+strings.ToUpper(dbName)+"_PASSWORD", ""), + Database: getEnv("POSTGRES_"+strings.ToUpper(dbName)+"_DATABASE", dbName), + Schema: getEnv("POSTGRES_"+strings.ToUpper(dbName)+"_SCHEMA", "public"), + SSLMode: getEnv("POSTGRES_"+strings.ToUpper(dbName)+"_SSLMODE", "disable"), + MaxOpenConns: getEnvAsInt("POSTGRES_MAX_OPEN_CONNS", 25), + MaxIdleConns: getEnvAsInt("POSTGRES_MAX_IDLE_CONNS", 25), + ConnMaxLifetime: parseDuration(getEnv("POSTGRES_CONN_MAX_LIFETIME", "5m")), + } + } + } + } + } +} + +// addMYSQLConfigs adds MYSQL database +func (c *Config) addMySQLConfigs() { + // Primary MySQL configuration + defaultMySQLHost := getEnv("MYSQL_HOST", "") + if defaultMySQLHost != "" { + c.Databases["mysql"] = DatabaseConfig{ + Name: "mysql", + Type: getEnv("MYSQL_CONNECTION", "mysql"), + Host: defaultMySQLHost, + Port: getEnvAsInt("MYSQL_PORT", 3306), + Username: getEnv("MYSQL_USERNAME", ""), + Password: getEnv("MYSQL_PASSWORD", ""), + Database: getEnv("MYSQL_DATABASE", "mysql"), + SSLMode: getEnv("MYSQL_SSLMODE", "disable"), + MaxOpenConns: getEnvAsInt("MYSQL_MAX_OPEN_CONNS", 25), + MaxIdleConns: getEnvAsInt("MYSQL_MAX_IDLE_CONNS", 25), + ConnMaxLifetime: parseDuration(getEnv("MYSQL_CONN_MAX_LIFETIME", "5m")), + } + } + + // Support for custom MySQL configurations with MYSQL_ prefix + envVars := os.Environ() + for _, envVar := range envVars { + parts := strings.SplitN(envVar, "=", 2) + if len(parts) != 2 { + continue + } + + key := parts[0] + // Parse MySQL configurations (format: MYSQL_[NAME]_[PROPERTY]) + if strings.HasPrefix(key, "MYSQL_") && strings.Contains(key, "_") { + segments := strings.Split(key, "_") + if len(segments) >= 3 { + dbName := strings.ToLower(strings.Join(segments[1:len(segments)-1], "_")) + + // Skip if it's a standard MySQL configuration + if dbName == "connection" || dbName == "dev" || dbName == "max" || dbName == "conn" { + continue + } + + // Create or update MySQL configuration + if _, exists := c.Databases[dbName]; !exists { + mysqlHost := getEnv("MYSQL_"+strings.ToUpper(dbName)+"_HOST", "") + if mysqlHost != "" { + c.Databases[dbName] = DatabaseConfig{ + Name: dbName, + Type: getEnv("MYSQL_"+strings.ToUpper(dbName)+"_CONNECTION", "mysql"), + Host: mysqlHost, + Port: getEnvAsInt("MYSQL_"+strings.ToUpper(dbName)+"_PORT", 3306), + Username: getEnv("MYSQL_"+strings.ToUpper(dbName)+"_USERNAME", ""), + Password: getEnv("MYSQL_"+strings.ToUpper(dbName)+"_PASSWORD", ""), + Database: getEnv("MYSQL_"+strings.ToUpper(dbName)+"_DATABASE", dbName), + SSLMode: getEnv("MYSQL_"+strings.ToUpper(dbName)+"_SSLMODE", "disable"), + MaxOpenConns: getEnvAsInt("MYSQL_MAX_OPEN_CONNS", 25), + MaxIdleConns: getEnvAsInt("MYSQL_MAX_IDLE_CONNS", 25), + ConnMaxLifetime: parseDuration(getEnv("MYSQL_CONN_MAX_LIFETIME", "5m")), + } + } + } + } + } + } +} + + +// addMongoDBConfigs adds MongoDB database configurations from environment variables +func (c *Config) addMongoDBConfigs() { + // Primary MongoDB configuration + mongoHost := getEnv("MONGODB_HOST", "") + if mongoHost != "" { + c.Databases["mongodb"] = DatabaseConfig{ + Name: "mongodb", + Type: getEnv("MONGODB_CONNECTION", "mongodb"), + Host: mongoHost, + Port: getEnvAsInt("MONGODB_PORT", 27017), + Username: getEnv("MONGODB_USER", ""), + Password: getEnv("MONGODB_PASS", ""), + Database: getEnv("MONGODB_MASTER", "master"), + SSLMode: getEnv("MONGODB_SSLMODE", "disable"), + MaxOpenConns: getEnvAsInt("MONGODB_MAX_OPEN_CONNS", 100), + MaxIdleConns: getEnvAsInt("MONGODB_MAX_IDLE_CONNS", 10), + ConnMaxLifetime: parseDuration(getEnv("MONGODB_CONN_MAX_LIFETIME", "30m")), + } + } + + // Additional MongoDB configurations for local database + mongoLocalHost := getEnv("MONGODB_LOCAL_HOST", "") + if mongoLocalHost != "" { + c.Databases["mongodb_local"] = DatabaseConfig{ + Name: "mongodb_local", + Type: getEnv("MONGODB_CONNECTION", "mongodb"), + Host: mongoLocalHost, + Port: getEnvAsInt("MONGODB_LOCAL_PORT", 27017), + Username: getEnv("MONGODB_LOCAL_USER", ""), + Password: getEnv("MONGODB_LOCAL_PASS", ""), + Database: getEnv("MONGODB_LOCAL_DB", "local"), + SSLMode: getEnv("MONGOD_SSLMODE", "disable"), + MaxOpenConns: getEnvAsInt("MONGODB_MAX_OPEN_CONNS", 100), + MaxIdleConns: getEnvAsInt("MONGODB_MAX_IDLE_CONNS", 10), + ConnMaxLifetime: parseDuration(getEnv("MONGODB_CONN_MAX_LIFETIME", "30m")), + } + } + + // Support for custom MongoDB configurations with MONGODB_ prefix + envVars := os.Environ() + for _, envVar := range envVars { + parts := strings.SplitN(envVar, "=", 2) + if len(parts) != 2 { + continue + } + + key := parts[0] + // Parse MongoDB configurations (format: MONGODB_[NAME]_[PROPERTY]) + if strings.HasPrefix(key, "MONGODB_") && strings.Contains(key, "_") { + segments := strings.Split(key, "_") + if len(segments) >= 3 { + dbName := strings.ToLower(strings.Join(segments[1:len(segments)-1], "_")) + // Skip if it's a standard MongoDB configuration + if dbName == "connection" || dbName == "dev" || dbName == "local" { + continue + } + + // Create or update MongoDB configuration + if _, exists := c.Databases[dbName]; !exists { + c.Databases[dbName] = DatabaseConfig{ + Name: dbName, + Type: "mongodb", + Host: getEnv("MONGODB_"+strings.ToUpper(dbName)+"_HOST", "localhost"), + Port: getEnvAsInt("MONGODB_"+strings.ToUpper(dbName)+"_PORT", 27017), + Username: getEnv("MONGODB_"+strings.ToUpper(dbName)+"_USER", ""), + Password: getEnv("MONGODB_"+strings.ToUpper(dbName)+"_PASS", ""), + Database: getEnv("MONGODB_"+strings.ToUpper(dbName)+"_DB", dbName), + SSLMode: getEnv("MONGOD_SSLMODE", "disable"), + MaxOpenConns: getEnvAsInt("MONGODB_MAX_OPEN_CONNS", 100), + MaxIdleConns: getEnvAsInt("MONGODB_MAX_IDLE_CONNS", 10), + ConnMaxLifetime: parseDuration(getEnv("MONGODB_CONN_MAX_LIFETIME", "30m")), + } + } + } + } + } +} func getEnvFromMap(config map[string]string, key, defaultValue string) string { if value, exists := config[key]; exists { diff --git a/internal/database/database.go b/internal/database/database.go index dfec3a3..ab056e0 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -118,13 +118,13 @@ func (s *service) addDatabase(name string, config config.DatabaseConfig) error { defer s.mu.Unlock() log.Printf("=== Database Connection Debug ===") - log.Printf("Database: %s", name) - log.Printf("Type: %s", config.Type) - log.Printf("Host: %s", config.Host) - log.Printf("Port: %d", config.Port) - log.Printf("Database: %s", config.Database) - log.Printf("Username: %s", config.Username) - log.Printf("SSLMode: %s", config.SSLMode) + // log.Printf("Database: %s", name) + // log.Printf("Type: %s", config.Type) + // log.Printf("Host: %s", config.Host) + // log.Printf("Port: %d", config.Port) + // log.Printf("Database: %s", config.Database) + // log.Printf("Username: %s", config.Username) + // log.Printf("SSLMode: %s", config.SSLMode) var db *sql.DB var err error diff --git a/internal/handlers/retribusi/retribusi.go b/internal/handlers/retribusi/retribusi.go index 2aeb858..e7db5ee 100644 --- a/internal/handlers/retribusi/retribusi.go +++ b/internal/handlers/retribusi/retribusi.go @@ -87,7 +87,7 @@ func (h *RetribusiHandler) GetRetribusi(c *gin.Context) { includeAggregation := c.Query("include_summary") == "true" // Get database connection - dbConn, err := h.db.GetDB("satudata") + dbConn, err := h.db.GetDB("postgres_satudata") if err != nil { h.logAndRespondError(c, "Database connection failed", err, http.StatusInternalServerError) return @@ -196,7 +196,7 @@ func (h *RetribusiHandler) GetRetribusiByID(c *gin.Context) { return } - dbConn, err := h.db.GetDB("satudata") + dbConn, err := h.db.GetDB("postgres_satudata") if err != nil { h.logAndRespondError(c, "Database connection failed", err, http.StatusInternalServerError) return @@ -248,7 +248,7 @@ func (h *RetribusiHandler) CreateRetribusi(c *gin.Context) { return } - dbConn, err := h.db.GetDB("satudata") + dbConn, err := h.db.GetDB("postgres_satudata") if err != nil { h.logAndRespondError(c, "Database connection failed", err, http.StatusInternalServerError) return @@ -308,7 +308,7 @@ func (h *RetribusiHandler) UpdateRetribusi(c *gin.Context) { return } - dbConn, err := h.db.GetDB("satudata") + dbConn, err := h.db.GetDB("postgres_satudata") if err != nil { h.logAndRespondError(c, "Database connection failed", err, http.StatusInternalServerError) return @@ -356,7 +356,7 @@ func (h *RetribusiHandler) DeleteRetribusi(c *gin.Context) { return } - dbConn, err := h.db.GetDB("satudata") + dbConn, err := h.db.GetDB("postgres_satudata") if err != nil { h.logAndRespondError(c, "Database connection failed", err, http.StatusInternalServerError) return @@ -394,7 +394,7 @@ func (h *RetribusiHandler) DeleteRetribusi(c *gin.Context) { // @Failure 500 {object} models.ErrorResponse "Internal server error" // @Router /api/v1/retribusis/stats [get] func (h *RetribusiHandler) GetRetribusiStats(c *gin.Context) { - dbConn, err := h.db.GetDB("satudata") + dbConn, err := h.db.GetDB("postgres_satudata") if err != nil { h.logAndRespondError(c, "Database connection failed", err, http.StatusInternalServerError) return