34748-vm/db/config.php
Flatlogic Bot a6d0ca0eea agenda
2025-10-08 00:23:05 +00:00

100 lines
3.3 KiB
PHP

<?php
// db/config.php
// --- Database Credentials ---
// We are using environment variables for configuration.
$db_host = getenv('DB_HOST') ?: '127.0.0.1';
$db_port = getenv('DB_PORT') ?: '3306';
$db_name = getenv('DB_DATABASE') ?: 'app';
$db_user = getenv('DB_USERNAME') ?: 'app';
$db_pass = getenv('DB_PASSWORD') ?: 'app';
/**
* Establishes a PDO database connection.
*
* @return PDO|null A PDO connection object on success, or null on failure.
*/
function db() {
global $db_host, $db_port, $db_name, $db_user, $db_pass;
static $pdo = null;
if ($pdo !== null) {
return $pdo;
}
$dsn = "mysql:host={$db_host};port={$db_port};dbname={$db_name};charset=utf8mb4";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false,
];
try {
$pdo = new PDO($dsn, $db_user, $db_pass, $options);
return $pdo;
} catch (PDOException $e) {
// In a real application, you would log this error and show a generic error page.
// For this development environment, we'll just show the error.
error_log('Database Connection Error: ' . $e->getMessage());
// Returning null or you could throw an exception.
return null;
}
}
/**
* Runs database migrations.
* It finds all .php files in the migrations directory and runs them in order.
* Each migration file should contain a function with the same name as the file (without .php).
*/
function run_migrations() {
$pdo = db();
if (!$pdo) {
// Cannot run migrations without a database connection.
return;
}
$migration_dir = __DIR__ . '/migrations';
if (!is_dir($migration_dir)) {
return; // No migrations directory.
}
$files = glob($migration_dir . '/*.php');
sort($files);
// Check if migrations table exists, create if not
$pdo->exec("CREATE TABLE IF NOT EXISTS migrations (migration VARCHAR(255) PRIMARY KEY)");
// Get all executed migrations
$executed_migrations = $pdo->query("SELECT migration FROM migrations")->fetchAll(PDO::FETCH_COLUMN);
foreach ($files as $file) {
$migration_name = basename($file, '.php');
if (in_array($migration_name, $executed_migrations)) {
continue; // Skip already executed migration
}
require_once $file;
// The function name inside the migration file must match the filename.
// e.g., 001_create_agenda_table.php must contain a function named 'migration_001_create_agenda_table'
$migration_function_name = 'migration_' . str_replace(['-'], '_', $migration_name);
if (function_exists($migration_function_name)) {
try {
$pdo->beginTransaction();
$migration_function_name($pdo);
// Record the migration
$stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)");
$stmt->execute([$migration_name]);
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
error_log("Migration failed: {$migration_name}. Error: " . $e->getMessage());
// Stop on first failed migration
return;
}
}
}
}