Initial commit: OMSORG website + Mitarbeiter-App
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
function db(): PDO {
|
||||
static $pdo = null;
|
||||
if ($pdo === null) {
|
||||
$c = require __DIR__ . '/config.php';
|
||||
$pdo = new PDO(
|
||||
$c['db_dsn'],
|
||||
$c['db_user'],
|
||||
$c['db_password'],
|
||||
[
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
]
|
||||
);
|
||||
if ($c['db_driver'] === 'sqlite') {
|
||||
$pdo->exec('PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;');
|
||||
}
|
||||
_run_migrations($pdo);
|
||||
}
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
function _table_exists(PDO $pdo, string $table, string $driver): bool {
|
||||
if ($driver === 'sqlite') {
|
||||
return (bool) $pdo->query(
|
||||
"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name=" . $pdo->quote($table)
|
||||
)->fetchColumn();
|
||||
}
|
||||
return (bool) $pdo->query(
|
||||
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema=DATABASE() AND table_name=" . $pdo->quote($table)
|
||||
)->fetchColumn();
|
||||
}
|
||||
|
||||
function _run_migrations(PDO $pdo): void {
|
||||
$c = require __DIR__ . '/config.php';
|
||||
$driver = $c['db_driver'];
|
||||
|
||||
$migrationTableExisted = _table_exists($pdo, 'schema_migrations', $driver);
|
||||
|
||||
$pdo->exec("
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version VARCHAR(255) NOT NULL PRIMARY KEY,
|
||||
applied_at VARCHAR(32) NOT NULL
|
||||
)
|
||||
");
|
||||
|
||||
$files = glob(__DIR__ . '/../migrations/*.php');
|
||||
if (!$files) return;
|
||||
sort($files);
|
||||
|
||||
// Existing DB without migration table: stamp all known migrations as applied.
|
||||
if (!$migrationTableExisted && _table_exists($pdo, 'users', $driver)) {
|
||||
$insertIgnore = $driver === 'sqlite' ? 'INSERT OR IGNORE' : 'INSERT IGNORE';
|
||||
$stmt = $pdo->prepare(
|
||||
"$insertIgnore INTO schema_migrations (version, applied_at) VALUES (?, ?)"
|
||||
);
|
||||
foreach ($files as $file) {
|
||||
$stmt->execute([basename($file, '.php'), date('c')]);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
$applied = $pdo->query('SELECT version FROM schema_migrations')
|
||||
->fetchAll(PDO::FETCH_COLUMN);
|
||||
$applied = array_flip($applied);
|
||||
|
||||
$useTransactions = ($driver === 'sqlite');
|
||||
|
||||
foreach ($files as $file) {
|
||||
$version = basename($file, '.php');
|
||||
if (isset($applied[$version])) continue;
|
||||
|
||||
$migration = require $file;
|
||||
if ($useTransactions) $pdo->beginTransaction();
|
||||
try {
|
||||
foreach ((array) $migration['up'] as $sql) {
|
||||
$pdo->exec($sql);
|
||||
}
|
||||
$pdo->prepare(
|
||||
'INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)'
|
||||
)->execute([$version, date('c')]);
|
||||
if ($useTransactions) $pdo->commit();
|
||||
} catch (Throwable $e) {
|
||||
if ($useTransactions && $pdo->inTransaction()) $pdo->rollBack();
|
||||
throw new RuntimeException(
|
||||
"Migration {$version} failed: " . $e->getMessage(), 0, $e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user