package database import ( "fmt" "log" "attune-heart-therapy/internal/config" "attune-heart-therapy/internal/models" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/logger" ) // DB holds the database connection type DB struct { *gorm.DB } // New creates a new database connection func New(cfg *config.Config) (*DB, error) { dsn := fmt.Sprintf( "host=%s user=%s password=%s dbname=%s port=%s sslmode=%s TimeZone=UTC", cfg.Database.Host, cfg.Database.User, cfg.Database.Password, cfg.Database.Name, cfg.Database.Port, cfg.Database.SSLMode, ) // Configure GORM logger gormConfig := &gorm.Config{ Logger: logger.Default.LogMode(logger.Info), } db, err := gorm.Open(postgres.Open(dsn), gormConfig) if err != nil { return nil, fmt.Errorf("failed to connect to database: %w", err) } // Configure connection pool sqlDB, err := db.DB() if err != nil { return nil, fmt.Errorf("failed to get underlying sql.DB: %w", err) } // Set connection pool settings sqlDB.SetMaxIdleConns(10) sqlDB.SetMaxOpenConns(100) log.Println("Successfully connected to PostgreSQL database") return &DB{db}, nil } // Close closes the database connection func (db *DB) Close() error { sqlDB, err := db.DB.DB() if err != nil { return err } return sqlDB.Close() } // Migrate runs database migrations func (db *DB) Migrate() error { log.Println("Running database migrations...") // Auto-migrate all models err := db.AutoMigrate( &models.User{}, &models.Schedule{}, &models.Booking{}, &models.Notification{}, ) if err != nil { return fmt.Errorf("failed to run migrations: %w", err) } log.Println("Database migrations completed successfully") return nil } // Seed creates initial data for the database func (db *DB) Seed() error { log.Println("Seeding database with initial data...") // Check if we already have data to avoid duplicate seeding var userCount int64 db.Model(&models.User{}).Count(&userCount) if userCount > 0 { log.Println("Database already contains data, skipping seeding") return nil } // Add any initial data here if needed // For now, we'll just log that seeding is complete log.Println("Database seeding completed") return nil } // Health checks database connectivity func (db *DB) Health() error { sqlDB, err := db.DB.DB() if err != nil { return err } return sqlDB.Ping() }