backend-service/internal/database/database.go
ats-tech25 488be7b8ef feat(project): Initialize project structure and core components
- Add initial project scaffolding with Go module and project structure
- Create server and CLI entry points for application
- Implement Makefile with development and build commands
- Add `.env.example` with comprehensive configuration template
- Set up README.md with project documentation and setup instructions
- Configure basic dependencies for server, database, and CLI tools
- Establish internal package structure for models, services, and handlers
- Add initial configuration and environment management
- Prepare for HTTP server, CLI, and database integration
2025-11-05 15:06:07 +00:00

113 lines
2.3 KiB
Go

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()
}