Database.php 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. <?php
  2. namespace App\Core\DB;
  3. use App\Core\Application;
  4. use PDO;
  5. /*
  6. * Gestiona las migraciones de la aplicación.
  7. */
  8. class Database
  9. {
  10. public PDO $pdo;
  11. public function __construct(array $config)
  12. {
  13. $dsn = $config['dsn'] ?? '';
  14. $username = $config['username'] ?? '';
  15. $password = $config['password'] ?? '';
  16. $this->pdo = new PDO($dsn, $username, $password);
  17. $this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  18. }
  19. /*
  20. * Ejecuta todas las migraciones.
  21. */
  22. public function applyMigrations()
  23. {
  24. $this->createMigrationsTable();
  25. $appliedMigrations = $this->getAppliedMigrations();
  26. $files = scandir(Application::$ROOT_DIR.'/migrations');
  27. $toApplyMigrations = array_diff($files, $appliedMigrations);
  28. $newMigrations = [];
  29. foreach ($toApplyMigrations as $migration) {
  30. if ($migration === '.' || $migration === '..') {
  31. continue;
  32. }
  33. require_once Application::$ROOT_DIR.'/migrations/'.$migration;
  34. $className = pathinfo($migration, PATHINFO_FILENAME);
  35. $instance = new $className();
  36. $this->log("Running migration {$migration}");
  37. $instance->up();
  38. $this->log("Applied migration {$migration}");
  39. $newMigrations[] = $migration;
  40. }
  41. if (! empty($newMigrations)) {
  42. $this->saveMigrations($newMigrations);
  43. } else {
  44. $this->log('All migrations are applied');
  45. }
  46. }
  47. /*
  48. * Crea la tabla de seguimiento de migraciones.
  49. */
  50. public function createMigrationsTable()
  51. {
  52. $this->pdo->exec('
  53. CREATE TABLE IF NOT EXISTS migrations (
  54. id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
  55. migration VARCHAR(255) NOT NULL,
  56. created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
  57. CONSTRAINT migrations_id_primary PRIMARY KEY(id)
  58. );
  59. ');
  60. }
  61. /*
  62. * Obtiene todas las migraciones ejecutadas.
  63. */
  64. public function getAppliedMigrations()
  65. {
  66. $statement = $this->prepare('SELECT migration FROM migrations');
  67. $statement->execute();
  68. return $statement->fetchAll(PDO::FETCH_COLUMN);
  69. }
  70. /*
  71. * Guarda la información de las migraciones ejecutadas.
  72. */
  73. public function saveMigrations(array $migrations)
  74. {
  75. $values = array_map(fn ($migration) => "('{$migration}')", $migrations);
  76. $statement = $this->prepare('INSERT INTO migrations(migration) VALUES'.implode(',', $values));
  77. $statement->execute();
  78. }
  79. /*
  80. * Imprime los registros (logs) de las migraciones.
  81. */
  82. public function log(string $message)
  83. {
  84. $datetime = date('Y-m-d H:i:s');
  85. echo "[{$datetime}] - {$message}".PHP_EOL;
  86. }
  87. /*
  88. * Prepara una sentencia SQL.
  89. */
  90. public function prepare(string $query)
  91. {
  92. return $this->pdo->prepare($query);
  93. }
  94. }