src/Mssql/ExpressionTrait.php
<?php
declare(strict_types=1);
namespace Atk4\Dsql\Mssql;
use Doctrine\DBAL\Result as DbalResult;
trait ExpressionTrait
{
protected function escapeIdentifier(string $value): string
{
return $this->fixOpenEscapeChar(parent::escapeIdentifier($value));
}
protected function escapeIdentifierSoft(string $value): string
{
return $this->fixOpenEscapeChar(parent::escapeIdentifierSoft($value));
}
private function fixOpenEscapeChar(string $v): string
{
return preg_replace('~(?:\'(?:\'\'|\\\\\'|[^\'])*\')?+\K\]([^\[\]\'"(){}]*?)\]~s', '[$1]', $v);
}
// {{{ MSSQL does not support named parameters, so convert them to numerical inside execute
/** @var array|null */
private $numQueryParamsBackup;
/** @var string|null */
private $numQueryRender;
/**
* @return DbalResult|\PDOStatement PDOStatement iff for DBAL 2.x
*/
public function execute(object $connection = null): object
{
if ($this->numQueryParamsBackup !== null) {
return parent::execute($connection);
}
$this->numQueryParamsBackup = $this->params;
try {
$numParams = [];
$i = 0;
$j = 0;
$this->numQueryRender = preg_replace_callback(
'~(?:\'(?:\'\'|\\\\\'|[^\'])*\')?+\K(?:\?|:\w+)~s',
function ($matches) use (&$numParams, &$i, &$j) {
$numParams[++$i] = $this->params[$matches[0] === '?' ? ++$j : $matches[0]];
return '?';
},
parent::render()
);
$this->params = $numParams;
return parent::execute($connection);
} finally {
$this->params = $this->numQueryParamsBackup;
$this->numQueryParamsBackup = null;
$this->numQueryRender = null;
}
}
public function render(): string
{
if ($this->numQueryParamsBackup !== null) {
return $this->numQueryRender;
}
return parent::render();
}
public function getDebugQuery(): string
{
if ($this->numQueryParamsBackup === null) {
return parent::getDebugQuery();
}
$paramsBackup = $this->params;
$numQueryRenderBackupBackup = $this->numQueryParamsBackup;
$numQueryRenderBackup = $this->numQueryRender;
try {
$this->params = $this->numQueryParamsBackup;
$this->numQueryParamsBackup = null;
$this->numQueryRender = null;
return parent::getDebugQuery();
} finally {
$this->params = $paramsBackup;
$this->numQueryParamsBackup = $numQueryRenderBackupBackup;
$this->numQueryRender = $numQueryRenderBackup;
}
}
/// }}}
}