| Current Path : /home/rtorresani/www/vendor/laminas/laminas-db/src/Sql/Platform/IbmDb2/ |
| Current File : //home/rtorresani/www/vendor/laminas/laminas-db/src/Sql/Platform/IbmDb2/SelectDecorator.php |
<?php
namespace Laminas\Db\Sql\Platform\IbmDb2;
use Laminas\Db\Adapter\Driver\DriverInterface;
use Laminas\Db\Adapter\ParameterContainer;
use Laminas\Db\Adapter\Platform\PlatformInterface;
use Laminas\Db\Sql\Platform\PlatformDecoratorInterface;
use Laminas\Db\Sql\Select;
use function array_push;
use function array_shift;
use function array_unshift;
use function current;
use function preg_match;
use function sprintf;
use function strpos;
class SelectDecorator extends Select implements PlatformDecoratorInterface
{
/** @var bool */
protected $isSelectContainDistinct = false;
/** @var Select */
protected $subject;
/** @var bool */
protected $supportsLimitOffset = false;
/**
* @return bool
*/
public function getIsSelectContainDistinct()
{
return $this->isSelectContainDistinct;
}
/**
* @param boolean $isSelectContainDistinct
*/
public function setIsSelectContainDistinct($isSelectContainDistinct)
{
$this->isSelectContainDistinct = $isSelectContainDistinct;
}
/**
* @param Select $select
*/
public function setSubject($select)
{
$this->subject = $select;
}
/**
* @return bool
*/
public function getSupportsLimitOffset()
{
return $this->supportsLimitOffset;
}
/**
* @param bool $supportsLimitOffset
*/
public function setSupportsLimitOffset($supportsLimitOffset)
{
$this->supportsLimitOffset = $supportsLimitOffset;
}
/**
* @see Select::renderTable
*
* @param string $table
* @param null|string $alias
* @return string
*/
protected function renderTable($table, $alias = null)
{
return $table . ' ' . $alias;
}
protected function localizeVariables()
{
parent::localizeVariables();
// set specifications
unset($this->specifications[self::LIMIT]);
unset($this->specifications[self::OFFSET]);
$this->specifications['LIMITOFFSET'] = null;
}
/**
* @param array $sqls
* @param array $parameters
*/
protected function processLimitOffset(
PlatformInterface $platform,
?DriverInterface $driver,
?ParameterContainer $parameterContainer,
&$sqls,
&$parameters
) {
if ($this->limit === null && $this->offset === null) {
return;
}
if ($this->supportsLimitOffset) {
// Note: db2_prepare/db2_execute fails with positional parameters, for LIMIT & OFFSET
$limit = (int) $this->limit;
if (! $limit) {
return;
}
$offset = (int) $this->offset;
if ($offset) {
array_push($sqls, sprintf("LIMIT %s OFFSET %s", $limit, $offset));
return;
}
array_push($sqls, sprintf("LIMIT %s", $limit));
return;
}
$selectParameters = $parameters[self::SELECT];
$starSuffix = $platform->getIdentifierSeparator() . self::SQL_STAR;
foreach ($selectParameters[0] as $i => $columnParameters) {
if (
$columnParameters[0] === self::SQL_STAR
|| (isset($columnParameters[1]) && $columnParameters[1] === self::SQL_STAR)
|| strpos($columnParameters[0], $starSuffix)
) {
$selectParameters[0] = [[self::SQL_STAR]];
break;
}
if (isset($columnParameters[1])) {
array_shift($columnParameters);
$selectParameters[0][$i] = $columnParameters;
}
}
// first, produce column list without compound names (using the AS portion only)
array_unshift($sqls, $this->createSqlFromSpecificationAndParameters(
['SELECT %1$s FROM (' => current($this->specifications[self::SELECT])],
$selectParameters
));
if (preg_match('/DISTINCT/i', $sqls[0])) {
$this->setIsSelectContainDistinct(true);
}
if ($parameterContainer) {
// create bottom part of query, with offset and limit using row_number
$limitParamName = $driver->formatParameterName('limit');
$offsetParamName = $driver->formatParameterName('offset');
array_push($sqls, sprintf(
// @codingStandardsIgnoreStart
") AS LAMINAS_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION WHERE LAMINAS_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION.LAMINAS_DB_ROWNUM BETWEEN %s AND %s",
// @codingStandardsIgnoreEnd
$offsetParamName,
$limitParamName
));
if ((int) $this->offset > 0) {
$parameterContainer->offsetSet('offset', (int) $this->offset + 1);
} else {
$parameterContainer->offsetSet('offset', (int) $this->offset);
}
$parameterContainer->offsetSet('limit', (int) $this->limit + (int) $this->offset);
} else {
if ((int) $this->offset > 0) {
$offset = (int) $this->offset + 1;
} else {
$offset = (int) $this->offset;
}
array_push($sqls, sprintf(
// @codingStandardsIgnoreStart
") AS LAMINAS_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION WHERE LAMINAS_IBMDB2_SERVER_LIMIT_OFFSET_EMULATION.LAMINAS_DB_ROWNUM BETWEEN %d AND %d",
// @codingStandardsIgnoreEnd
$offset,
(int) $this->limit + (int) $this->offset
));
}
if (isset($sqls[self::ORDER])) {
$orderBy = $sqls[self::ORDER];
unset($sqls[self::ORDER]);
} else {
$orderBy = '';
}
// add a column for row_number() using the order specification //dense_rank()
if ($this->getIsSelectContainDistinct()) {
$parameters[self::SELECT][0][] = ['DENSE_RANK() OVER (' . $orderBy . ')', 'LAMINAS_DB_ROWNUM'];
} else {
$parameters[self::SELECT][0][] = ['ROW_NUMBER() OVER (' . $orderBy . ')', 'LAMINAS_DB_ROWNUM'];
}
$sqls[self::SELECT] = $this->createSqlFromSpecificationAndParameters(
$this->specifications[self::SELECT],
$parameters[self::SELECT]
);
}
}