package config import ( "fmt" "log" "lost-and-found/internal/models" "os" "time" "gorm.io/driver/mysql" "gorm.io/gorm" "gorm.io/gorm/logger" ) var db *gorm.DB // DatabaseConfig holds database connection configuration type DatabaseConfig struct { Host string Port string User string Password string DBName string Charset string ParseTime string Loc string } // GetDatabaseConfig returns database configuration from environment func GetDatabaseConfig() DatabaseConfig { return DatabaseConfig{ Host: getEnv("DB_HOST", "localhost"), Port: getEnv("DB_PORT", "3306"), User: getEnv("DB_USER", "root"), Password: getEnv("DB_PASSWORD", ""), DBName: getEnv("DB_NAME", "lost_and_found"), Charset: getEnv("DB_CHARSET", "utf8mb4"), ParseTime: getEnv("DB_PARSE_TIME", "True"), Loc: getEnv("DB_LOC", "Local"), } } // InitDB initializes database connection func InitDB() error { config := GetDatabaseConfig() // Build DSN (Data Source Name) for MySQL dsn := fmt.Sprintf( "%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=%s&loc=%s", config.User, config.Password, config.Host, config.Port, config.DBName, config.Charset, config.ParseTime, config.Loc, ) // Configure GORM logger gormLogger := logger.Default if IsDevelopment() { gormLogger = logger.Default.LogMode(logger.Info) } else { gormLogger = logger.Default.LogMode(logger.Error) } // Open database connection var err error db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{ Logger: gormLogger, NowFunc: func() time.Time { return time.Now().Local() }, }) if err != nil { return fmt.Errorf("failed to connect to database: %w", err) } // Get underlying SQL database sqlDB, err := db.DB() if err != nil { return fmt.Errorf("failed to get database instance: %w", err) } // Set connection pool settings sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) sqlDB.SetConnMaxLifetime(time.Hour) // Test connection if err := sqlDB.Ping(); err != nil { return fmt.Errorf("failed to ping database: %w", err) } log.Println("✅ Database connected successfully") return nil } // GetDB returns the database instance func GetDB() *gorm.DB { return db } // RunMigrations runs database migrations func RunMigrations(db *gorm.DB) error { log.Println("⚠️ Auto-migration is disabled. Please run schema.sql manually via HeidiSQL") log.Println("📋 Steps:") log.Println(" 1. Open HeidiSQL") log.Println(" 2. Connect to your MySQL database") log.Println(" 3. Create database 'lost_and_found' if not exists") log.Println(" 4. Run database/schema.sql") log.Println(" 5. Run database/seed.sql (optional)") // Check if tables exist if !db.Migrator().HasTable(&models.Role{}) { return fmt.Errorf("❌ Tables not found. Please run database/schema.sql first") } log.Println("✅ Database tables detected") return nil } // CloseDB closes database connection func CloseDB() error { if db != nil { sqlDB, err := db.DB() if err != nil { return err } return sqlDB.Close() } return nil } // Helper function to get environment variable with default value func getEnv(key, defaultValue string) string { value := os.Getenv(key) if value == "" { return defaultValue } return value }