2025-03-20 11:06:41 +00:00
package database
2025-01-31 13:43:55 +00:00
import (
"context"
"database/sql"
2025-03-20 11:06:41 +00:00
"embed"
2025-01-31 13:43:55 +00:00
"fmt"
"log/slog"
2025-03-05 12:05:46 +00:00
2025-01-31 13:43:55 +00:00
"queryorchestration/internal/serviceconfig"
2025-02-03 17:30:50 +00:00
"queryorchestration/internal/serviceconfig/database"
2025-01-31 13:43:55 +00:00
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/postgres"
_ "github.com/golang-migrate/migrate/v4/source/file"
2025-03-20 11:06:41 +00:00
"github.com/golang-migrate/migrate/v4/source/iofs"
2025-01-31 13:43:55 +00:00
_ "github.com/lib/pq"
)
2025-02-03 17:30:50 +00:00
func createDB ( cfg database . ConfigProvider ) error {
2025-01-31 13:43:55 +00:00
connStr := fmt . Sprintf ( "%s?%s" , cfg . GetDBBaseURI ( ) , cfg . GetDBOptsString ( ) )
db , err := sql . Open ( cfg . GetDBDriver ( ) , connStr )
if err != nil {
return fmt . Errorf ( "error opening database: %v" , err )
}
err = db . Ping ( )
if err != nil {
return fmt . Errorf ( "error pinging database: %v" , err )
}
rs , err := db . Query ( fmt . Sprintf ( "SELECT 'CREATE DATABASE %s' WHERE NOT EXISTS (SELECT FROM pg_database WHERE datname = '%s')" , cfg . GetDBName ( ) , cfg . GetDBName ( ) ) )
if err != nil {
return fmt . Errorf ( "error creating database: %v" , err )
}
2025-02-03 17:30:50 +00:00
if rs . Next ( ) {
2025-01-31 13:43:55 +00:00
slog . Info ( "database created" , "name" , cfg . GetDBName ( ) )
} else {
slog . Info ( "database already exists" , "name" , cfg . GetDBName ( ) )
}
return nil
}
2025-03-20 11:06:41 +00:00
//go:embed migrations/*.up.sql
var migrations embed . FS
func RunMigrations ( ctx context . Context , cfg serviceconfig . ConfigProvider ) error {
2025-01-31 13:43:55 +00:00
err := createDB ( cfg )
if err != nil {
return err
}
2025-03-20 11:06:41 +00:00
source , err := iofs . New ( migrations , "migrations" )
if err != nil {
return err
}
m , err := migrate . NewWithSourceInstance ( "iofs" , source , cfg . GetDBURI ( ) )
2025-01-31 13:43:55 +00:00
if err != nil {
return fmt . Errorf ( "failed to create migrate instance: %v" , err )
}
err = m . Up ( )
if err == migrate . ErrNoChange {
slog . Info ( "No migration changes required" )
} else if err != nil {
return fmt . Errorf ( "failed to apply migrations: %v" , err )
} else {
slog . Info ( "Migrations applied successfully!" )
}
return nil
}