Files
2025-08-02 16:30:27 +02:00

158 lines
4.5 KiB
PHP

<?php
namespace KupShop\DevelopmentBundle\Util\Tests;
use KupShop\KupShopBundle\Util\Compat\ServiceContainer;
use Upgrade;
class DatabaseUtils
{
private $databaseChecksum;
private $testDatabase = [
'engine' => 'phpunit_test',
'engine_units_float' => 'phpunit_test_units_float',
'shop' => 'phpunit_test_shop',
];
public function prepare()
{
$databaseName = $this->getDbName();
// Pass current database name to upgrade check_DBExists
define('TEST_DB_NAME', $databaseName);
// Load stored checksum
if (empty($this->databaseChecksum) && is_file('/tmp/kupshop_test_checksum')) {
$this->databaseChecksum = file_get_contents('/tmp/kupshop_test_checksum');
}
try {
$this->debugDatabaseChecksum();
$this->createSchema();
$this->debugDatabaseChecksum();
} catch (\Exception $e) {
echo "Error during database upgrade: {$e->getMessage()}\n{$e->getTraceAsString()}\n";
}
if (TEST_SUITE == 'engine') {
$this->checkDatabaseChecksum();
} else {
$this->databaseChecksum = $this->makeDatabaseChecksum();
}
// Clear memcached
getMemcached()->flush();
}
public function createSchema()
{
global $cfg;
/* @var \Doctrine\DBAL\Driver\PDOStatement $res */
$cfg['Connection']['database'] = $this->getDbName();
$coverage = false;
if (extension_loaded('xdebug')) {
if ($coverage = xdebug_code_coverage_started()) {
xdebug_stop_code_coverage(false);
}
}
// Run migrations
$upgrade = new \Upgrade(
\Upgrade::VERBOSE_NO,
TEST_SUITE === 'shop' ? \Upgrade::LOCAL_UPGRADES_YES : \Upgrade::LOCAL_UPGRADES_NO
);
$upgrade->run();
$upgrade->run();
if ($coverage) {
xdebug_start_code_coverage();
}
ServiceContainer::destroy();
}
private function debugDatabaseChecksum()
{
return;
try {
echo "Database tables checksum:\n";
$checksums = sqlFetchAll(sqlQuery(
sprintf(
'CHECKSUM TABLE %s',
join(',', sqlGetConnection()->getSchemaManager()->listTableNames())
)
));
array_map(function ($row) {
echo "{$row['Table']}: {$row['Checksum']}\n";
}, $checksums);
echo "\n{$this->makeDatabaseChecksum()}\n";
} catch (Exception $e) {
echo "exception\n";
}
}
private function makeDatabaseChecksum()
{
$tables = sqlGetConnection()->getSchemaManager()->listTableNames();
if (!count($tables)) {
return 'empty';
}
return sha1(implode(array_column(sqlFetchAll(sqlQuery(
sprintf(
'CHECKSUM TABLE %s',
join(',', $tables)
)
)), 'Checksum')));
}
private function checkDatabaseChecksum()
{
$checksum = $this->makeDatabaseChecksum();
if ($checksum != $this->databaseChecksum) {
echo "Database checksum does not match!\n
correct:".$this->databaseChecksum." current:{$checksum}\n";
$this->debugDatabaseChecksum();
echo "Deleting database {$this->getDbName()}...\n";
sqlQuery('DROP DATABASE IF EXISTS '.$this->getDbName());
sqlQuery('CREATE DATABASE '.$this->getDbName());
sqlQuery('USE '.$this->getDbName());
echo "Running upgrade ...\n";
$this->createSchema();
$this->databaseChecksum = $this->makeDatabaseChecksum();
$this->debugDatabaseChecksum();
echo 'Database checksum does not match!
Correct checksum: '.$this->databaseChecksum."\n\n";
echo "Storing checksum {$this->databaseChecksum} to /tmp/kupshop_test_checksum";
$f = fopen('/tmp/kupshop_test_checksum', 'w');
fwrite($f, $this->databaseChecksum);
fclose($f);
}
}
public function getDatabaseChecksum(): string
{
return $this->databaseChecksum;
}
public function getDbName()
{
return $this->testDatabase[TEST_SUITE].getenv('TEST_TOKEN');
}
public function checkDatabaseNotChanged()
{
return $this->databaseChecksum === $this->makeDatabaseChecksum();
}
}