Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/contracts/Test/Persistence/Fixture/FixtureImporter.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,24 @@ static function ($tableData): bool {
}
}

/**
* Doctrine's own nesting counter is not enough here: dama/doctrine-test-bundle opens the
* transaction wrapping each test on the driver connection, underneath DBAL, so
* Connection::isTransactionActive() reports false while the session is very much inside one.
*
* @throws \Doctrine\DBAL\Exception
*/
private function isInTransaction(): bool
{
if ($this->connection->isTransactionActive()) {
return true;
}

$nativeConnection = $this->connection->getNativeConnection();

return $nativeConnection instanceof \PDO && $nativeConnection->inTransaction();
}

/**
* @param string[] $tables a list of table names
*
Expand All @@ -67,7 +85,20 @@ private function truncateTables(array $tables): void
{
$dbPlatform = $this->connection->getDatabasePlatform();

// TRUNCATE is DDL, and inside a transaction both supported platforms punish it: MySQL and
// MariaDB commit implicitly, ending the transaction the test suite wraps each test in and
// discarding its savepoints, while PostgreSQL refuses it outright for any table a foreign
// key references and aborts the transaction, so not even the DELETE below can run. Nothing
// is being saved by it there either - the rows are a fixture, not a real data set.
$useTruncate = !$this->isInTransaction();

foreach ($tables as $table) {
if (!$useTruncate) {
$this->connection->createQueryBuilder()->delete($table)->executeStatement();

continue;
}

try {
// Cleanup before inserting (using TRUNCATE for speed, however not possible to rollback)
$this->connection->executeStatement(
Expand Down
Loading