From 68088c16c59619cca17756e8691eddfd040a27cf Mon Sep 17 00:00:00 2001 From: zYne Date: Thu, 17 May 2007 23:13:58 +0000 Subject: [PATCH] Enum support for placeholders! --- lib/Doctrine/Hydrate.php | 17 ++++++--- lib/Doctrine/Query.php | 67 +++++++++++++++++++++++++++++------ lib/Doctrine/Query/Where.php | 7 ++++ lib/Doctrine/Table.php | 1 - tests/Query/WhereTestCase.php | 33 +++++++++++++++++ 5 files changed, 110 insertions(+), 15 deletions(-) diff --git a/lib/Doctrine/Hydrate.php b/lib/Doctrine/Hydrate.php index 96357f63d..71873f243 100644 --- a/lib/Doctrine/Hydrate.php +++ b/lib/Doctrine/Hydrate.php @@ -109,6 +109,8 @@ class Doctrine_Hydrate */ protected $parts = array( 'select' => array(), + 'distinct' => false, + 'forUpdate' => false, 'from' => array(), 'set' => array(), 'join' => array(), @@ -255,6 +257,8 @@ class Doctrine_Hydrate $this->tables = array(); $this->parts = array( 'select' => array(), + 'distinct' => false, + 'forUpdate' => false, 'from' => array(), 'set' => array(), 'join' => array(), @@ -327,6 +331,7 @@ class Doctrine_Hydrate public function _fetch($params = array(), $fetchMode = Doctrine::FETCH_RECORD) { $params = $this->conn->convertBooleans(array_merge($this->params, $params)); + $params = $this->convertEnums($params); if ( ! $this->view) { $query = $this->getQuery($params); @@ -336,19 +341,23 @@ class Doctrine_Hydrate if ($this->isLimitSubqueryUsed() && $this->conn->getDBH()->getAttribute(Doctrine::ATTR_DRIVER_NAME) !== 'mysql') { - + $params = array_merge($params, $params); } + $stmt = $this->conn->execute($query, $params); return $this->parseData($stmt); } - + public function convertEnums($params) + { + return $params; + } public function setAliasMap($map) { $this->_aliasMap = $map; } - public function getAliasMap() + public function getAliasMap() { return $this->_aliasMap; } @@ -403,7 +412,7 @@ class Doctrine_Hydrate // we keep track of all the collections $colls = array(); - $colls[] = $coll; + $colls[] = $coll; $prevRow = array(); /** * iterate over the fetched data diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index a2826d906..6200d27f6 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -35,15 +35,15 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable /** * @param array $subqueryAliases the table aliases needed in some LIMIT subqueries */ - private $subqueryAliases = array(); + protected $subqueryAliases = array(); /** * @param boolean $needsSubquery */ - private $needsSubquery = false; + protected $needsSubquery = false; /** * @param boolean $limitSubqueryUsed */ - private $limitSubqueryUsed = false; + protected $limitSubqueryUsed = false; protected $_status = array('needsSubquery' => true); @@ -51,20 +51,20 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable * @param boolean $isSubquery whether or not this query object is a subquery of another * query object */ - private $isSubquery; + protected $isSubquery; - private $isDistinct = false; + protected $isDistinct = false; - private $neededTables = array(); + protected $neededTables = array(); /** * @var array $pendingFields */ - private $pendingFields = array(); + protected $pendingFields = array(); /** * @var array $pendingSubqueries SELECT part subqueries, these are called pending subqueries since * they cannot be parsed directly (some queries might be correlated) */ - private $pendingSubqueries = array(); + protected $pendingSubqueries = array(); /** * @var boolean $subqueriesProcessed Whether or not pending subqueries have already been processed. * Consequent calls to getQuery would result badly constructed queries @@ -73,12 +73,15 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable * Since subqueries can be correlated, they can only be processed when * the main query is fully constructed */ - private $subqueriesProcessed = false; + protected $subqueriesProcessed = false; /** * @var array $_parsers an array of parser objects */ protected $_parsers = array(); - + /** + * @var array $_enumParams an array containing the keys of the parameters that should be enumerated + */ + protected $_enumParams = array(); /** * create @@ -90,6 +93,50 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { return new Doctrine_Query(); } + /** + * addEnumParam + * sets input parameter as an enumerated parameter + * + * @param string $key the key of the input parameter + * @return Doctrine_Query + */ + public function addEnumParam($key, $table = null, $column = null) + { + $array = (isset($table) || isset($column)) ? array($table, $column) : array(); + + if ($key === '?') { + $this->_enumParams[] = $array; + } else { + $this->_enumParams[$key] = $array; + } + } + /** + * getEnumParams + * get all enumerated parameters + * + * @return array all enumerated parameters + */ + public function getEnumParams() + { + return $this->_enumParams; + } + /** + * convertEnums + * convert enum parameters to their integer equivalents + * + * @return array converted parameter array + */ + public function convertEnums($params) + { + foreach ($this->_enumParams as $key => $values) { + if (isset($params[$key])) { + if ( ! empty($values)) { + $params[$key] = $values[0]->enumIndex($values[1], $params[$key]); + } + } + } + return $params; + } /** * isSubquery * if $bool parameter is set this method sets the value of diff --git a/lib/Doctrine/Query/Where.php b/lib/Doctrine/Query/Where.php index 91f6a773e..f8e32c5ea 100644 --- a/lib/Doctrine/Query/Where.php +++ b/lib/Doctrine/Query/Where.php @@ -163,6 +163,13 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition } $value = '(' . implode(', ', $value) . ')'; } + } elseif(substr($value, 0, 1) == ':' || $value === '?') { + // placeholder found + if ($table->getTypeOf($field) == 'enum') { + $this->query->addEnumParam($value, $table, $field); + } else { + $this->query->addEnumParam($value, null, null); + } } else { if ($enumIndex !== false) { $value = $enumIndex; diff --git a/lib/Doctrine/Table.php b/lib/Doctrine/Table.php index 44b5cd30e..96bb050e1 100644 --- a/lib/Doctrine/Table.php +++ b/lib/Doctrine/Table.php @@ -1387,7 +1387,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable { return array_keys($this->columns); } - /** * getDefinitionOf * diff --git a/tests/Query/WhereTestCase.php b/tests/Query/WhereTestCase.php index 02ea8fe96..7da4313c3 100644 --- a/tests/Query/WhereTestCase.php +++ b/tests/Query/WhereTestCase.php @@ -211,6 +211,39 @@ class Doctrine_Query_Where_TestCase extends Doctrine_UnitTestCase $this->assertEqual($q->getQuery(), "SELECT e.id AS e__id FROM entity e WHERE e.name = 'foo.bar' AND (e.type = 0)"); } + public function testEnumValuesWorkInPlaceholders() + { + $e = new EnumTest; + $e->status = 'verified'; + $e->save(); + $q = new Doctrine_Query(); + + $q->select('e.*')->from('EnumTest e')->where('e.status = ?'); + + $this->assertEqual(count($q->getEnumParams()), 1); + + $q->execute(array('verified')); + } + public function testEnumValuesWorkWithMultiplePlaceholders() + { + $q = new Doctrine_Query(); + + $q->select('e.*')->from('EnumTest e')->where('e.id = ? AND e.status = ?'); + $p = $q->getEnumParams(); + $this->assertEqual(array_keys($p), array(0, 1)); + $this->assertTrue(empty($p[0])); + $q->execute(array(1, 'verified')); + } + public function testEnumValuesWorkWithMultipleNamedPlaceholders() + { + $q = new Doctrine_Query(); + + $q->select('e.*')->from('EnumTest e')->where('e.id = :id AND e.status = :status'); + $p = $q->getEnumParams(); + $this->assertEqual(array_keys($p), array(':id', ':status')); + $this->assertTrue(empty($p[':id'])); + $q->execute(array(1, 'verified')); + } } ?>