137 lines
3.7 KiB
PHP
137 lines
3.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
if (PHP_SAPI !== 'cli') {
|
|
fwrite(STDERR, "This script must be run from the command line.\n");
|
|
exit(1);
|
|
}
|
|
|
|
$dumpPath = $argv[1] ?? null;
|
|
|
|
if ($dumpPath === null || ! is_file($dumpPath) || ! is_readable($dumpPath)) {
|
|
fwrite(STDERR, "Usage: php tests/_support/import_baseline.php path/to/dump.sql\n");
|
|
exit(1);
|
|
}
|
|
|
|
$requiredEnv = [
|
|
'TEST_DB_HOST',
|
|
'TEST_DB_USER',
|
|
'TEST_DB_PASSWORD',
|
|
'TEST_DB_NAME',
|
|
'TEST_DB_PORT',
|
|
];
|
|
|
|
foreach ($requiredEnv as $name) {
|
|
if (getenv($name) === false || getenv($name) === '') {
|
|
fwrite(STDERR, "Missing required environment variable: {$name}\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
$testDatabase = (string) getenv('TEST_DB_NAME');
|
|
|
|
if (! preg_match('/(^test_|_test$|^tests$|^alrahma_test$)/i', $testDatabase)) {
|
|
fwrite(
|
|
STDERR,
|
|
"Refusing to import baseline into {$testDatabase}: TEST_DB_NAME must clearly identify a test database.\n"
|
|
);
|
|
exit(1);
|
|
}
|
|
|
|
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
|
|
|
|
$db = new mysqli(
|
|
getenv('TEST_DB_HOST'),
|
|
getenv('TEST_DB_USER'),
|
|
getenv('TEST_DB_PASSWORD'),
|
|
getenv('TEST_DB_NAME'),
|
|
(int) getenv('TEST_DB_PORT')
|
|
);
|
|
|
|
$db->set_charset('utf8mb4');
|
|
$db->query('SET FOREIGN_KEY_CHECKS=0');
|
|
|
|
$tables = $db->query('SHOW FULL TABLES WHERE Table_type = "BASE TABLE"')->fetch_all(MYSQLI_NUM);
|
|
|
|
foreach ($tables as [$table]) {
|
|
$db->query('DROP TABLE IF EXISTS `' . str_replace('`', '``', $table) . '`');
|
|
}
|
|
|
|
$db->query('SET FOREIGN_KEY_CHECKS=1');
|
|
|
|
$sql = file_get_contents($dumpPath);
|
|
|
|
if ($sql === false) {
|
|
fwrite(STDERR, "Unable to read baseline dump: {$dumpPath}\n");
|
|
exit(1);
|
|
}
|
|
|
|
$db->multi_query($sql);
|
|
|
|
do {
|
|
if ($result = $db->store_result()) {
|
|
$result->free();
|
|
}
|
|
} while ($db->more_results() && $db->next_result());
|
|
|
|
$baselineVersion = '2025-12-07-235959';
|
|
$migrationFiles = glob(dirname(__DIR__, 2) . '/app/Database/Migrations/*.php') ?: [];
|
|
$maxId = (int) ($db->query('SELECT COALESCE(MAX(id), 0) AS id FROM migrations')->fetch_assoc()['id'] ?? 0);
|
|
$maxBatch = (int) ($db->query('SELECT COALESCE(MAX(batch), 0) AS batch FROM migrations')->fetch_assoc()['batch'] ?? 0);
|
|
|
|
foreach ($migrationFiles as $file) {
|
|
$filename = basename($file, '.php');
|
|
|
|
if (! preg_match('/^(\d{4}-\d{2}-\d{2}-\d{6})_(.+)$/', $filename, $matches)) {
|
|
continue;
|
|
}
|
|
|
|
[$all, $version] = $matches;
|
|
|
|
if ($version > $baselineVersion) {
|
|
continue;
|
|
}
|
|
|
|
$contents = file_get_contents($file);
|
|
|
|
if ($contents === false || ! preg_match('/class\s+([A-Za-z_][A-Za-z0-9_]*)\s+extends\s+Migration/', $contents, $classMatch)) {
|
|
continue;
|
|
}
|
|
|
|
$class = 'App\\Database\\Migrations\\' . $classMatch[1];
|
|
$exists = $db
|
|
->query(
|
|
'SELECT 1 FROM migrations WHERE version = "' . $db->real_escape_string($version) . '"'
|
|
. ' AND class = "' . $db->real_escape_string($class) . '" LIMIT 1'
|
|
)
|
|
->num_rows > 0;
|
|
|
|
if ($exists) {
|
|
continue;
|
|
}
|
|
|
|
$date = DateTimeImmutable::createFromFormat('Y-m-d-His', $version);
|
|
$time = $date instanceof DateTimeImmutable ? $date->getTimestamp() : time();
|
|
|
|
$statement = $db->prepare(
|
|
'INSERT INTO migrations (id, version, class, `group`, namespace, time, batch) VALUES (?, ?, ?, ?, ?, ?, ?)'
|
|
);
|
|
|
|
$id = ++$maxId;
|
|
$group = 'default';
|
|
$namespace = 'App';
|
|
$batch = $maxBatch;
|
|
$statement->bind_param('issssii', $id, $version, $class, $group, $namespace, $time, $batch);
|
|
$statement->execute();
|
|
}
|
|
|
|
$count = $db->query('SHOW TABLES')->num_rows;
|
|
|
|
if ($count === 0) {
|
|
fwrite(STDERR, "Baseline import produced no tables\n");
|
|
exit(1);
|
|
}
|
|
|
|
echo "Baseline schema imported: {$count} table(s)\n";
|