Skip to content

Commit

Permalink
Merge branch 'hotfix/3682' into develop
Browse files Browse the repository at this point in the history
Forward port zendframework#3682
  • Loading branch information
weierophinney committed Feb 6, 2013
2 parents 381b189 + cae5c0a commit ce4f339
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 18 deletions.
25 changes: 18 additions & 7 deletions library/Zend/Db/Sql/AbstractSql.php
Expand Up @@ -112,19 +112,30 @@ protected function processExpression(ExpressionInterface $expression, PlatformIn
}

/**
* @param $specification
* @param $specifications
* @param $parameters
* @return string
* @throws Exception\RuntimeException
*/
protected function createSqlFromSpecificationAndParameters($specification, $parameters)
protected function createSqlFromSpecificationAndParameters($specifications, $parameters)
{
if (is_string($specification)) {
return vsprintf($specification, $parameters);
if (is_string($specifications)) {
return vsprintf($specifications, $parameters);
}

$topSpec = key($specification);
$paramSpecs = $specification[$topSpec];
$parametersCount = count($parameters);
foreach ($specifications as $specificationString => $paramSpecs) {
if ($parametersCount == count($paramSpecs)) {
break;
}
unset($specificationString, $paramSpecs);
}

if (!isset($specificationString)) {
throw new Exception\RuntimeException(
'A number of parameters was found that is not supported by this specification'
);
}

$topParameters = array();
foreach ($parameters as $position => $paramsForPosition) {
Expand All @@ -148,7 +159,7 @@ protected function createSqlFromSpecificationAndParameters($specification, $para
$topParameters[] = $paramsForPosition;
}
}
return vsprintf($topSpec, $topParameters);
return vsprintf($specificationString, $topParameters);
}

protected function processSubSelect(Select $subselect, PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
Expand Down
70 changes: 59 additions & 11 deletions library/Zend/Db/Sql/Select.php
Expand Up @@ -28,6 +28,7 @@ class Select extends AbstractSql implements SqlInterface, PreparableSqlInterface
* @const
*/
const SELECT = 'select';
const QUANTIFIER = 'quantifier';
const COLUMNS = 'columns';
const TABLE = 'table';
const JOINS = 'joins';
Expand All @@ -37,6 +38,8 @@ class Select extends AbstractSql implements SqlInterface, PreparableSqlInterface
const ORDER = 'order';
const LIMIT = 'limit';
const OFFSET = 'offset';
const QUANTIFIER_DISTINCT = 'DISTINCT';
const QUANTIFIER_ALL = 'ALL';
const JOIN_INNER = 'inner';
const JOIN_OUTER = 'outer';
const JOIN_LEFT = 'left';
Expand All @@ -54,7 +57,12 @@ class Select extends AbstractSql implements SqlInterface, PreparableSqlInterface
'SELECT %1$s FROM %2$s' => array(
array(1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '),
null
)
),
'SELECT %1$s %2$s FROM %3$s' => array(
null,
array(1 => '%1$s', 2 => '%1$s AS %2$s', 'combinedby' => ', '),
null
),
),
self::JOINS => array(
'%1$s' => array(
Expand Down Expand Up @@ -92,6 +100,11 @@ class Select extends AbstractSql implements SqlInterface, PreparableSqlInterface
*/
protected $table = null;

/**
* @var null|string|Expression
*/
protected $quantifier = null;

/**
* @var array
*/
Expand Down Expand Up @@ -173,6 +186,21 @@ public function from($table)
return $this;
}

/**
* @param string|Expression $quantifier DISTINCT|ALL
* @return Select
*/
public function quantifier($quantifier)
{
if (!is_string($quantifier) && !$quantifier instanceof Expression) {
throw new Exception\InvalidArgumentException(
'Quantifier must be one of DISTINCT, ALL, or some platform specific Expression object'
);
}
$this->quantifier = $quantifier;
return $this;
}

/**
* Specify columns from which to select
*
Expand Down Expand Up @@ -392,6 +420,9 @@ public function reset($part)
}
$this->table = null;
break;
case self::QUANTIFIER:
$this->quantifier = null;
break;
case self::COLUMNS:
$this->columns = array();
break;
Expand Down Expand Up @@ -432,15 +463,16 @@ public function setSpecification($index, $specification)
public function getRawState($key = null)
{
$rawState = array(
self::TABLE => $this->table,
self::COLUMNS => $this->columns,
self::JOINS => $this->joins,
self::WHERE => $this->where,
self::ORDER => $this->order,
self::GROUP => $this->group,
self::HAVING => $this->having,
self::LIMIT => $this->limit,
self::OFFSET => $this->offset
self::TABLE => $this->table,
self::QUANTIFIER => $this->quantifier,
self::COLUMNS => $this->columns,
self::JOINS => $this->joins,
self::WHERE => $this->where,
self::ORDER => $this->order,
self::GROUP => $this->group,
self::HAVING => $this->having,
self::LIMIT => $this->limit,
self::OFFSET => $this->offset
);
return (isset($key) && array_key_exists($key, $rawState)) ? $rawState[$key] : $rawState;
}
Expand Down Expand Up @@ -623,7 +655,23 @@ protected function processSelect(PlatformInterface $platform, DriverInterface $d
}
}

return array($columns, $table);
if ($this->quantifier) {
if ($this->quantifier instanceof Expression) {
$quantifierParts = $this->processExpression($this->quantifier, $platform, $driver, 'quantifier');
if ($parameterContainer) {
$parameterContainer->merge($quantifierParts->getParameterContainer());
}
$quantifier = $quantifierParts->getSql();
} else {
$quantifier = $this->quantifier;
}
}

if (isset($quantifier)) {
return array($quantifier, $columns, $table);
} else {
return array($columns, $table);
}
}

protected function processJoins(PlatformInterface $platform, DriverInterface $driver = null, ParameterContainer $parameterContainer = null)
Expand Down
41 changes: 41 additions & 0 deletions tests/ZendTest/Db/Sql/SelectTest.php
Expand Up @@ -53,6 +53,28 @@ public function testGetRawStateViaFrom(Select $select)
$this->assertEquals('foo', $select->getRawState('table'));
}

/**
* @testdox unit test: Test quantifier() returns Select object (is chainable)
* @covers Zend\Db\Sql\Select::quantifier
*/
public function testQuantifier()
{
$select = new Select;
$return = $select->quantifier($select::QUANTIFIER_DISTINCT);
$this->assertSame($select, $return);
return $return;
}

/**
* @testdox unit test: Test getRawState() returns infromation populated via from()
* @covers Zend\Db\Sql\Select::getRawState
* @depends testQuantifier
*/
public function testGetRawStateViaQuantifier(Select $select)
{
$this->assertEquals(Select::QUANTIFIER_DISTINCT, $select->getRawState('quantifier'));
}

/**
* @testdox unit test: Test columns() returns Select object (is chainable)
* @covers Zend\Db\Sql\Select::columns
Expand Down Expand Up @@ -979,6 +1001,23 @@ public function providerData()
))
);

$select41 = new Select;
$select41->from('foo')->quantifier(Select::QUANTIFIER_DISTINCT);
$sqlPrep41 = // same
$sqlStr41 = 'SELECT DISTINCT "foo".* FROM "foo"';
$internalTests41 = array(
'processSelect' => array(SELECT::QUANTIFIER_DISTINCT, array(array('"foo".*')), '"foo"'),
);

$select42 = new Select;
$select42->from('foo')->quantifier(new Expression('TOP ?', array(10)));
$sqlPrep42 = 'SELECT TOP ? "foo".* FROM "foo"';
$sqlStr42 = 'SELECT TOP \'10\' "foo".* FROM "foo"';
$internalTests42 = array(
'processSelect' => array('TOP ?', array(array('"foo".*')), '"foo"'),
);


/**
* $select = the select object
* $sqlPrep = the sql as a result of preparation
Expand Down Expand Up @@ -1030,6 +1069,8 @@ public function providerData()
array($select38, $sqlPrep38, array(), $sqlStr38, $internalTests38),
array($select39, $sqlPrep39, array(), $sqlStr39, $internalTests39),
array($select40, $sqlPrep40, array(), $sqlStr40, $internalTests40),
array($select41, $sqlPrep41, array(), $sqlStr41, $internalTests41),
array($select42, $sqlPrep42, array(), $sqlStr42, $internalTests42),
);
}
}

0 comments on commit ce4f339

Please sign in to comment.