src/Propel/Runtime/Adapter/MSSQL/MssqlPropelPDO.php
<?php
/**
* MIT License. This file is part of the Propel package.
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Propel\Runtime\Adapter\MSSQL;
use Propel\Runtime\Connection\PropelPDO;
use Propel\Runtime\Exception\PropelException;
/**
* dblib doesn't support transactions so we need to add a workaround for
* transactions, last insert ID, and quoting
*/
class MssqlPropelPDO extends PropelPDO
{
/**
* Begin a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*
* @return bool
*/
public function beginTransaction(): bool
{
$return = true;
$opcount = $this->getNestedTransactionCount();
if ($opcount === 0) {
$return = (bool)$this->exec('BEGIN TRANSACTION');
if ($this->isInDebugMode()) {
$this->log('Begin transaction: ' . __METHOD__);
}
$this->isUncommitable = false;
}
$this->nestedTransactionCount++;
return $return;
}
/**
* Commit a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*
* @throws \Propel\Runtime\Exception\PropelException
*
* @return bool
*/
public function commit(): bool
{
$return = true;
$opcount = $this->getNestedTransactionCount();
if ($opcount > 0) {
if ($opcount === 1) {
if ($this->isUncommitable) {
throw new PropelException('Cannot commit because a nested transaction was rolled back');
}
$return = (bool)$this->exec('COMMIT TRANSACTION');
if ($this->isInDebugMode()) {
$this->log('Commit transaction: ' . __METHOD__);
}
}
$this->nestedTransactionCount--;
}
return $return;
}
/**
* Roll-back a transaction.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*
* @return bool
*/
public function rollBack(): bool
{
$return = true;
$opcount = $this->getNestedTransactionCount();
if ($opcount > 0) {
if ($opcount === 1) {
$return = (bool)$this->exec('ROLLBACK TRANSACTION');
if ($this->isInDebugMode()) {
$this->log('Rollback transaction: ' . __METHOD__);
}
} else {
$this->isUncommitable = true;
}
$this->nestedTransactionCount--;
}
return $return;
}
/**
* Rollback the whole transaction, even if this is a nested rollback
* and reset the nested transaction count to 0.
*
* It is necessary to override the abstract PDO transaction functions here, as
* the PDO driver for MSSQL does not support transactions.
*
* @return bool
*/
public function forceRollBack(): bool
{
$return = true;
$opcount = $this->getNestedTransactionCount();
if ($opcount > 0) {
// If we're in a transaction, always roll it back
// regardless of nesting level.
$return = (bool)$this->exec('ROLLBACK TRANSACTION');
// reset nested transaction count to 0 so that we don't
// try to commit (or rollback) the transaction outside this scope.
$this->nestedTransactionCount = 0;
if ($this->isInDebugMode()) {
$this->log('Rollback transaction: ' . __METHOD__);
}
}
return $return;
}
/**
* @param string|null $name
*
* @return int
*/
public function lastInsertId(?string $name = null): int
{
$result = $this->query('SELECT SCOPE_IDENTITY()');
return (int)$result->fetchColumn();
}
/**
* @param string $text
*
* @return string
*/
public function quoteIdentifier(string $text): string
{
return '[' . $text . ']';
}
}