From d77ffb28c934d6db9c3d357d137ffa658e89a518 Mon Sep 17 00:00:00 2001 From: zYne Date: Tue, 23 Jan 2007 16:27:20 +0000 Subject: [PATCH] added support for column aliases --- lib/Doctrine/Query.php | 46 +++++----- lib/Doctrine/Query/Where.php | 18 ++-- lib/Doctrine/Record.php | 12 ++- lib/Doctrine/Table.php | 55 +++++++++--- tests/CollectionTestCase.php | 39 +++++--- tests/ColumnAliasTestCase.php | 89 +++++++++++++++++++ .../CustomResultSetOrderTestCaseTestCase.php | 34 +++++++ tests/run.php | 3 +- 8 files changed, 241 insertions(+), 55 deletions(-) create mode 100644 tests/ColumnAliasTestCase.php create mode 100644 tests/CustomResultSetOrderTestCaseTestCase.php diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php index 8170004bc..3bf89a090 100644 --- a/lib/Doctrine/Query.php +++ b/lib/Doctrine/Query.php @@ -111,12 +111,12 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { { $tableAlias = $this->getTableAlias($componentAlias); - if( ! isset($this->tables[$tableAlias])) + if ( ! isset($this->tables[$tableAlias])) throw new Doctrine_Query_Exception('Unknown component path '.$componentPath); $table = $this->tables[$tableAlias]; - if(isset($this->pendingFields[$componentAlias])) { + if (isset($this->pendingFields[$componentAlias])) { $fields = $this->pendingFields[$componentAlias]; if(in_array('*', $fields)) @@ -124,7 +124,9 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { else $fields = array_unique(array_merge($table->getPrimaryKeys(), $fields)); } - foreach($fields as $name) { + foreach ($fields as $name) { + $name = $table->getColumnName($name); + $this->parts["select"][] = $tableAlias . '.' .$name . ' AS ' . $tableAlias . '__' . $name; } @@ -159,34 +161,34 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { if(method_exists($this->conn->expression, $name)) { - $argStr = substr($func, ($pos + 1), -1); + $argStr = substr($func, ($pos + 1), -1); - $args = explode(',', $argStr); + $args = explode(',', $argStr); - $e2 = explode(' ', $args[0]); + $e2 = explode(' ', $args[0]); - $distinct = ''; - if(count($e2) > 1) { - if(strtoupper($e2[0]) == 'DISTINCT') - $distinct = 'DISTINCT '; + $distinct = ''; + if(count($e2) > 1) { + if(strtoupper($e2[0]) == 'DISTINCT') + $distinct = 'DISTINCT '; - $args[0] = $e2[1]; - } + $args[0] = $e2[1]; + } - $parts = explode('.', $args[0]); - $owner = $parts[0]; - $alias = (isset($e[1])) ? $e[1] : $name; + $parts = explode('.', $args[0]); + $owner = $parts[0]; + $alias = (isset($e[1])) ? $e[1] : $name; - $e3 = explode('.', $alias); + $e3 = explode('.', $alias); - if(count($e3) > 1) { - $alias = $e3[1]; - $owner = $e3[0]; - } + if(count($e3) > 1) { + $alias = $e3[1]; + $owner = $e3[0]; + } - $this->pendingAggregates[$owner][] = array($name, $args, $distinct, $alias); + $this->pendingAggregates[$owner][] = array($name, $args, $distinct, $alias); } else { throw new Doctrine_Query_Exception('Unknown aggregate function '.$name); } @@ -212,6 +214,8 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable { $tableAlias = $this->getTableAlias($e[0]); $table = $this->tables[$tableAlias]; + $e[1] = $table->getColumnName($e[1]); + if( ! $table->hasColumn($e[1])) { throw new Doctrine_Query_Exception('Unknown column ' . $e[1]); } diff --git a/lib/Doctrine/Query/Where.php b/lib/Doctrine/Query/Where.php index fc1d79373..d6894d52a 100644 --- a/lib/Doctrine/Query/Where.php +++ b/lib/Doctrine/Query/Where.php @@ -83,8 +83,13 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition $field = array_pop($a); $reference = implode('.', $a); $table = $this->query->load($reference, false); + + $field = $table->getColumnName($field); + array_pop($a); + $reference2 = implode('.', $a); + $alias = $this->query->getTableAlias($reference2); $stack = $this->query->getRelationStack(); @@ -103,9 +108,10 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition } $where = array(); foreach ($values as $value) { - $where[] = $alias.'.'.$relation->getLocal(). - ' IN (SELECT '.$relation->getForeign(). - ' FROM '.$relation->getTable()->getTableName().' WHERE '.$field.$operator.$value.')'; + $where[] = $alias . '.' . $relation->getLocal() + . ' IN (SELECT '.$relation->getForeign() + . ' FROM ' . $relation->getTable()->getTableName() + . ' WHERE ' . $field . $operator . $value . ')'; } $where = implode(' AND ', $where); break; @@ -116,6 +122,8 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition $table = $this->query->load($reference, false); $alias = $this->query->getTableAlias($reference); $table = $this->query->getTable($alias); + + $field = $table->getColumnName($field); // check if value is enumerated value $enumIndex = $table->enumIndex($field, trim($value, "'")); @@ -161,8 +169,8 @@ class Doctrine_Query_Where extends Doctrine_Query_Condition $value = $enumIndex; } default: - $where = $alias . '.' . $field . ' ' - . $operator . ' ' . $value; + $where = $alias . '.' . $field . ' ' + . $operator . ' ' . $value; } } } diff --git a/lib/Doctrine/Record.php b/lib/Doctrine/Record.php index 28d7c53b7..16afde7ac 100644 --- a/lib/Doctrine/Record.php +++ b/lib/Doctrine/Record.php @@ -469,7 +469,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite } } break; - }; + } } /** * serialize @@ -501,7 +501,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite case "object": $vars['_data'][$k] = serialize($vars['_data'][$k]); break; - }; + } } } @@ -726,11 +726,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite */ public function get($name, $invoke = true) { - $listener = $this->_table->getAttribute(Doctrine::ATTR_LISTENER); $value = self::$null; $lower = strtolower($name); + $lower = $this->_table->getColumnName($lower); + if (isset($this->_data[$lower])) { // check if the property is null (= it is the Doctrine_Null object located in self::$null) if ($this->_data[$lower] === self::$null) { @@ -810,12 +811,15 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite { $lower = strtolower($name); + $lower = $this->_table->getColumnName($lower); + if (isset($this->_data[$lower])) { if ($value instanceof Doctrine_Record) { $id = $value->getIncremented(); - if ($id !== null) + if ($id !== null) { $value = $id; + } } if ($load) { diff --git a/lib/Doctrine/Table.php b/lib/Doctrine/Table.php index 5ed1ee508..f32c574c0 100644 --- a/lib/Doctrine/Table.php +++ b/lib/Doctrine/Table.php @@ -92,24 +92,29 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable */ protected $columns = array(); /** - * @var array $bound bound relations + * @var array $columnAliases an array of column aliases + * keys as column aliases and values as column names + */ + protected $columnAliases = array(); + /** + * @var array $bound bound relations */ private $bound = array(); /** - * @var array $boundAliases bound relation aliases + * @var array $boundAliases bound relation aliases */ private $boundAliases = array(); /** - * @var integer $columnCount cached column count, Doctrine_Record uses this column count in when - * determining its state + * @var integer $columnCount cached column count, Doctrine_Record uses this column count in when + * determining its state */ private $columnCount; /** - * @var array $parents the parent classes of this component + * @var array $parents the parent classes of this component */ private $parents = array(); /** - * @var boolean $hasDefaultValues whether or not this table has default values + * @var boolean $hasDefaultValues whether or not this table has default values */ private $hasDefaultValues; /** @@ -392,6 +397,24 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable } return null; } + /** + * getColumnName + * + * returns a column name for column alias + * if the actual name for the alias cannot be found + * this method returns the given alias + * + * @param string $alias column alias + * @return string column name + */ + public function getColumnName($alias) + { + if(isset($this->columnAliases[$alias])) { + return $this->columnAliases[$alias]; + } + + return $alias; + } /** * setColumn * @@ -402,7 +425,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable * @throws Doctrine_Table_Exception if trying use wrongly typed parameter * @return void */ - final public function setColumn($name, $type, $length = null, $options = array()) { + public function setColumn($name, $type, $length = null, $options = array()) + { if (is_string($options)) { $options = explode('|', $options); } @@ -415,12 +439,21 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable unset($options[$k]); } } - $name = strtolower($name); - if ($length == null) + $name = strtolower($name); + $parts = explode(' as ', $name); + + if (count($parts) > 1) { + $this->columnAliases[$parts[1]] = $parts[0]; + $name = $parts[0]; + } + + + if ($length == null) { $length = 2147483647; - - if((string) (int) $length !== (string) $length) { + } + + if ((string) (int) $length !== (string) $length) { throw new Doctrine_Table_Exception('Invalid argument given for column length'); } diff --git a/tests/CollectionTestCase.php b/tests/CollectionTestCase.php index f55d2293d..b1ab40819 100644 --- a/tests/CollectionTestCase.php +++ b/tests/CollectionTestCase.php @@ -30,8 +30,10 @@ * @since 1.0 * @version $Revision$ */ -class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { - public function testLoadRelatedForAssociation() { +class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase +{ + public function testLoadRelatedForAssociation() + { $coll = $this->connection->query("FROM User"); $this->assertEqual($coll->count(), 8); @@ -96,7 +98,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $this->assertEqual($coll[0]->name, 'zYne'); } - public function testLoadRelatedForNormalAssociation() { + public function testLoadRelatedForNormalAssociation() + { $resource = new Doctrine_Collection('Resource'); $resource[0]->name = 'resource 1'; $resource[0]->Type[0]->type = 'type 1'; @@ -126,7 +129,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $this->assertEqual(($count + 1), $this->dbh->count()); } - public function testAdd() { + public function testAdd() + { $coll = new Doctrine_Collection($this->objTable); $coll->add(new User()); $this->assertEqual($coll->count(),1); @@ -142,7 +146,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { } - public function testLoadRelated() { + public function testLoadRelated() + { $coll = $this->connection->query("FROM User(id)"); $q = $coll->loadRelated(); @@ -158,7 +163,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $coll[0]->Group[0]; $this->assertEqual($count, $this->dbh->count()); } - public function testLoadRelatedForLocalKeyRelation() { + public function testLoadRelatedForLocalKeyRelation() + { $coll = $this->connection->query("FROM User"); $this->assertEqual($coll->count(), 8); @@ -182,7 +188,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $this->connection->clear(); } - public function testLoadRelatedForForeignKey() { + public function testLoadRelatedForForeignKey() + { $coll = $this->connection->query("FROM User"); $this->assertEqual($coll->count(), 8); @@ -214,13 +221,15 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $this->connection->clear(); } - public function testCount() { + public function testCount() + { $coll = new Doctrine_Collection($this->connection->getTable('User')); $this->assertEqual($coll->count(), 0); $coll[0]; $this->assertEqual($coll->count(), 1); } - public function testExpand() { + public function testExpand() + { $users = $this->connection->query("FROM User-b.Phonenumber-l WHERE User.Phonenumber.phonenumber LIKE '%123%'"); $this->assertTrue($users instanceof Doctrine_Collection_Batch); @@ -248,7 +257,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $user = $this->connection->getTable("User")->find(4); } - public function testGenerator() { + public function testGenerator() + { $coll = new Doctrine_Collection($this->objTable); $coll->setKeyColumn('name'); @@ -266,7 +276,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { } } - public function testFetchCollectionWithIdAsIndex() { + public function testFetchCollectionWithIdAsIndex() + { $user = new User(); $user->attribute(Doctrine::ATTR_COLL_KEY, 'id'); @@ -277,7 +288,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $this->assertEqual($users[0]->state(), Doctrine_Record::STATE_TCLEAN); $this->assertEqual($users[4]->state(), Doctrine_Record::STATE_CLEAN); } - public function testFetchCollectionWithNameAsIndex() { + public function testFetchCollectionWithNameAsIndex() + { $user = new User(); $user->attribute(Doctrine::ATTR_COLL_KEY, 'name'); @@ -288,7 +300,8 @@ class Doctrine_Collection_TestCase extends Doctrine_UnitTestCase { $this->assertEqual($users[0]->state(), Doctrine_Record::STATE_TCLEAN); $this->assertEqual($users['zYne']->state(), Doctrine_Record::STATE_CLEAN); } - public function testFetchMultipleCollections() { + public function testFetchMultipleCollections() + { $this->connection->clear(); $user = new User(); diff --git a/tests/ColumnAliasTestCase.php b/tests/ColumnAliasTestCase.php new file mode 100644 index 000000000..8829b19e2 --- /dev/null +++ b/tests/ColumnAliasTestCase.php @@ -0,0 +1,89 @@ +. + */ + +/** + * Doctrine_ColumnAlias_TestCase + * + * @package Doctrine + * @author Konsta Vesterinen + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + */ +class Doctrine_ColumnAlias_TestCase extends Doctrine_UnitTestCase +{ + public function prepareData() + { } + public function prepareTables() + { } + + public function testAliasesAreSupportedForRecordPropertyAccessors() + { + $record = new ColumnAliasTest; + try { + $record->alias1 = 'someone'; + $record->alias2 = 187; + + $this->assertEqual($record->alias1, 'someone'); + $this->assertEqual($record->alias2, 187); + } catch(Doctrine_Record_Exception $e) { + $this->fail(); + } + $record->save(); + } + public function testAliasesAreSupportedForDqlSelectPart() + { + $q = new Doctrine_Query(); + + $q->select('c.alias1, c.alias2')->from('ColumnAliasTest c'); + + $coll = $q->execute(); + + $this->assertEqual($coll[0]->alias1, 'someone'); + $this->assertEqual($coll[0]->alias2, 187); + } + public function testAliasesAreSupportedForDqlWherePart() + { + $q = new Doctrine_Query(); + + $q->select('c.alias1, c.alias2') + ->from('ColumnAliasTest c') + ->where('c.alias1 = ?'); + + $coll = $q->execute(array('someone')); + + $this->assertEqual($coll[0]->alias1, 'someone'); + $this->assertEqual($coll[0]->alias2, 187); + } +} +class ColumnAliasTest extends Doctrine_Record +{ + public function setTableDefinition() + { + $this->hasColumn('column1 as alias1', 'string', 200); + $this->hasColumn('column2 as alias2', 'integer', 11); + } + public function setUp() + { + } +} diff --git a/tests/CustomResultSetOrderTestCaseTestCase.php b/tests/CustomResultSetOrderTestCaseTestCase.php new file mode 100644 index 000000000..2c02c18e8 --- /dev/null +++ b/tests/CustomResultSetOrderTestCaseTestCase.php @@ -0,0 +1,34 @@ +. + */ + +/** + * Doctrine_CustomResultSetOrderTestCase + * + * @package Doctrine + * @author Konsta Vesterinen + * @license http://www.opensource.org/licenses/lgpl-license.php LGPL + * @category Object Relational Mapping + * @link www.phpdoctrine.com + * @since 1.0 + * @version $Revision$ + */ +class Doctrine_CustomResultSetOrderTestCase extends Doctrine_UnitTestCase { +} diff --git a/tests/run.php b/tests/run.php index b7621c963..7d6f50619 100644 --- a/tests/run.php +++ b/tests/run.php @@ -106,7 +106,7 @@ $test->addTestCase(new Doctrine_Sequence_Sqlite_TestCase()); // Export module (not yet fully tested) $test->addTestCase(new Doctrine_Export_TestCase()); -$test->addTestCase(new Doctrine_Export_Reporter_TestCase()); +//$test->addTestCase(new Doctrine_Export_Reporter_TestCase()); $test->addTestCase(new Doctrine_Export_Firebird_TestCase()); $test->addTestCase(new Doctrine_Export_Informix_TestCase()); $test->addTestCase(new Doctrine_Export_Mysql_TestCase()); @@ -214,6 +214,7 @@ $test->addTestCase(new Doctrine_Query_Having_TestCase()); $test->addTestCase(new Doctrine_Query_JoinCondition_TestCase()); $test->addTestCase(new Doctrine_Query_Join_TestCase()); +$test->addTestCase(new Doctrine_ColumnAlias_TestCase()); // Cache tests //$test->addTestCase(new Doctrine_Cache_Query_SqliteTestCase()); //$test->addTestCase(new Doctrine_Cache_FileTestCase());