145 lines
3.2 KiB
Go
145 lines
3.2 KiB
Go
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
|
|
} |