Commit cfc7d4e4 authored by romanb's avatar romanb

Refactoring. Started to introduced a clear separation between column names and...

Refactoring. Started to introduced a clear separation between column names and field names (aka column aliases).\nDoctrine_Connection, DQL Parser classes/methods map field names => column names.\nDoctrine_Hydrate maps column names => field names during hydration.\nColumn names are only stored in Doctrine_Table:: and Doctrine_Table::.\nRelations use column names in 'local'/'foreign'.\nWhen using field names (column aliases) you need to use the column names in 'local'/'foreign' when setting up a relation (hasOne/hasMany), not the field names.\n\n In other words column names are only used to communicate with the database. field names are used everywhere else. the casing of field names does not matter. column names are forced to lower case for portability. If you dont use field names (column aliases) your column names are your field names (and therefore all lowercase).
parent 95792cdb
Beta 2 Beta 2
------ ------
* r3183: NestedSet: 'level' column renamed to 'lvl' because LEVEL is an oracle keyword.
In order to upgrade existing trees you need to rename the level column to lvl
in your databases. This does not affect your code because the NestedSet now uses
a column alias (lvl as level). So your code still refers to the 'level' field.
* r3048: Doctrine::exportSchema() replaced by Doctrine::createTablesFromModels() * r3048: Doctrine::exportSchema() replaced by Doctrine::createTablesFromModels()
* r3048: Doctrine::exportSql() replaced by Doctrine::generateSqlFromModels() * r3048: Doctrine::exportSql() replaced by Doctrine::generateSqlFromModels()
* r3048: Doctrine::importSchema() replaced by Doctrine::generateModelsFromDb() * r3048: Doctrine::importSchema() replaced by Doctrine::generateModelsFromDb()
......
...@@ -151,7 +151,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -151,7 +151,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
protected $options = array(); protected $options = array();
/** /**
* @var array $availableDrivers an array containing all availible drivers * @var array $availableDrivers an array containing all available drivers
*/ */
private static $availableDrivers = array( private static $availableDrivers = array(
'Mysql', 'Mysql',
...@@ -180,7 +180,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -180,7 +180,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->isConnected = true; $this->isConnected = true;
} elseif (is_array($adapter)) { } else if (is_array($adapter)) {
$this->pendingAttributes[Doctrine::ATTR_DRIVER_NAME] = $adapter['scheme']; $this->pendingAttributes[Doctrine::ATTR_DRIVER_NAME] = $adapter['scheme'];
$this->options['dsn'] = $adapter['dsn']; $this->options['dsn'] = $adapter['dsn'];
...@@ -468,7 +468,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -468,7 +468,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @throws PDOException if something fails at PDO level * @throws PDOException if something fails at PDO level
* @return integer number of rows affected * @return integer number of rows affected
*/ */
public function replace($table, array $fields, array $keys) public function replace(Doctrine_Table $table, array $fields, array $keys)
{ {
//if ( ! $this->supports('replace')) //if ( ! $this->supports('replace'))
// throw new Doctrine_Connection_Exception('replace query is not supported'); // throw new Doctrine_Connection_Exception('replace query is not supported');
...@@ -478,26 +478,26 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -478,26 +478,26 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
} }
$condition = $values = array(); $condition = $values = array();
foreach ($fields as $name => $value) { foreach ($fields as $fieldName => $value) {
$values[$name] = $value; $values[$fieldName] = $value;
if (in_array($name, $keys)) { if (in_array($fieldName, $keys)) {
if ($value === null) if ($value === null)
throw new Doctrine_Connection_Exception('key value '.$name.' may not be null'); throw new Doctrine_Connection_Exception('key value '.$fieldName.' may not be null');
$condition[] = $name . ' = ?'; $condition[] = $table->getColumnName($fieldName) . ' = ?';
$conditionValues[] = $value; $conditionValues[] = $value;
} }
} }
$query = 'DELETE FROM ' . $this->quoteIdentifier($table) . ' WHERE ' . implode(' AND ', $condition); $query = 'DELETE FROM ' . $this->quoteIdentifier($table->getTableName())
$affectedRows = $this->exec($query); . ' WHERE ' . implode(' AND ', $condition);
$affectedRows = $this->exec($query, $conditionValues);
$this->insert($table, $values); $this->insert($table, $values);
$affectedRows++; $affectedRows++;
return $affectedRows; return $affectedRows;
} }
...@@ -509,16 +509,16 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -509,16 +509,16 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @param array $identifier An associateve array containing identifier column-value pairs. * @param array $identifier An associateve array containing identifier column-value pairs.
* @return integer The number of affected rows * @return integer The number of affected rows
*/ */
public function delete($table, array $identifier) public function delete(Doctrine_Table $table, array $identifier)
{ {
$tmp = array(); $tmp = array();
foreach (array_keys($identifier) as $id) { foreach (array_keys($identifier) as $id) {
$tmp[] = $id . ' = ?'; $tmp[] = $table->getColumnName($id) . ' = ?';
} }
$query = 'DELETE FROM ' $query = 'DELETE FROM '
. $this->quoteIdentifier($table) . $this->quoteIdentifier($table->getTableName())
. ' WHERE ' . implode(' AND ', $tmp); . ' WHERE ' . implode(' AND ', $tmp);
...@@ -534,27 +534,27 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -534,27 +534,27 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return mixed boolean false if empty value array was given, * @return mixed boolean false if empty value array was given,
* otherwise returns the number of affected rows * otherwise returns the number of affected rows
*/ */
public function update($table, array $values, array $identifier) public function update(Doctrine_Table $table, array $fields, array $identifier)
{ {
if (empty($values)) { if (empty($fields)) {
return false; return false;
} }
$set = array(); $set = array();
foreach ($values as $name => $value) { foreach ($fields as $fieldName => $value) {
if ($value instanceof Doctrine_Expression) { if ($value instanceof Doctrine_Expression) {
$set[] = $name . ' = ' . $value->getSql(); $set[] = $table->getColumnName($fieldName) . ' = ' . $value->getSql();
unset($values[$name]); unset($values[$name]);
} else { } else {
$set[] = $name . ' = ?'; $set[] = $table->getColumnName($fieldName) . ' = ?';
} }
} }
$params = array_merge(array_values($values), array_values($identifier)); $params = array_merge(array_values($fields), array_values($identifier));
$sql = 'UPDATE ' . $this->quoteIdentifier($table) $sql = 'UPDATE ' . $this->quoteIdentifier($table->getTableName())
. ' SET ' . implode(', ', $set) . ' SET ' . implode(', ', $set)
. ' WHERE ' . implode(' = ? AND ', array_keys($identifier)) . ' WHERE ' . implode(' = ? AND ', $table->getIdentifierColumnNames())
. ' = ?'; . ' = ?';
return $this->exec($sql, $params); return $this->exec($sql, $params);
...@@ -568,34 +568,36 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -568,34 +568,36 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @return mixed boolean false if empty value array was given, * @return mixed boolean false if empty value array was given,
* otherwise returns the number of affected rows * otherwise returns the number of affected rows
*/ */
public function insert($table, array $values) { public function insert(Doctrine_Table $table, array $fields) {
if (empty($values)) { if (empty($fields)) {
return false; return false;
} }
$tableName = $table->getTableName();
// column names are specified as array keys // column names are specified as array keys
$cols = array(); $cols = array();
// the query VALUES will contain either expresions (eg 'NOW()') or ? // the query VALUES will contain either expresions (eg 'NOW()') or ?
$a = array(); $a = array();
foreach ($values as $k => $value) { foreach ($fields as $fieldName => $value) {
$cols[] = $this->quoteIdentifier($k); $cols[] = $this->quoteIdentifier($table->getColumnName($fieldName));
if ($value instanceof Doctrine_Expression) { if ($value instanceof Doctrine_Expression) {
$a[] = $value->getSql(); $a[] = $value->getSql();
unset($values[$k]); unset($fields[$fieldName]);
} else { } else {
$a[] = '?'; $a[] = '?';
} }
} }
// build the statement // build the statement
$query = 'INSERT INTO ' . $this->quoteIdentifier($table) $query = 'INSERT INTO ' . $this->quoteIdentifier($tableName)
. ' (' . implode(', ', $cols) . ') ' . ' (' . implode(', ', $cols) . ') '
. 'VALUES ('; . 'VALUES (';
$query .= implode(', ', $a) . ')'; $query .= implode(', ', $a) . ')';
// prepare and execute the statement // prepare and execute the statement
return $this->exec($query, array_values($values)); return $this->exec($query, array_values($fields));
} }
/** /**
...@@ -912,6 +914,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun ...@@ -912,6 +914,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->getAttribute(Doctrine::ATTR_LISTENER)->preQuery($event); $this->getAttribute(Doctrine::ATTR_LISTENER)->preQuery($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
//echo $query . "<br />";
$stmt = $this->dbh->query($query); $stmt = $this->dbh->query($query);
$this->_count++; $this->_count++;
......
...@@ -166,7 +166,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common ...@@ -166,7 +166,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common
* *
* @return integer the number of affected rows * @return integer the number of affected rows
*/ */
public function replace($table, array $fields, array $keys) public function replace(Doctrine_Table $table, array $fields, array $keys)
{ {
$count = count($fields); $count = count($fields);
$query = $values = ''; $query = $values = '';
...@@ -180,7 +180,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common ...@@ -180,7 +180,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common
$values.= ','; $values.= ',';
} }
$query .= $name; $query .= $table->getColumnName($name);
if (isset($fields[$name]['null']) && $fields[$name]['null']) { if (isset($fields[$name]['null']) && $fields[$name]['null']) {
$value = 'NULL'; $value = 'NULL';
...@@ -202,7 +202,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common ...@@ -202,7 +202,7 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common
if ($keys == 0) { if ($keys == 0) {
throw new Doctrine_Connection_Mysql_Exception('not specified which fields are keys'); throw new Doctrine_Connection_Mysql_Exception('not specified which fields are keys');
} }
$query = 'REPLACE INTO ' . $table . ' (' . $query . ') VALUES (' . $values . ')'; $query = 'REPLACE INTO ' . $table->getTableName() . ' (' . $query . ') VALUES (' . $values . ')';
return $this->exec($query); return $this->exec($query);
} }
......
...@@ -148,9 +148,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -148,9 +148,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
$record->state(Doctrine_Record::STATE_LOCKED); $record->state(Doctrine_Record::STATE_LOCKED);
$conn->beginTransaction(); $conn->beginTransaction();
$saveLater = $this->saveRelated($record); $saveLater = $this->saveRelated($record);
$record->state($state); $record->state($state);
...@@ -159,7 +158,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -159,7 +158,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE);
$record->preSave($event); $record->preSave($event);
$record->getTable()->getRecordListener()->preSave($event); $record->getTable()->getRecordListener()->preSave($event);
$state = $record->state(); $state = $record->state();
...@@ -180,7 +179,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -180,7 +179,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
$record->getTable()->getRecordListener()->postSave($event); $record->getTable()->getRecordListener()->postSave($event);
$record->postSave($event); $record->postSave($event);
} else { } else {
$conn->transaction->addInvalid($record); $conn->transaction->addInvalid($record);
...@@ -195,7 +194,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -195,7 +194,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
if ($record->hasReference($alias)) { if ($record->hasReference($alias)) {
$obj = $record->$alias; $obj = $record->$alias;
// check that the related object is not an instance of Doctrine_Null // check that the related object is not an instance of Doctrine_Null
if ( ! ($obj instanceof Doctrine_Null)) { if ( ! ($obj instanceof Doctrine_Null)) {
$obj->save($conn); $obj->save($conn);
...@@ -207,7 +206,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -207,7 +206,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$this->saveAssociations($record); $this->saveAssociations($record);
$record->state($state); $record->state($state);
$conn->commit(); $conn->commit();
return true; return true;
...@@ -284,10 +283,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -284,10 +283,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
foreach ($table->getOption('joinedParents') as $parent) { foreach ($table->getOption('joinedParents') as $parent) {
$parentTable = $table->getConnection()->getTable($parent); $parentTable = $table->getConnection()->getTable($parent);
$this->conn->delete($parentTable->getTableName(), $record->identifier()); $this->conn->delete($parentTable, $record->identifier());
} }
} }
$this->conn->delete($table->getTableName(), $record->identifier()); $this->conn->delete($table, $record->identifier());
$record->state(Doctrine_Record::STATE_TCLEAN); $record->state(Doctrine_Record::STATE_TCLEAN);
} else { } else {
...@@ -295,7 +294,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -295,7 +294,6 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$record->state($state); $record->state($state);
} }
$table->getRecordListener()->postDelete($event); $table->getRecordListener()->postDelete($event);
$record->postDelete($event); $record->postDelete($event);
...@@ -554,12 +552,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -554,12 +552,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
foreach ($classes as $class) { foreach ($classes as $class) {
$parentTable = $this->conn->getTable($class); $parentTable = $this->conn->getTable($class);
$this->conn->update($this->conn->getTable($class)->getTableName(), $dataSet[$class], $identifier); $this->conn->update($this->conn->getTable($class), $dataSet[$class], $identifier);
} }
} else { } else {
$array = $record->getPrepared(); $array = $record->getPrepared();
$this->conn->update($table->getTableName(), $array, $identifier); $this->conn->update($table, $array, $identifier);
} }
$record->assignIdentifier(true); $record->assignIdentifier(true);
} }
...@@ -608,7 +606,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -608,7 +606,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$dataSet[$parent][$id] = $value; $dataSet[$parent][$id] = $value;
} }
$this->conn->insert($this->conn->getTable($parent)->getTableName(), $dataSet[$parent]); $this->conn->insert($this->conn->getTable($parent), $dataSet[$parent]);
} }
} }
} else { } else {
...@@ -624,6 +622,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -624,6 +622,10 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
return true; return true;
} }
/**
* @todo DESCRIBE WHAT THIS METHOD DOES, PLEASE!
*/
public function formatDataSet(Doctrine_Record $record) public function formatDataSet(Doctrine_Record $record)
{ {
$table = $record->getTable(); $table = $record->getTable();
...@@ -634,47 +636,53 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module ...@@ -634,47 +636,53 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$array = $record->getPrepared(); $array = $record->getPrepared();
foreach ($table->getColumns() as $column => $definition) { foreach ($table->getColumns() as $columnName => $definition) {
$fieldName = $table->getFieldName($columnName);
if (isset($definition['primary']) && $definition['primary']) { if (isset($definition['primary']) && $definition['primary']) {
continue; continue;
} }
if (isset($definition['owner'])) { if (isset($definition['owner'])) {
$dataSet[$definition['owner']][$column] = $array[$column]; $dataSet[$definition['owner']][$fieldName] = $array[$fieldName];
} else { } else {
$dataSet[$component][$column] = $array[$column]; $dataSet[$component][$fieldName] = $array[$fieldName];
} }
} }
return $dataSet; return $dataSet;
} }
/**
* @todo DESCRIBE WHAT THIS METHOD DOES, PLEASE!
*/
public function processSingleInsert(Doctrine_Record $record) public function processSingleInsert(Doctrine_Record $record)
{ {
$array = $record->getPrepared(); $fields = $record->getPrepared();
if (empty($array)) { if (empty($fields)) {
return false; return false;
} }
$table = $record->getTable();
$keys = (array) $table->getIdentifier(); $table = $record->getTable();
$identifier = (array) $table->getIdentifier();
$seq = $record->getTable()->sequenceName; $seq = $record->getTable()->sequenceName;
if ( ! empty($seq)) { if ( ! empty($seq)) {
$id = $this->conn->sequence->nextId($seq); $id = $this->conn->sequence->nextId($seq);
$name = $record->getTable()->getIdentifier(); $seqName = $table->getIdentifier();
$array[$name] = $id; $fields[$seqName] = $id;
$record->assignIdentifier($id); $record->assignIdentifier($id);
} }
$this->conn->insert($table->getTableName(), $array); $this->conn->insert($table, $fields);
if (empty($seq) && count($keys) == 1 && $keys[0] == $table->getIdentifier() && if (empty($seq) && count($identifier) == 1 && $identifier[0] == $table->getIdentifier() &&
$table->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) { $table->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) {
if (strtolower($this->conn->getName()) == 'pgsql') { if (strtolower($this->conn->getName()) == 'pgsql') {
$seq = $table->getTableName() . '_' . $keys[0]; $seq = $table->getTableName() . '_' . $identifier[0];
} }
$id = $this->conn->sequence->lastInsertId($seq); $id = $this->conn->sequence->lastInsertId($seq);
......
...@@ -819,7 +819,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -819,7 +819,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
if ($this->type !== self::SELECT) { if ($this->type !== self::SELECT) {
return $this->_conn->exec($query, $params); return $this->_conn->exec($query, $params);
} }
//echo $query . "<br /><br />";
$stmt = $this->_conn->execute($query, $params); $stmt = $this->_conn->execute($query, $params);
return $stmt; return $stmt;
} }
...@@ -850,7 +850,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -850,7 +850,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
if ($cached === false) { if ($cached === false) {
// cache miss // cache miss
$stmt = $this->_execute($params); $stmt = $this->_execute($params);
$array = $this->parseData2($stmt, Doctrine::HYDRATE_ARRAY); $array = $this->hydrateResultSet($stmt, Doctrine::HYDRATE_ARRAY);
$cached = $this->getCachedForm($array); $cached = $this->getCachedForm($array);
...@@ -883,7 +883,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -883,7 +883,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
return $stmt; return $stmt;
} }
$array = $this->parseData2($stmt, $hydrationMode); $array = $this->hydrateResultSet($stmt, $hydrationMode);
} }
return $array; return $array;
} }
...@@ -1022,7 +1022,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -1022,7 +1022,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
* @param mixed $stmt * @param mixed $stmt
* @return array * @return array
*/ */
public function parseData2($stmt, $hydrationMode) public function hydrateResultSet($stmt, $hydrationMode)
{ {
if ($hydrationMode == Doctrine::HYDRATE_NONE) { if ($hydrationMode == Doctrine::HYDRATE_NONE) {
return $stmt->fetchAll(PDO::FETCH_NUM); return $stmt->fetchAll(PDO::FETCH_NUM);
...@@ -1076,29 +1076,33 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -1076,29 +1076,33 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
// of magnitude. // of magnitude.
if ( ! isset($cache[$key])) { if ( ! isset($cache[$key])) {
$e = explode('__', $key); $e = explode('__', $key);
$cache[$key]['field'] = $field = strtolower(array_pop($e)); $last = strtolower(array_pop($e));
$cache[$key]['alias'] = $this->_tableAliases[strtolower(implode('__', $e))]; $cache[$key]['alias'] = $this->_tableAliases[strtolower(implode('__', $e))];
$fieldName = $this->_aliasMap[$cache[$key]['alias']]['table']->getFieldName($last);
//echo "hydrate:" . $fieldName . "<br /><br />";
$cache[$key]['fieldName'] = $fieldName;
$cache[$key]['columnName'] = $last;
} }
$map = $this->_aliasMap[$cache[$key]['alias']]; $map = $this->_aliasMap[$cache[$key]['alias']];
$table = $map['table']; $table = $map['table'];
$alias = $cache[$key]['alias']; $alias = $cache[$key]['alias'];
$field = $cache[$key]['field']; $fieldName = $cache[$key]['fieldName'];
if (isset($this->_aliasMap[$alias]['agg'][$field])) { if (isset($this->_aliasMap[$alias]['agg'][$fieldName])) {
$field = $this->_aliasMap[$alias]['agg'][$field]; $fieldName = $this->_aliasMap[$alias]['agg'][$fieldName];
} }
if ($table->isIdentifier($fieldName)) {
if ($table->isIdentifier($field)) {
$id[$alias] .= '|' . $value; $id[$alias] .= '|' . $value;
} }
$currData[$alias][$field] = $table->prepareValue($field, $value); $currData[$alias][$fieldName] = $table->prepareValue($fieldName, $value);
if ($value !== null) { if ($value !== null) {
$identifiable[$alias] = true; $identifiable[$alias] = true;
} }
} }
// dealing with root component // dealing with root component
...@@ -1162,7 +1166,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -1162,7 +1166,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
if ( ! isset($prev[$parent])) { if ( ! isset($prev[$parent])) {
break; break;
} }
// check the type of the relation // check the type of the relation
if ( ! $relation->isOneToOne()) { if ( ! $relation->isOneToOne()) {
// initialize the collection // initialize the collection
...@@ -1207,7 +1211,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -1207,7 +1211,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
} else { } else {
$prev[$parent][$componentAlias] = $element; $prev[$parent][$componentAlias] = $element;
} }
$oneToOne = true; $oneToOne = true;
} }
$coll =& $prev[$parent][$componentAlias]; $coll =& $prev[$parent][$componentAlias];
$this->_setLastElement($prev, $coll, $index, $alias, $oneToOne); $this->_setLastElement($prev, $coll, $index, $alias, $oneToOne);
...@@ -1215,7 +1219,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab ...@@ -1215,7 +1219,7 @@ class Doctrine_Hydrate extends Doctrine_Locator_Injectable implements Serializab
} }
$id[$rootAlias] = ''; $id[$rootAlias] = '';
} }
$driver->flush(); $driver->flush();
$stmt->closeCursor(); $stmt->closeCursor();
......
...@@ -78,7 +78,7 @@ class Doctrine_Hydrate_Record extends Doctrine_Locator_Injectable ...@@ -78,7 +78,7 @@ class Doctrine_Hydrate_Record extends Doctrine_Locator_Injectable
*/ */
public function isIdentifiable(array $row, Doctrine_Table $table) public function isIdentifiable(array $row, Doctrine_Table $table)
{ {
$primaryKeys = $table->getIdentifier(); $primaryKeys = $table->getIdentifierColumnNames();
if (is_array($primaryKeys)) { if (is_array($primaryKeys)) {
foreach ($primaryKeys as $id) { foreach ($primaryKeys as $id) {
...@@ -103,8 +103,15 @@ class Doctrine_Hydrate_Record extends Doctrine_Locator_Injectable ...@@ -103,8 +103,15 @@ class Doctrine_Hydrate_Record extends Doctrine_Locator_Injectable
$this->_tables[$component] = Doctrine_Manager::getInstance()->getTable($component); $this->_tables[$component] = Doctrine_Manager::getInstance()->getTable($component);
$this->_tables[$component]->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false); $this->_tables[$component]->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
} }
//echo "..before..";
//Doctrine::dump($data);
$this->_tables[$component]->setData($data); $this->_tables[$component]->setData($data);
$record = $this->_tables[$component]->getRecord(); $record = $this->_tables[$component]->getRecord();
//echo "..after..";
//Doctrine::dump($record->getData());
if ( ! isset($this->_records[$record->getOid()]) ) { if ( ! isset($this->_records[$record->getOid()]) ) {
$record->clearRelated(); $record->clearRelated();
......
...@@ -32,6 +32,7 @@ Doctrine::autoload('Doctrine_Query_Abstract'); ...@@ -32,6 +32,7 @@ Doctrine::autoload('Doctrine_Query_Abstract');
*/ */
class Doctrine_Query extends Doctrine_Query_Abstract implements Countable class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
{ {
/** @todo document the query states (and the transitions between them). */
const STATE_CLEAN = 1; const STATE_CLEAN = 1;
const STATE_DIRTY = 2; const STATE_DIRTY = 2;
...@@ -156,7 +157,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -156,7 +157,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
protected $_pendingJoinConditions = array(); protected $_pendingJoinConditions = array();
protected $_expressionMap = array(); protected $_expressionMap = array();
/**
* @var integer $_state The current state of this query.
*/
protected $_state = Doctrine_Query::STATE_CLEAN; protected $_state = Doctrine_Query::STATE_CLEAN;
/** /**
...@@ -170,7 +174,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -170,7 +174,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
{ {
return new Doctrine_Query($conn); return new Doctrine_Query($conn);
} }
/**
* Resets the query to the state just after it has been instantiated.
*/
public function reset() public function reset()
{ {
$this->_pendingJoinConditions = array(); $this->_pendingJoinConditions = array();
...@@ -318,6 +325,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -318,6 +325,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* *
* @throws Doctrine_Query_Exception if unknown parser name given * @throws Doctrine_Query_Exception if unknown parser name given
* @return Doctrine_Query_Part * @return Doctrine_Query_Part
* @todo Doc/Description: What is the parameter for? Which parsers are available?
*/ */
public function getParser($name) public function getParser($name)
{ {
...@@ -386,10 +394,12 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -386,10 +394,12 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
/** /**
* getDqlPart * getDqlPart
* returns the given DQL query part * returns a specific DQL query part.
* *
* @param string $queryPart the name of the query part * @param string $queryPart the name of the query part
* @return string the DQL query part * @return string the DQL query part
* @todo Description: List which query parts exist or point to the method/property
* where they are listed.
*/ */
public function getDqlPart($queryPart) public function getDqlPart($queryPart)
{ {
...@@ -402,7 +412,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -402,7 +412,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
/** /**
* getDql * getDql
* returns the DQL query associated with this object * returns the DQL query that is represented by this query object.
* *
* the query is built from $_dqlParts * the query is built from $_dqlParts
* *
...@@ -432,6 +442,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -432,6 +442,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* @throws Doctrine_Query_Exception if unknown component alias has been given * @throws Doctrine_Query_Exception if unknown component alias has been given
* @param string $componentAlias the alias of the component * @param string $componentAlias the alias of the component
* @return void * @return void
* @todo Description: What is a 'pending field' (and are there non-pending fields, too)?
* What is 'processed'? (Meaning: What information is gathered & stored away)
*/ */
public function processPendingFields($componentAlias) public function processPendingFields($componentAlias)
{ {
...@@ -443,6 +455,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -443,6 +455,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
// check for wildcards // check for wildcards
if (in_array('*', $fields)) { if (in_array('*', $fields)) {
//echo "<br />";Doctrine::dump($table->getColumnNames()); echo "<br />";
$fields = $table->getColumnNames(); $fields = $table->getColumnNames();
} else { } else {
// only auto-add the primary key fields if this query object is not // only auto-add the primary key fields if this query object is not
...@@ -477,7 +490,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -477,7 +490,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
} }
$this->_neededTables[] = $tableAlias; $this->_neededTables[] = $tableAlias;
//Doctrine::dump(implode(', ', $sql));
//echo "<br /><br />";
return implode(', ', $sql); return implode(', ', $sql);
} }
} }
...@@ -487,6 +501,9 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -487,6 +501,9 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* *
* @throws Doctrine_Query_Exception if unknown component alias has been given * @throws Doctrine_Query_Exception if unknown component alias has been given
* @return void * @return void
* @todo Description: Explain what this method does. Is there a relation to parseSelect()?
* (It doesnt seem to get called from there...?). In what circumstances is this method
* used?
*/ */
public function parseSelectField($field) public function parseSelectField($field)
{ {
...@@ -533,6 +550,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -533,6 +550,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* *
* @param string $expr expression from which to get to owner from * @param string $expr expression from which to get to owner from
* @return string the component alias * @return string the component alias
* @todo Description: What does it mean if a component is an 'owner' of an expression?
* What kind of 'expression' are we talking about here?
*/ */
public function getExpressionOwner($expr) public function getExpressionOwner($expr)
{ {
...@@ -557,6 +576,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -557,6 +576,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* adds selected fields to pendingFields array * adds selected fields to pendingFields array
* *
* @param string $dql * @param string $dql
* @todo Description: What information is extracted (and then stored)?
*/ */
public function parseSelect($dql) public function parseSelect($dql)
{ {
...@@ -640,8 +660,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -640,8 +660,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* 5. Parses nested clauses and subqueries recursively * 5. Parses nested clauses and subqueries recursively
* *
* @return string SQL string * @return string SQL string
* @todo Description: What is a 'dql clause' (and what not)?
* Refactor: Too long & nesting level
*/ */
public function parseClause($clause) public function parseClause($clause)
{ {
$clause = trim($clause); $clause = trim($clause);
...@@ -670,7 +692,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -670,7 +692,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
// convert DQL function to its RDBMS specific equivalent // convert DQL function to its RDBMS specific equivalent
try { try {
$expr = call_user_func_array(array($this->_conn->expression, $name), $args); $expr = call_user_func_array(array($this->_conn->expression, $name), $args);
} catch(Doctrine_Expression_Exception $e) { } catch (Doctrine_Expression_Exception $e) {
throw new Doctrine_Query_Exception('Unknown function ' . $expr . '.'); throw new Doctrine_Query_Exception('Unknown function ' . $expr . '.');
} }
$term[0] = $expr; $term[0] = $expr;
...@@ -849,6 +871,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -849,6 +871,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* since some subqueries may be correlated * since some subqueries may be correlated
* *
* @return void * @return void
* @todo Better description. i.e. What is a 'pending subquery'? What does 'processed' mean?
* (parsed? sql is constructed? some information is gathered?)
*/ */
public function processPendingSubqueries() public function processPendingSubqueries()
{ {
...@@ -878,6 +902,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -878,6 +902,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* processes pending aggregate values for given component alias * processes pending aggregate values for given component alias
* *
* @return void * @return void
* @todo Better description. i.e. What is a 'pending aggregate'? What does 'processed' mean?
*/ */
public function processPendingAggregates() public function processPendingAggregates()
{ {
...@@ -1135,7 +1160,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1135,7 +1160,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$table = $map['table']; $table = $map['table'];
$rootAlias = key($this->_aliasMap); $rootAlias = key($this->_aliasMap);
if ( ! empty($this->parts['limit']) && $this->needsSubquery && $table->getAttribute(Doctrine::ATTR_QUERY_LIMIT) == Doctrine::LIMIT_RECORDS) { if ( ! empty($this->parts['limit']) && $this->needsSubquery &&
$table->getAttribute(Doctrine::ATTR_QUERY_LIMIT) == Doctrine::LIMIT_RECORDS) {
$this->isLimitSubqueryUsed = true; $this->isLimitSubqueryUsed = true;
$needsSubQuery = true; $needsSubQuery = true;
} }
...@@ -1235,6 +1261,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1235,6 +1261,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* of limiting the number of sql result set rows * of limiting the number of sql result set rows
* *
* @return string the limit subquery * @return string the limit subquery
* @todo A little refactor to make the method easier to understand & maybe shorter?
*/ */
public function getLimitSubquery() public function getLimitSubquery()
{ {
...@@ -1445,7 +1472,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1445,7 +1472,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$parts = $this->tokenizeQuery($query); $parts = $this->tokenizeQuery($query);
foreach($parts as $k => $part) { foreach ($parts as $k => $part) {
$part = implode(' ', $part); $part = implode(' ', $part);
$k = strtolower($k); $k = strtolower($k);
switch ($k) { switch ($k) {
...@@ -1485,7 +1512,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1485,7 +1512,10 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
return $this; return $this;
} }
/**
* @todo DESCRIBE ME! REFACTOR ME! I'M FAR TOO LONG AND COMPLEX! HARD TO UNDERSTAND!
*/
public function load($path, $loadFields = true) public function load($path, $loadFields = true)
{ {
if (isset($this->_aliasMap[$path])) { if (isset($this->_aliasMap[$path])) {
...@@ -1610,7 +1640,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1610,7 +1640,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$queryPart .= ' ON ' . $localAlias $queryPart .= ' ON ' . $localAlias
. '.' . '.'
. $localTable->getIdentifier() . $localTable->getIdentifier() // what about composite keys?
. ' = ' . ' = '
. $assocAlias . '.' . $relation->getLocal(); . $assocAlias . '.' . $relation->getLocal();
...@@ -1708,6 +1738,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1708,6 +1738,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
* *
* @param string $name * @param string $name
* @param string $componentAlias * @param string $componentAlias
* @todo DESCRIBE ME!
*/ */
public function loadRoot($name, $componentAlias) public function loadRoot($name, $componentAlias)
{ {
...@@ -1737,11 +1768,14 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1737,11 +1768,14 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
return $table; return $table;
} }
/**
* @todo DESCRIBE ME!
*/
public function buildInheritanceJoinSql($name, $componentAlias) public function buildInheritanceJoinSql($name, $componentAlias)
{ {
// get the connection for the component // get the connection for the component
$this->_conn = Doctrine_Manager::getInstance() $this->_conn = Doctrine_Manager::getInstance()->getConnectionForComponent($name);
->getConnectionForComponent($name);
$table = $this->_conn->getTable($name); $table = $this->_conn->getTable($name);
$tableName = $table->getTableName(); $tableName = $table->getTableName();
...@@ -1762,6 +1796,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable ...@@ -1762,6 +1796,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
$queryPart .= ' LEFT JOIN ' . $this->_conn->quoteIdentifier($parentTable->getTableName()) $queryPart .= ' LEFT JOIN ' . $this->_conn->quoteIdentifier($parentTable->getTableName())
. ' ' . $this->_conn->quoteIdentifier($parentTableAlias) . ' ON '; . ' ' . $this->_conn->quoteIdentifier($parentTableAlias) . ' ON ';
//Doctrine::dump($table->getIdentifier());
foreach ((array) $table->getIdentifier() as $identifier) { foreach ((array) $table->getIdentifier() as $identifier) {
$column = $table->getColumnName($identifier); $column = $table->getColumnName($identifier);
......
...@@ -105,7 +105,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -105,7 +105,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
protected $_state; protected $_state;
/** /**
* @var array $_modified an array containing properties that have been modified * @var array $_modified an array containing field names that have been modified
*/ */
protected $_modified = array(); protected $_modified = array();
...@@ -156,48 +156,47 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -156,48 +156,47 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
// Check if the current connection has the records table in its registry // Check if the current connection has the records table in its registry
// If not this record is only used for creating table definition and setting up // If not this record is only used for creating table definition and setting up
// relations. // relations.
if ( ! $this->_table->getConnection()->hasTable($this->_table->getComponentName())) {
return;
}
if ($this->_table->getConnection()->hasTable($this->_table->getComponentName())) { $this->_oid = self::$_index;
$this->_oid = self::$_index;
self::$_index++;
$keys = (array) $this->_table->getIdentifier();
// get the data array self::$_index++;
$this->_data = $this->_table->getData();
// get the column count // get the data array
$count = count($this->_data); $this->_data = $this->_table->getData();
$this->_values = $this->cleanData($this->_data); // get the column count
$count = count($this->_data);
$this->prepareIdentifiers($exists); $this->_values = $this->cleanData($this->_data);
if ( ! $exists) { $this->prepareIdentifiers($exists);
if ($count > count($this->_values)) {
$this->_state = Doctrine_Record::STATE_TDIRTY;
} else {
$this->_state = Doctrine_Record::STATE_TCLEAN;
}
// set the default values for this record if ( ! $exists) {
$this->assignDefaultValues(); if ($count > count($this->_values)) {
$this->_state = Doctrine_Record::STATE_TDIRTY;
} else { } else {
$this->_state = Doctrine_Record::STATE_CLEAN; $this->_state = Doctrine_Record::STATE_TCLEAN;
if ($count < $this->_table->getColumnCount()) {
$this->_state = Doctrine_Record::STATE_PROXY;
}
} }
$this->_errorStack = new Doctrine_Validator_ErrorStack(get_class($this)); // set the default values for this record
$this->assignDefaultValues();
} else {
$this->_state = Doctrine_Record::STATE_CLEAN;
$repository = $this->_table->getRepository(); if ($count < $this->_table->getColumnCount()) {
$repository->add($this); $this->_state = Doctrine_Record::STATE_PROXY;
}
$this->construct();
} }
$this->_errorStack = new Doctrine_Validator_ErrorStack(get_class($this));
$repository = $this->_table->getRepository();
$repository->add($this);
$this->construct();
} }
...@@ -434,13 +433,14 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -434,13 +433,14 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$tmp = $data; $tmp = $data;
$data = array(); $data = array();
foreach ($this->getTable()->getColumnNames() as $name) { //Doctrine::dump($this->getTable()->getFieldNames());
if ( ! isset($tmp[$name])) { foreach ($this->getTable()->getFieldNames() as $fieldName) {
$data[$name] = self::$_null; if ( ! isset($tmp[$fieldName])) {
$data[$fieldName] = self::$_null;
} else { } else {
$data[$name] = $tmp[$name]; $data[$fieldName] = $tmp[$fieldName];
} }
unset($tmp[$name]); unset($tmp[$fieldName]);
} }
return $tmp; return $tmp;
...@@ -455,9 +455,10 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -455,9 +455,10 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/ */
public function hydrate(array $data) public function hydrate(array $data)
{ {
$this->_values = array_merge($this->_values, $this->cleanData($data)); $this->_values = array_merge($this->_values, $this->cleanData($data));
$this->_data = array_merge($this->_data, $data); $this->_data = array_merge($this->_data, $data);
//Doctrine::dump($this->_data);
$this->prepareIdentifiers(true); $this->prepareIdentifiers(true);
} }
...@@ -475,7 +476,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -475,7 +476,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
case Doctrine::IDENTIFIER_SEQUENCE: case Doctrine::IDENTIFIER_SEQUENCE:
case Doctrine::IDENTIFIER_NATURAL: case Doctrine::IDENTIFIER_NATURAL:
$name = $this->_table->getIdentifier(); $name = $this->_table->getIdentifier();
if (is_array($name)) {
$name = $name[0];
}
if ($exists) { if ($exists) {
if (isset($this->_data[$name]) && $this->_data[$name] !== self::$_null) { if (isset($this->_data[$name]) && $this->_data[$name] !== self::$_null) {
$this->_id[$name] = $this->_data[$name]; $this->_id[$name] = $this->_data[$name];
...@@ -623,7 +626,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -623,7 +626,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} else { } else {
$err = true; $err = true;
} }
} elseif (is_string($state)) { } else if (is_string($state)) {
$upper = strtoupper($state); $upper = strtoupper($state);
$const = 'Doctrine_Record::STATE_' . $upper; $const = 'Doctrine_Record::STATE_' . $upper;
...@@ -677,7 +680,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -677,7 +680,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->prepareIdentifiers(); $this->prepareIdentifiers();
$this->_state = Doctrine_Record::STATE_CLEAN; $this->_state = Doctrine_Record::STATE_CLEAN;
return $this; return $this;
} }
...@@ -745,15 +748,16 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -745,15 +748,16 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* @throws Doctrine_Record_Exception if trying to get an unknown property * @throws Doctrine_Record_Exception if trying to get an unknown property
* @return mixed * @return mixed
*/ */
public function rawGet($name) public function rawGet($fieldName)
{ {
if ( ! isset($this->_data[$name])) { if ( ! isset($this->_data[$fieldName])) {
throw new Doctrine_Record_Exception('Unknown property '. $name); throw new Doctrine_Record_Exception('Unknown property '. $fieldName);
} }
if ($this->_data[$name] === self::$_null) if ($this->_data[$fieldName] === self::$_null) {
return null; return null;
}
return $this->_data[$name]; return $this->_data[$fieldName];
} }
/** /**
...@@ -767,9 +771,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -767,9 +771,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
// only load the data from database if the Doctrine_Record is in proxy state // only load the data from database if the Doctrine_Record is in proxy state
if ($this->_state == Doctrine_Record::STATE_PROXY) { if ($this->_state == Doctrine_Record::STATE_PROXY) {
$this->refresh(); $this->refresh();
$this->_state = Doctrine_Record::STATE_CLEAN; $this->_state = Doctrine_Record::STATE_CLEAN;
return true; return true;
} }
return false; return false;
...@@ -784,45 +786,40 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -784,45 +786,40 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* @throws Doctrine_Record_Exception if trying to get a value of unknown property / related component * @throws Doctrine_Record_Exception if trying to get a value of unknown property / related component
* @return mixed * @return mixed
*/ */
public function get($name, $load = true) public function get($fieldName, $load = true)
{ {
$value = self::$_null; $value = self::$_null;
$lower = strtolower($name);
$lower = $this->_table->getColumnName($lower);
if (isset($this->_data[$lower])) { if (isset($this->_data[$fieldName])) {
// check if the property is null (= it is the Doctrine_Null object located in self::$_null) // check if the property is null (= it is the Doctrine_Null object located in self::$_null)
if ($this->_data[$lower] === self::$_null && $load) { if ($this->_data[$fieldName] === self::$_null && $load) {
$this->load(); $this->load();
} }
if ($this->_data[$lower] === self::$_null) { if ($this->_data[$fieldName] === self::$_null) {
$value = null; $value = null;
} else { } else {
$value = $this->_data[$lower]; $value = $this->_data[$fieldName];
} }
return $value; return $value;
} }
if (isset($this->_values[$lower])) { if (isset($this->_values[$fieldName])) {
return $this->_values[$lower]; return $this->_values[$fieldName];
} }
try { try {
if ( ! isset($this->_references[$fieldName]) && $load) {
if ( ! isset($this->_references[$name]) && $load) { $rel = $this->_table->getRelation($fieldName);
$rel = $this->_table->getRelation($name); $this->_references[$fieldName] = $rel->fetchRelatedFor($this);
$this->_references[$name] = $rel->fetchRelatedFor($this);
} }
return $this->_references[$name]; return $this->_references[$fieldName];
} catch(Doctrine_Table_Exception $e) {
} catch (Doctrine_Table_Exception $e) {
foreach ($this->_table->getFilters() as $filter) { foreach ($this->_table->getFilters() as $filter) {
if (($value = $filter->filterGet($this, $name, $value)) !== null) { if (($value = $filter->filterGet($this, $fieldName, $value)) !== null) {
return $value; return $value;
} }
} }
...@@ -841,7 +838,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -841,7 +838,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/ */
public function mapValue($name, $value) public function mapValue($name, $value)
{ {
$name = strtolower($name);
$this->_values[$name] = $value; $this->_values[$name] = $value;
} }
...@@ -859,15 +855,11 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -859,15 +855,11 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* *
* @return Doctrine_Record * @return Doctrine_Record
*/ */
public function set($name, $value, $load = true) public function set($fieldName, $value, $load = true)
{ {
$lower = strtolower($name); if (isset($this->_data[$fieldName])) {
$lower = $this->_table->getColumnName($lower);
if (isset($this->_data[$lower])) {
if ($value instanceof Doctrine_Record) { if ($value instanceof Doctrine_Record) {
$type = $this->_table->getTypeOf($name); $type = $this->_table->getTypeOf($fieldName);
$id = $value->getIncremented(); $id = $value->getIncremented();
...@@ -877,9 +869,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -877,9 +869,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
if ($load) { if ($load) {
$old = $this->get($lower, $load); $old = $this->get($fieldName, $load);
} else { } else {
$old = $this->_data[$lower]; $old = $this->_data[$fieldName];
} }
if ($old !== $value) { if ($old !== $value) {
...@@ -887,8 +879,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -887,8 +879,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$value = self::$_null; $value = self::$_null;
} }
$this->_data[$lower] = $value; $this->_data[$fieldName] = $value;
$this->_modified[] = $lower; $this->_modified[] = $fieldName;
switch ($this->_state) { switch ($this->_state) {
case Doctrine_Record::STATE_CLEAN: case Doctrine_Record::STATE_CLEAN:
$this->_state = Doctrine_Record::STATE_DIRTY; $this->_state = Doctrine_Record::STATE_DIRTY;
...@@ -900,17 +892,21 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -900,17 +892,21 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
} else { } else {
try { try {
$this->coreSetRelated($name, $value); $this->coreSetRelated($fieldName, $value);
} catch(Doctrine_Table_Exception $e) { } catch (Doctrine_Table_Exception $e) {
foreach ($this->_table->getFilters() as $filter) { foreach ($this->_table->getFilters() as $filter) {
if (($value = $filter->filterSet($this, $name, $value)) !== null) { if (($value = $filter->filterSet($this, $fieldName, $value)) !== null) {
return $value; return $value;
} }
} }
} }
} }
} }
/**
* DESCRIBE WHAT THIS METHOD DOES, PLEASE!
* @todo Refactor. What about composite keys?
*/
public function coreSetRelated($name, $value) public function coreSetRelated($name, $value)
{ {
$rel = $this->_table->getRelation($name); $rel = $this->_table->getRelation($name);
...@@ -929,23 +925,27 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -929,23 +925,27 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
} else { } else {
if ($value !== self::$_null) { if ($value !== self::$_null) {
$relatedTable = $value->getTable();
$foreignFieldName = $relatedTable->getFieldName($rel->getForeign());
$localFieldName = $this->_table->getFieldName($rel->getLocal());
// one-to-one relation found // one-to-one relation found
if ( ! ($value instanceof Doctrine_Record)) { if ( ! ($value instanceof Doctrine_Record)) {
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record or Doctrine_Null when setting one-to-one references."); throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Record or Doctrine_Null when setting one-to-one references.");
} }
if ($rel instanceof Doctrine_Relation_LocalKey) { if ($rel instanceof Doctrine_Relation_LocalKey) {
$foreign = $rel->getForeign(); if ( ! empty($foreignFieldName) && $foreignFieldName != $value->getTable()->getIdentifier()) {
if ( ! empty($foreign) && $foreign != $value->getTable()->getIdentifier()) $this->set($localFieldName, $value->rawGet($foreignFieldName), false);
$this->set($rel->getLocal(), $value->rawGet($foreign), false); } else {
else $this->set($localFieldName, $value, false);
$this->set($rel->getLocal(), $value, false); }
} else { } else {
$value->set($rel->getForeign(), $this, false); $value->set($foreignFieldName, $this, false);
} }
} }
} }
} elseif ($rel instanceof Doctrine_Relation_Association) { } else if ($rel instanceof Doctrine_Relation_Association) {
// join table relation found // join table relation found
if ( ! ($value instanceof Doctrine_Collection)) { if ( ! ($value instanceof Doctrine_Collection)) {
throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting many-to-many references."); throw new Doctrine_Record_Exception("Couldn't call Doctrine::set(), second argument should be an instance of Doctrine_Collection when setting many-to-many references.");
...@@ -961,21 +961,19 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -961,21 +961,19 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* @param string $name * @param string $name
* @return boolean * @return boolean
*/ */
public function contains($name) public function contains($fieldName)
{ {
$lower = strtolower($name); if (isset($this->_data[$fieldName])) {
if (isset($this->_data[$lower])) {
return true; return true;
} }
if (isset($this->_id[$lower])) { if (isset($this->_id[$fieldName])) {
return true; return true;
} }
if (isset($this->_values[$lower])) { if (isset($this->_values[$fieldName])) {
return true; return true;
} }
if (isset($this->_references[$name]) && if (isset($this->_references[$fieldName]) &&
$this->_references[$name] !== self::$_null) { $this->_references[$fieldName] !== self::$_null) {
return true; return true;
} }
...@@ -986,10 +984,10 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -986,10 +984,10 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* @param string $name * @param string $name
* @return void * @return void
*/ */
public function __unset($name) public function __unset($fieldName)
{ {
if (isset($this->_data[$name])) { if (isset($this->_data[$fieldName])) {
$this->_data[$name] = array(); $this->_data[$fieldName] = array();
} }
// todo: what to do with references ? // todo: what to do with references ?
} }
...@@ -1054,12 +1052,13 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1054,12 +1052,13 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$conn = $this->_table->getConnection(); $conn = $this->_table->getConnection();
} }
return $conn->replace($this->_table->getTableName(), $this->getPrepared(), $this->_id); return $conn->replace($this->_table, $this->getPrepared(), $this->_id);
} }
/** /**
* returns an array of modified fields and associated values * returns an array of modified fields and associated values
* @return array * @return array
* @todo What about a better name? getModifiedFields?
*/ */
public function getModified() public function getModified()
{ {
...@@ -1071,6 +1070,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1071,6 +1070,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
return $a; return $a;
} }
/**
* REDUNDANT?
*/
public function modifiedFields() public function modifiedFields()
{ {
$a = array(); $a = array();
...@@ -1089,40 +1091,41 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1089,40 +1091,41 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* *
* @param array $array * @param array $array
* @return array * @return array
* @todo What about a little bit more expressive name? getPreparedData?
*/ */
public function getPrepared(array $array = array()) public function getPrepared(array $array = array())
{ {
$a = array(); $a = array();
if (empty($array)) { if (empty($array)) {
$array = $this->_modified; $modifiedFields = $this->_modified;
} }
foreach ($array as $k => $v) { foreach ($modifiedFields as $field) {
$type = $this->_table->getTypeOf($v); $type = $this->_table->getTypeOf($field);
if ($this->_data[$v] === self::$_null) { if ($this->_data[$field] === self::$_null) {
$a[$v] = null; $a[$field] = null;
continue; continue;
} }
switch ($type) { switch ($type) {
case 'array': case 'array':
case 'object': case 'object':
$a[$v] = serialize($this->_data[$v]); $a[$field] = serialize($this->_data[$field]);
break; break;
case 'gzip': case 'gzip':
$a[$v] = gzcompress($this->_data[$v],5); $a[$field] = gzcompress($this->_data[$field],5);
break; break;
case 'boolean': case 'boolean':
$a[$v] = $this->getTable()->getConnection()->convertBooleans($this->_data[$v]); $a[$field] = $this->getTable()->getConnection()->convertBooleans($this->_data[$field]);
break; break;
case 'enum': case 'enum':
$a[$v] = $this->_table->enumIndex($v, $this->_data[$v]); $a[$field] = $this->_table->enumIndex($field, $this->_data[$field]);
break; break;
default: default:
if ($this->_data[$v] instanceof Doctrine_Record) { if ($this->_data[$field] instanceof Doctrine_Record) {
$this->_data[$v] = $this->_data[$v]->getIncremented(); $this->_data[$field] = $this->_data[$field]->getIncremented();
} }
/** TODO: /** TODO:
if ($this->_data[$v] === null) { if ($this->_data[$v] === null) {
...@@ -1130,7 +1133,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1130,7 +1133,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
} }
*/ */
$a[$v] = $this->_data[$v]; $a[$field] = $this->_data[$field];
} }
} }
$map = $this->_table->inheritanceMap; $map = $this->_table->inheritanceMap;
...@@ -1255,12 +1258,12 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1255,12 +1258,12 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* @param mixed $name name of the property or reference * @param mixed $name name of the property or reference
* @return boolean * @return boolean
*/ */
public function hasRelation($name) public function hasRelation($fieldName)
{ {
if (isset($this->_data[$name]) || isset($this->_id[$name])) { if (isset($this->_data[$fieldName]) || isset($this->_id[$fieldName])) {
return true; return true;
} }
return $this->_table->hasRelation($name); return $this->_table->hasRelation($fieldName);
} }
/** /**
...@@ -1311,8 +1314,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1311,8 +1314,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
if ( ! ($val instanceof Doctrine_Null)) { if ( ! ($val instanceof Doctrine_Null)) {
$ret->_modified[] = $key; $ret->_modified[] = $key;
} }
} }
return $ret; return $ret;
} }
...@@ -1356,7 +1358,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1356,7 +1358,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->_state = Doctrine_Record::STATE_CLEAN; $this->_state = Doctrine_Record::STATE_CLEAN;
$this->_modified = array(); $this->_modified = array();
} else { } else {
$name = $this->_table->getIdentifier(); $name = $this->_table->getIdentifier();
$this->_id[$name] = $id; $this->_id[$name] = $id;
$this->_data[$name] = $id; $this->_data[$name] = $id;
$this->_state = Doctrine_Record::STATE_CLEAN; $this->_state = Doctrine_Record::STATE_CLEAN;
...@@ -1481,12 +1483,12 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1481,12 +1483,12 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/ */
public function merge(array $values) public function merge(array $values)
{ {
foreach ($this->_table->getColumnNames() as $value) { foreach ($this->_table->getFieldNames() as $fieldName) {
try { try {
if (isset($values[$value])) { if (isset($values[$fieldName])) {
$this->set($value, $values[$value]); $this->set($fieldName, $values[$fieldName]);
} }
} catch(Doctrine_Exception $e) { } catch (Doctrine_Exception $e) {
// silence all exceptions // silence all exceptions
} }
} }
...@@ -1506,12 +1508,12 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1506,12 +1508,12 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
array_shift($args); array_shift($args);
if (isset($args[0])) { if (isset($args[0])) {
$column = $args[0]; $fieldName = $args[0];
$args[0] = $this->get($column); $args[0] = $this->get($fieldName);
$newvalue = call_user_func_array($callback, $args); $newvalue = call_user_func_array($callback, $args);
$this->_data[$column] = $newvalue; $this->_data[$fieldName] = $newvalue;
} }
return $this; return $this;
} }
...@@ -1592,8 +1594,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count ...@@ -1592,8 +1594,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$q->execute(); $q->execute();
} else if ($rel instanceof Doctrine_Relation_ForeignKey) {
} elseif ($rel instanceof Doctrine_Relation_ForeignKey) {
$q->update($rel->getTable()->getComponentName()) $q->update($rel->getTable()->getComponentName())
->set($rel->getForeign(), '?', array(null)) ->set($rel->getForeign(), '?', array(null))
->addWhere($rel->getForeign() . ' = ?', array_values($this->identifier())); ->addWhere($rel->getForeign() . ' = ?', array_values($this->identifier()));
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
* @version $Revision: 1397 $ * @version $Revision: 1397 $
* @link www.phpdoctrine.com * @link www.phpdoctrine.com
* @since 1.0 * @since 1.0
* @todo Composite key support?
*/ */
class Doctrine_Relation_Parser class Doctrine_Relation_Parser
{ {
...@@ -103,11 +104,12 @@ class Doctrine_Relation_Parser ...@@ -103,11 +104,12 @@ class Doctrine_Relation_Parser
unset($this->relations[$name]); unset($this->relations[$name]);
} }
/* looks like old code?
$lower = strtolower($name); $lower = strtolower($name);
if ($this->_table->hasColumn($lower)) { if ($this->_table->hasColumn($lower)) {
throw new Doctrine_Relation_Exception("Couldn't bind relation. Column with name " . $lower . ' already exists!'); throw new Doctrine_Relation_Exception("Couldn't bind relation. Column with name " . $lower . ' already exists!');
} }
*/
$e = explode(' as ', $name); $e = explode(' as ', $name);
$name = $e[0]; $name = $e[0];
...@@ -145,6 +147,8 @@ class Doctrine_Relation_Parser ...@@ -145,6 +147,8 @@ class Doctrine_Relation_Parser
if (isset($this->_pending[$alias])) { if (isset($this->_pending[$alias])) {
$def = $this->_pending[$alias]; $def = $this->_pending[$alias];
$identifierColumnNames = $this->_table->getIdentifierColumnNames();
$idColumnName = array_pop($identifierColumnNames);
// check if reference class name exists // check if reference class name exists
// if it does we are dealing with association relation // if it does we are dealing with association relation
...@@ -160,7 +164,7 @@ class Doctrine_Relation_Parser ...@@ -160,7 +164,7 @@ class Doctrine_Relation_Parser
$parser->bind($this->_table->getComponentName(), $parser->bind($this->_table->getComponentName(),
array('type' => Doctrine_Relation::ONE, array('type' => Doctrine_Relation::ONE,
'local' => $def['local'], 'local' => $def['local'],
'foreign' => $this->_table->getIdentifier(), 'foreign' => $idColumnName,
'localKey' => true, 'localKey' => true,
)); ));
} }
...@@ -168,7 +172,7 @@ class Doctrine_Relation_Parser ...@@ -168,7 +172,7 @@ class Doctrine_Relation_Parser
if ( ! $this->hasRelation($def['refClass'])) { if ( ! $this->hasRelation($def['refClass'])) {
$this->bind($def['refClass'], array('type' => Doctrine_Relation::MANY, $this->bind($def['refClass'], array('type' => Doctrine_Relation::MANY,
'foreign' => $def['local'], 'foreign' => $def['local'],
'local' => $this->_table->getIdentifier())); 'local' => $idColumnName));
} }
} }
if (in_array($def['class'], $localClasses)) { if (in_array($def['class'], $localClasses)) {
...@@ -181,7 +185,6 @@ class Doctrine_Relation_Parser ...@@ -181,7 +185,6 @@ class Doctrine_Relation_Parser
$def = $this->completeDefinition($def); $def = $this->completeDefinition($def);
if (isset($def['localKey'])) { if (isset($def['localKey'])) {
$rel = new Doctrine_Relation_LocalKey($def); $rel = new Doctrine_Relation_LocalKey($def);
} else { } else {
$rel = new Doctrine_Relation_ForeignKey($def); $rel = new Doctrine_Relation_ForeignKey($def);
...@@ -257,7 +260,7 @@ class Doctrine_Relation_Parser ...@@ -257,7 +260,7 @@ class Doctrine_Relation_Parser
$def['class'] = $def['table']->getComponentName(); $def['class'] = $def['table']->getComponentName();
$def['refTable'] = $this->getImpl($def['refClass']); $def['refTable'] = $this->getImpl($def['refClass']);
$id = $def['refTable']->getIdentifier(); $id = $def['refTable']->getIdentifierColumnNames();
if (count($id) > 1) { if (count($id) > 1) {
if ( ! isset($def['foreign'])) { if ( ! isset($def['foreign'])) {
...@@ -304,15 +307,15 @@ class Doctrine_Relation_Parser ...@@ -304,15 +307,15 @@ class Doctrine_Relation_Parser
*/ */
public function getIdentifiers(Doctrine_Table $table) public function getIdentifiers(Doctrine_Table $table)
{ {
$componentNameToLower = strtolower($table->getComponentName());
if (is_array($table->getIdentifier())) { if (is_array($table->getIdentifier())) {
$columns = array(); $columns = array();
foreach((array) $table->getIdentifier() as $identifier) { foreach ((array) $table->getIdentifierColumnNames() as $identColName) {
$columns[] = strtolower($table->getComponentName()) $columns[] = $componentNameToLower . '_' . $identColName;
. '_' . $table->getIdentifier();
} }
} else { } else {
$columns = strtolower($table->getComponentName()) $columns = $componentNameToLower . '_' . $table->getColumnName(
. '_' . $table->getIdentifier(); $table->getIdentifier());
} }
return $columns; return $columns;
...@@ -361,6 +364,8 @@ class Doctrine_Relation_Parser ...@@ -361,6 +364,8 @@ class Doctrine_Relation_Parser
* *
* @param array $def definition array to be completed * @param array $def definition array to be completed
* @return array completed definition array * @return array completed definition array
* @todo Description: What does it mean to complete a definition? What is done (not how)?
* Refactor (too long & nesting level)
*/ */
public function completeDefinition($def) public function completeDefinition($def)
{ {
...@@ -371,21 +376,26 @@ class Doctrine_Relation_Parser ...@@ -371,21 +376,26 @@ class Doctrine_Relation_Parser
$foreignClasses = array_merge($def['table']->getOption('parents'), array($def['class'])); $foreignClasses = array_merge($def['table']->getOption('parents'), array($def['class']));
$localClasses = array_merge($this->_table->getOption('parents'), array($this->_table->getComponentName())); $localClasses = array_merge($this->_table->getOption('parents'), array($this->_table->getComponentName()));
$localIdentifierColumnNames = $this->_table->getIdentifierColumnNames();
$localIdColumnName = array_pop($localIdentifierColumnNames);
$foreignIdentifierColumnNames = $def['table']->getIdentifierColumnNames();
$foreignIdColumnName = array_pop($foreignIdentifierColumnNames);
if (isset($def['local'])) { if (isset($def['local'])) {
if ( ! isset($def['foreign'])) { if ( ! isset($def['foreign'])) {
// local key is set, but foreign key is not // local key is set, but foreign key is not
// try to guess the foreign key // try to guess the foreign key
if ($def['local'] === $this->_table->getIdentifier()) { if ($def['local'] === $localIdColumnName) {
$def['foreign'] = $this->guessColumns($localClasses, $def['table']); $def['foreign'] = $this->guessColumns($localClasses, $def['table']);
} else { } else {
// the foreign field is likely to be the // the foreign field is likely to be the
// identifier of the foreign class // identifier of the foreign class
$def['foreign'] = $def['table']->getIdentifier(); $def['foreign'] = $foreignIdColumnName;
$def['localKey'] = true; $def['localKey'] = true;
} }
} else { } else {
if ($def['local'] !== $this->_table->getIdentifier() && if ($def['local'] !== $localIdColumnName &&
$def['type'] == Doctrine_Relation::ONE) { $def['type'] == Doctrine_Relation::ONE) {
$def['localKey'] = true; $def['localKey'] = true;
} }
...@@ -394,15 +404,15 @@ class Doctrine_Relation_Parser ...@@ -394,15 +404,15 @@ class Doctrine_Relation_Parser
if (isset($def['foreign'])) { if (isset($def['foreign'])) {
// local key not set, but foreign key is set // local key not set, but foreign key is set
// try to guess the local key // try to guess the local key
if ($def['foreign'] === $def['table']->getIdentifier()) { if ($def['foreign'] === $foreignIdColumnName) {
$def['localKey'] = true; $def['localKey'] = true;
try { try {
$def['local'] = $this->guessColumns($foreignClasses, $this->_table); $def['local'] = $this->guessColumns($foreignClasses, $this->_table);
} catch (Doctrine_Relation_Exception $e) { } catch (Doctrine_Relation_Exception $e) {
$def['local'] = $this->_table->getIdentifier(); $def['local'] = $localIdColumnName;
} }
} else { } else {
$def['local'] = $this->_table->getIdentifier(); $def['local'] = $localIdColumnName;
} }
} else { } else {
// neither local or foreign key is being set // neither local or foreign key is being set
...@@ -412,16 +422,17 @@ class Doctrine_Relation_Parser ...@@ -412,16 +422,17 @@ class Doctrine_Relation_Parser
// the following loops are needed for covering inheritance // the following loops are needed for covering inheritance
foreach ($localClasses as $class) { foreach ($localClasses as $class) {
$table = $conn->getTable($class); $table = $conn->getTable($class);
$identifierColumnNames = $table->getIdentifierColumnNames();
$idColumnName = array_pop($identifierColumnNames);
$column = strtolower($table->getComponentName()) $column = strtolower($table->getComponentName())
. '_' . $table->getIdentifier(); . '_' . $idColumnName;
foreach ($foreignClasses as $class2) { foreach ($foreignClasses as $class2) {
$table2 = $conn->getTable($class2); $table2 = $conn->getTable($class2);
if ($table2->hasColumn($column)) { if ($table2->hasColumn($column)) {
$def['foreign'] = $column; $def['foreign'] = $column;
$def['local'] = $table->getIdentifier(); $def['local'] = $idColumnName;
return $def; return $def;
} }
} }
...@@ -429,13 +440,15 @@ class Doctrine_Relation_Parser ...@@ -429,13 +440,15 @@ class Doctrine_Relation_Parser
foreach ($foreignClasses as $class) { foreach ($foreignClasses as $class) {
$table = $conn->getTable($class); $table = $conn->getTable($class);
$identifierColumnNames = $table->getIdentifierColumnNames();
$idColumnName = array_pop($identifierColumnNames);
$column = strtolower($table->getComponentName()) $column = strtolower($table->getComponentName())
. '_' . $table->getIdentifier(); . '_' . $idColumnName;
foreach ($localClasses as $class2) { foreach ($localClasses as $class2) {
$table2 = $conn->getTable($class2); $table2 = $conn->getTable($class2);
if ($table2->hasColumn($column)) { if ($table2->hasColumn($column)) {
$def['foreign'] = $table->getIdentifier(); $def['foreign'] = $idColumnName;
$def['local'] = $column; $def['local'] = $column;
$def['localKey'] = true; $def['localKey'] = true;
return $def; return $def;
...@@ -445,11 +458,12 @@ class Doctrine_Relation_Parser ...@@ -445,11 +458,12 @@ class Doctrine_Relation_Parser
// auto-add columns and auto-build relation // auto-add columns and auto-build relation
$columns = array(); $columns = array();
foreach ((array) $this->_table->getIdentifier() as $id) { foreach ((array) $this->_table->getIdentifierColumnNames() as $id) {
// ?? should this not be $this->_table->getComponentName() ??
$column = strtolower($table->getComponentName()) $column = strtolower($table->getComponentName())
. '_' . $id; . '_' . $id;
$col = $this->_table->getDefinitionOf($id); $col = $this->_table->getColumnDefinition($id);
$type = $col['type']; $type = $col['type'];
$length = $col['length']; $length = $col['length'];
...@@ -468,7 +482,7 @@ class Doctrine_Relation_Parser ...@@ -468,7 +482,7 @@ class Doctrine_Relation_Parser
} else { } else {
$def['foreign'] = $columns[0]; $def['foreign'] = $columns[0];
} }
$def['local'] = $this->_table->getIdentifier(); $def['local'] = $localIdColumnName;
} }
} }
return $def; return $def;
......
...@@ -40,9 +40,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -40,9 +40,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
protected $_data = array(); protected $_data = array();
/** /**
* @var mixed $identifier * @var mixed $identifier The field names of all fields that are part of the identifier/primary key
*/ */
protected $_identifier; protected $_identifier = array();
/** /**
* @see Doctrine_Identifier constants * @see Doctrine_Identifier constants
...@@ -67,7 +67,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -67,7 +67,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
/** /**
* @var array $columns an array of column definitions, * @var array $columns an array of column definitions,
* keys as column names and values as column definitions * keys are column names and values are column definitions
* *
* the definition array has atleast the following values: * the definition array has atleast the following values:
* *
...@@ -83,10 +83,20 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -83,10 +83,20 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
protected $_columns = array(); protected $_columns = array();
/** /**
* @var array $columnAliases an array of column aliases * @var array $_fieldNames an array of field names. used to look up field names
* keys as column aliases and values as column names * from column names.
* keys are column names and values are field names
*/ */
protected $_columnAliases = array(); protected $_fieldNames = array();
/**
*
* @var array $_columnNames an array of column names
* keys are field names and values column names.
* used to look up column names from field names.
* this is the reverse lookup map of $_fieldNames.
*/
protected $_columnNames = array();
/** /**
* @var integer $columnCount cached column count, Doctrine_Record uses this column count in when * @var integer $columnCount cached column count, Doctrine_Record uses this column count in when
...@@ -202,7 +212,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -202,7 +212,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$this->_parser = new Doctrine_Relation_Parser($this); $this->_parser = new Doctrine_Relation_Parser($this);
if ($initDefinition) { if ($initDefinition) {
$record = $this->initDefinition($name); $record = $this->initDefinition();
$this->initIdentifier(); $this->initIdentifier();
...@@ -216,8 +226,15 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -216,8 +226,15 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$this->_filters[] = new Doctrine_Record_Filter_Standard(); $this->_filters[] = new Doctrine_Record_Filter_Standard();
$this->_repository = new Doctrine_Table_Repository($this); $this->_repository = new Doctrine_Table_Repository($this);
} }
public function initDefinition($name)
{ /**
* Initializes the in-memory table definition.
*
* @param string $name
*/
public function initDefinition()
{
$name = $this->_options['name'];
if ( ! class_exists($name) || empty($name)) { if ( ! class_exists($name) || empty($name)) {
throw new Doctrine_Exception("Couldn't find class " . $name); throw new Doctrine_Exception("Couldn't find class " . $name);
} }
...@@ -253,15 +270,16 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -253,15 +270,16 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$record->setTableDefinition(); $record->setTableDefinition();
// get the declaring class of setTableDefinition method // get the declaring class of setTableDefinition method
$method = new ReflectionMethod($this->_options['name'], 'setTableDefinition'); $method = new ReflectionMethod($this->_options['name'], 'setTableDefinition');
$class = $method->getDeclaringClass(); $class = $method->getDeclaringClass();
} else { } else {
$class = new ReflectionClass($class); $class = new ReflectionClass($class);
} }
$this->_options['joinedParents'] = array(); $this->_options['joinedParents'] = array();
foreach (array_reverse($this->_options['parents']) as $parent) { foreach (array_reverse($this->_options['parents']) as $parent) {
if ($parent === $class->getName()) { if ($parent === $class->getName()) {
continue; continue;
} }
...@@ -270,25 +288,25 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -270,25 +288,25 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
if ($ref->isAbstract()) { if ($ref->isAbstract()) {
continue; continue;
} }
$table = $this->_conn->getTable($parent); $parentTable = $this->_conn->getTable($parent);
$found = false; $found = false;
$columns = $table->getColumns(); $parentColumns = $parentTable->getColumns();
foreach ($columns as $column => $definition) { foreach ($parentColumns as $columnName => $definition) {
if ( ! isset($definition['primary'])) { if ( ! isset($definition['primary'])) {
if (isset($this->_columns[$column])) { if (isset($this->_columns[$columnName])) {
$found = true; $found = true;
break; break;
} else { } else {
if ( ! isset($columns[$column]['owner'])) { if ( ! isset($parentColumns[$columnName]['owner'])) {
$columns[$column]['owner'] = $table->getComponentName(); $parentColumns[$columnName]['owner'] = $parentTable->getComponentName();
} }
$this->_options['joinedParents'][] = $columns[$column]['owner']; $this->_options['joinedParents'][] = $parentColumns[$columnName]['owner'];
} }
} else { } else {
unset($columns[$column]); unset($parentColumns[$columnName]);
} }
} }
...@@ -296,7 +314,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -296,7 +314,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
continue; continue;
} }
$this->_columns = array_merge($columns, $this->_columns); foreach ($parentColumns as $columnName => $definition) {
$fullName = $columnName . ' as ' . $parentTable->getFieldName($columnName);
$this->setColumn($fullName, $definition['type'], $definition['length'], $definition, true);
}
break; break;
} }
...@@ -318,6 +339,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -318,6 +339,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
return $record; return $record;
} }
/**
* Initializes the table identifier(s)/primary key(s)
*
*/
public function initIdentifier() public function initIdentifier()
{ {
switch (count($this->_identifier)) { switch (count($this->_identifier)) {
...@@ -342,15 +368,16 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -342,15 +368,16 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
unset($definition['sequence']); unset($definition['sequence']);
// add the inherited primary key column // add the inherited primary key column
$this->_columns = array_merge(array($id => $definition), $this->_columns); $fullName = $id . ' as ' . $table->getFieldName($id);
$this->setColumn($fullName, $definition['type'], $definition['length'],
$definition, true);
} }
} else { } else {
$this->_columns = array_merge(array('id' => $definition = array('type' => 'integer',
array('type' => 'integer', 'length' => 20,
'length' => 20, 'autoincrement' => true,
'autoincrement' => true, 'primary' => true);
'primary' => true)), $this->_columns); $this->setColumn('id', $definition['type'], $definition['length'], $definition, true);
$this->_identifier = 'id'; $this->_identifier = 'id';
$this->_identifierType = Doctrine::IDENTIFIER_AUTOINC; $this->_identifierType = Doctrine::IDENTIFIER_AUTOINC;
} }
...@@ -358,7 +385,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -358,7 +385,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
break; break;
case 1: case 1:
foreach ($this->_identifier as $pk) { foreach ($this->_identifier as $pk) {
$e = $this->_columns[$pk]; $columnName = $this->getColumnName($pk);
$e = $this->_columns[$columnName];
$found = false; $found = false;
...@@ -404,25 +432,46 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -404,25 +432,46 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$this->_identifierType = Doctrine::IDENTIFIER_COMPOSITE; $this->_identifierType = Doctrine::IDENTIFIER_COMPOSITE;
} }
} }
public function getColumnOwner($column) /**
* Gets the owner of a column.
* The owner of a column is the name of the component in a hierarchy that
* defines the column.
*
* @param string $columnName The column name
* @return string The name of the owning/defining component
*/
public function getColumnOwner($columnName)
{ {
if (isset($this->_columns[$column]['owner'])) { if (isset($this->_columns[$columnName]['owner'])) {
return $this->_columns[$column]['owner']; return $this->_columns[$columnName]['owner'];
} else { } else {
return $this->getComponentName(); return $this->getComponentName();
} }
} }
public function isInheritedColumn($column) /**
* Checks whether a column is inherited from a component further up in the hierarchy.
*
* @param $columnName The column name
* @return boolean TRUE if column is inherited, FALSE otherwise.
*/
public function isInheritedColumn($columnName)
{ {
return (isset($this->_columns[$column]['owner'])); return (isset($this->_columns[$columnName]['owner']));
} }
public function isIdentifier($identifier) /**
* Checks whether a field is part of the table identifier/primary key field(s).
*
* @param string $fieldName The field name
* @return boolean TRUE if the field is part of the table identifier/primary key field(s),
* FALSE otherwise.
*/
public function isIdentifier($fieldName)
{ {
return ($identifier === $this->_identifier || return ($fieldName === $this->getIdentifier() ||
in_array($identifier, (array) $this->_identifier)); in_array($fieldName, (array) $this->getIdentifier()));
} }
public function getMethodOwner($method) public function getMethodOwner($method)
...@@ -472,10 +521,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -472,10 +521,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$columns = array(); $columns = array();
$primary = array(); $primary = array();
foreach ($this->getColumns() as $name => $column) { foreach ($this->getColumns() as $name => $definition) {
$definition = $column;
if (isset($column['owner'])) { if (isset($definition['owner'])) {
continue; continue;
} }
...@@ -499,52 +547,50 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -499,52 +547,50 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
} }
$options['foreignKeys'] = array(); $options['foreignKeys'] = array();
if ($parseForeignKeys) {
if ($this->getAttribute(Doctrine::ATTR_EXPORT) & Doctrine::EXPORT_CONSTRAINTS) {
$constraints = array(); if ($parseForeignKeys && $this->getAttribute(Doctrine::ATTR_EXPORT)
& Doctrine::EXPORT_CONSTRAINTS) {
$emptyIntegrity = array('onUpdate' => null, $constraints = array();
'onDelete' => null);
foreach ($this->getRelations() as $name => $relation) { $emptyIntegrity = array('onUpdate' => null,
$fk = $relation->toArray(); 'onDelete' => null);
$fk['foreignTable'] = $relation->getTable()->getTableName();
if ($relation->getTable() === $this && in_array($relation->getLocal(), $primary)) { foreach ($this->getRelations() as $name => $relation) {
if ($relation->hasConstraint()) { $fk = $relation->toArray();
throw new Doctrine_Table_Exception("Badly constructed integrity constraints."); $fk['foreignTable'] = $relation->getTable()->getTableName();
}
continue; if ($relation->getTable() === $this && in_array($relation->getLocal(), $primary)) {
if ($relation->hasConstraint()) {
throw new Doctrine_Table_Exception("Badly constructed integrity constraints.");
} }
continue;
}
$integrity = array('onUpdate' => $fk['onUpdate'], $integrity = array('onUpdate' => $fk['onUpdate'],
'onDelete' => $fk['onDelete']); 'onDelete' => $fk['onDelete']);
if ($relation instanceof Doctrine_Relation_LocalKey) {
$def = array('local' => $relation->getLocal(),
'foreign' => $relation->getForeign(),
'foreignTable' => $relation->getTable()->getTableName());
if (($key = array_search($def, $options['foreignKeys'])) === false) { if ($relation instanceof Doctrine_Relation_LocalKey) {
$options['foreignKeys'][] = $def; $def = array('local' => $relation->getLocal(),
'foreign' => $relation->getForeign(),
'foreignTable' => $relation->getTable()->getTableName());
$constraints[] = $integrity; if (($key = array_search($def, $options['foreignKeys'])) === false) {
} else { $options['foreignKeys'][] = $def;
if ($integrity !== $emptyIntegrity) { $constraints[] = $integrity;
$constraints[$key] = $integrity; } else {
} if ($integrity !== $emptyIntegrity) {
$constraints[$key] = $integrity;
} }
} }
} }
}
foreach ($constraints as $k => $def) { foreach ($constraints as $k => $def) {
$options['foreignKeys'][$k] = array_merge($options['foreignKeys'][$k], $def); $options['foreignKeys'][$k] = array_merge($options['foreignKeys'][$k], $def);
}
} }
} }
$options['primary'] = $primary; $options['primary'] = $primary;
return array('tableName' => $this->getOption('tableName'), return array('tableName' => $this->getOption('tableName'),
...@@ -568,9 +614,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -568,9 +614,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$this->_conn->export->createIndex($this->_options['tableName'], $index, $definition); $this->_conn->export->createIndex($this->_options['tableName'], $index, $definition);
} }
$this->_conn->commit(); $this->_conn->commit();
} catch(Doctrine_Connection_Exception $e) { } catch (Doctrine_Connection_Exception $e) {
$this->_conn->rollback(); $this->_conn->rollback();
throw $e; throw $e;
} }
} }
...@@ -676,6 +721,12 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -676,6 +721,12 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
return false; return false;
} }
/**
* DESCRIBE WHAT THIS METHOD DOES, PLEASE!
*
* @todo Name proposal: addRelation
*/
public function bind($args, $type) public function bind($args, $type)
{ {
$options = array(); $options = array();
...@@ -833,14 +884,41 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -833,14 +884,41 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @param string $alias column alias * @param string $alias column alias
* @return string column name * @return string column name
*/ */
public function getColumnName($alias) public function getColumnName($fieldName)
{ {
$alias = strtolower($alias); if (isset($this->_columnNames[$fieldName])) {
if (isset($this->_columnAliases[$alias])) { return $this->_columnNames[$fieldName];
return $this->_columnAliases[$alias];
} }
return $fieldName;
return $alias; }
/**
*
*
*/
public function getColumnDefinition($columnName)
{
if ( ! isset($this->_columns[$columnName])) {
return false;
}
return $this->_columns[$columnName];
}
/**
* getColumnAlias
*
* returns a column alias for a column name
* if no alias can be found the column name is returned.
*
* @param string $columnName column name
* @return string column alias
*/
public function getFieldName($columnName)
{
if (isset($this->_fieldNames[$columnName])) {
return $this->_fieldNames[$columnName];
}
return $columnName;
} }
/** /**
...@@ -850,10 +928,12 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -850,10 +928,12 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @param string $type * @param string $type
* @param integer $length * @param integer $length
* @param mixed $options * @param mixed $options
* @param boolean $prepend Whether to prepend or append the new column to the column list.
* By default the column gets appended.
* @throws Doctrine_Table_Exception if trying use wrongly typed parameter * @throws Doctrine_Table_Exception if trying use wrongly typed parameter
* @return void * @return void
*/ */
public function setColumn($name, $type, $length = null, $options = array()) public function setColumn($name, $type, $length = null, $options = array(), $prepend = false)
{ {
if (is_string($options)) { if (is_string($options)) {
$options = explode('|', $options); $options = explode('|', $options);
...@@ -867,16 +947,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -867,16 +947,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
unset($options[$k]); unset($options[$k]);
} }
} }
$name = strtolower($name); // extract column name & field name
$parts = explode(' as ', $name); $parts = explode(' as ', $name);
if (count($parts) > 1) { if (count($parts) > 1) {
$this->_columnAliases[$parts[1]] = $parts[0]; $fieldName = $parts[1];
$name = $parts[0]; } else {
$fieldName = $parts[0];
} }
$name = strtolower($parts[0]);
$this->_columnNames[$fieldName] = $name;
$this->_fieldNames[$name] = $fieldName;
if ($length == null) { if ($length == null) {
switch ($type) { switch ($type) {
...@@ -905,13 +986,23 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -905,13 +986,23 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
break; break;
} }
} }
$this->_columns[$name] = $options; $options['type'] = $type;
$this->_columns[$name]['type'] = $type; $options['length'] = $length;
$this->_columns[$name]['length'] = $length;
if ($prepend) {
$this->_columns = array_merge(array($name => $options), $this->_columns);
} else {
$this->_columns[$name] = $options;
}
if (isset($options['primary'])) { if (isset($options['primary'])) {
$this->_identifier[] = $name; if (isset($this->_identifier)) {
$this->_identifier = (array) $this->_identifier;
}
if ( ! in_array($fieldName, $this->_identifier)) {
$this->_identifier[] = $fieldName;
}
} }
if (isset($options['default'])) { if (isset($options['default'])) {
$this->hasDefaultValues = true; $this->hasDefaultValues = true;
...@@ -933,17 +1024,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -933,17 +1024,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* getDefaultValueOf * getDefaultValueOf
* returns the default value(if any) for given column * returns the default value(if any) for given column
* *
* @param string $column * @param string $fieldName
* @return mixed * @return mixed
*/ */
public function getDefaultValueOf($column) public function getDefaultValueOf($fieldName)
{ {
$column = strtolower($column); $columnName = $this->getColumnName($fieldName);
if ( ! isset($this->_columns[$column])) { if ( ! isset($this->_columns[$columnName])) {
throw new Doctrine_Table_Exception("Couldn't get default value. Column ".$column." doesn't exist."); throw new Doctrine_Table_Exception("Couldn't get default value. Column ".$columnName." doesn't exist.");
} }
if (isset($this->_columns[$column]['default'])) { if (isset($this->_columns[$columnName]['default'])) {
return $this->_columns[$column]['default']; return $this->_columns[$columnName]['default'];
} else { } else {
return null; return null;
} }
...@@ -969,9 +1060,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -969,9 +1060,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* hasColumn * hasColumn
* @return boolean * @return boolean
*/ */
public function hasColumn($name) public function hasColumn($columnName)
{ {
return isset($this->_columns[$name]); return isset($this->_columns[$columnName]);
} }
/** /**
...@@ -1030,7 +1121,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1030,7 +1121,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$id = is_array($id) ? array_values($id) : array($id); $id = is_array($id) ? array_values($id) : array($id);
return $this->createQuery() return $this->createQuery()
->where(implode(' = ? AND ', (array) $this->_identifier) . ' = ?') ->where(implode(' = ? AND ', $this->getIdentifierColumnNames()) . ' = ?')
->fetchOne($id, $hydrationMode); ->fetchOne($id, $hydrationMode);
} }
...@@ -1111,6 +1202,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1111,6 +1202,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* clears the first level cache (identityMap) * clears the first level cache (identityMap)
* *
* @return void * @return void
* @todo what about a more descriptive name? clearIdentityMap?
*/ */
public function clear() public function clear()
{ {
...@@ -1167,29 +1259,27 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1167,29 +1259,27 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
public function getRecord() public function getRecord()
{ {
if ( ! empty($this->_data)) { if ( ! empty($this->_data)) {
$this->_data = array_change_key_case($this->_data, CASE_LOWER);
$key = $this->getIdentifier(); $identifierFieldNames = $this->getIdentifier();
if ( ! is_array($key)) { if ( ! is_array($identifierFieldNames)) {
$key = array($key); $identifierFieldNames = array($identifierFieldNames);
} }
$found = false; $found = false;
foreach ($key as $k) { foreach ($identifierFieldNames as $fieldName) {
if ( ! isset($this->_data[$k])) { if ( ! isset($this->_data[$fieldName])) {
// primary key column not found return new record // primary key column not found return new record
$found = true; $found = true;
break; break;
} }
$id[] = $this->_data[$k]; $id[] = $this->_data[$fieldName];
} }
if ($found) { if ($found) {
$recordName = $this->getClassnameToReturn(); $recordName = $this->getClassnameToReturn();
$record = new $recordName($this, true); $record = new $recordName($this, true);
$this->_data = array(); $this->_data = array();
return $record; return $record;
} }
...@@ -1210,7 +1300,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1210,7 +1300,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$record = new $recordName($this, true); $record = new $recordName($this, true);
} }
return $record; return $record;
} }
...@@ -1257,9 +1346,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1257,9 +1346,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
final public function getProxy($id = null) final public function getProxy($id = null)
{ {
if ($id !== null) { if ($id !== null) {
$query = 'SELECT ' . implode(', ', (array) $this->_identifier) $identifierColumnNames = $this->getIdentifierColumnNames();
$query = 'SELECT ' . implode(', ', (array) $identifierColumnNames)
. ' FROM ' . $this->getTableName() . ' FROM ' . $this->getTableName()
. ' WHERE ' . implode(' = ? && ', (array) $this->_identifier) . ' = ?'; . ' WHERE ' . implode(' = ? && ', (array) $identifierColumnNames) . ' = ?';
$query = $this->applyInheritance($query); $query = $this->applyInheritance($query);
$params = array_merge(array($id), array_values($this->_options['inheritanceMap'])); $params = array_merge(array($id), array_values($this->_options['inheritanceMap']));
...@@ -1282,7 +1372,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1282,7 +1372,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
if ( ! empty($this->_options['inheritanceMap'])) { if ( ! empty($this->_options['inheritanceMap'])) {
$a = array(); $a = array();
foreach ($this->_options['inheritanceMap'] as $field => $value) { foreach ($this->_options['inheritanceMap'] as $field => $value) {
$a[] = $field . ' = ?'; $a[] = $this->getColumnName($field) . ' = ?';
} }
$i = implode(' AND ', $a); $i = implode(' AND ', $a);
$where .= ' AND ' . $i; $where .= ' AND ' . $i;
...@@ -1302,7 +1392,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1302,7 +1392,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
} }
/** /**
* @return Doctrine_Query a Doctrine_Query object * @return Doctrine_Query a Doctrine_Query object
*/ */
public function getQueryObject() public function getQueryObject()
{ {
...@@ -1312,13 +1402,14 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1312,13 +1402,14 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
} }
/** /**
* @param string $field * @param string $fieldName
* @return array * @return array
*/ */
public function getEnumValues($field) public function getEnumValues($fieldName)
{ {
if (isset($this->_columns[$field]['values'])) { $columnName = $this->getColumnName($fieldName);
return $this->_columns[$field]['values']; if (isset($this->_columns[$columnName]['values'])) {
return $this->_columns[$columnName]['values'];
} else { } else {
return array(); return array();
} }
...@@ -1331,16 +1422,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1331,16 +1422,17 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @param integer $index * @param integer $index
* @return mixed * @return mixed
*/ */
public function enumValue($field, $index) public function enumValue($fieldName, $index)
{ {
if ($index instanceof Doctrine_Null) { if ($index instanceof Doctrine_Null) {
return $index; return $index;
} }
$columnName = $this->getColumnName($fieldName);
if ( ! $this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM) if ( ! $this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)
&& isset($this->_columns[$field]['values'][$index]) && isset($this->_columns[$columnName]['values'][$index])
) { ) {
return $this->_columns[$field]['values'][$index]; return $this->_columns[$columnName]['values'][$index];
} }
return $index; return $index;
...@@ -1353,9 +1445,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1353,9 +1445,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @param mixed $value * @param mixed $value
* @return mixed * @return mixed
*/ */
public function enumIndex($field, $value) public function enumIndex($fieldName, $value)
{ {
$values = $this->getEnumValues($field); $values = $this->getEnumValues($fieldName);
$index = array_search($value, $values); $index = array_search($value, $values);
if ($index === false || !$this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) { if ($index === false || !$this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) {
...@@ -1363,7 +1455,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1363,7 +1455,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
} }
return $value; return $value;
} }
/* getColumnCount
/**
* getColumnCount
* *
* @return integer the number of columns in this table * @return integer the number of columns in this table
*/ */
...@@ -1388,11 +1482,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1388,11 +1482,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* *
* @return boolean * @return boolean
*/ */
public function removeColumn($column) public function removeColumn($columnName)
{ {
if (isset($this->_columns[$column])) { if (isset($this->_columns[$columnName])) {
unset($this->_columns[$column]); unset($this->_columns[$columnName]);
return true; return true;
} }
...@@ -1400,13 +1493,41 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1400,13 +1493,41 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
} }
/** /**
* returns an array containing all the column names * returns an array containing all the column names.
* *
* @return array * @return array
*/ */
public function getColumnNames() public function getColumnNames(array $fieldNames = null)
{ {
return array_keys($this->_columns); if ($fieldNames === null) {
return array_keys($this->_columns);
} else {
$columnNames = array();
foreach ($fieldNames as $fieldName) {
$columnNames[] = $this->getColumnName($fieldName);
}
return $columnNames;
}
}
/**
* returns an array with all the identifier column names.
*
* @return array
*/
public function getIdentifierColumnNames()
{
return $this->getColumnNames((array) $this->getIdentifier());
}
/**
* returns an array containing all the field names.
*
* @return array
*/
public function getFieldNames()
{
return array_values($this->_fieldNames);
} }
/** /**
...@@ -1414,12 +1535,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1414,12 +1535,10 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* *
* @return mixed array on success, false on failure * @return mixed array on success, false on failure
*/ */
public function getDefinitionOf($column) public function getDefinitionOf($fieldName)
{ {
if (isset($this->_columns[$column])) { $columnName = $this->getColumnName($fieldName);
return $this->_columns[$column]; return $this->getColumnDefinition($columnName);
}
return false;
} }
/** /**
...@@ -1427,10 +1546,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1427,10 +1546,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* *
* @return mixed string on success, false on failure * @return mixed string on success, false on failure
*/ */
public function getTypeOf($column) public function getTypeOf($fieldName)
{ {
if (isset($this->_columns[$column])) { $columnName = $this->getColumnName($fieldName);
return $this->_columns[$column]['type']; if (isset($this->_columns[$columnName])) {
return $this->_columns[$columnName]['type'];
} }
return false; return false;
} }
...@@ -1482,14 +1602,14 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1482,14 +1602,14 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @param string $value field value * @param string $value field value
* @return mixed prepared value * @return mixed prepared value
*/ */
public function prepareValue($field, $value) public function prepareValue($fieldName, $value)
{ {
if ($value === self::$_null) { if ($value === self::$_null) {
return self::$_null; return self::$_null;
} elseif ($value === null) { } elseif ($value === null) {
return null; return null;
} else { } else {
$type = $this->getTypeOf($field); $type = $this->getTypeOf($fieldName);
switch ($type) { switch ($type) {
case 'array': case 'array':
...@@ -1498,7 +1618,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1498,7 +1618,7 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$value = unserialize($value); $value = unserialize($value);
if ($value === false) { if ($value === false) {
throw new Doctrine_Table_Exception('Unserialization of ' . $field . ' failed.'); throw new Doctrine_Table_Exception('Unserialization of ' . $fieldName . ' failed.');
} }
return $value; return $value;
} }
...@@ -1507,12 +1627,12 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1507,12 +1627,12 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
$value = gzuncompress($value); $value = gzuncompress($value);
if ($value === false) { if ($value === false) {
throw new Doctrine_Table_Exception('Uncompressing of ' . $field . ' failed.'); throw new Doctrine_Table_Exception('Uncompressing of ' . $fieldName . ' failed.');
} }
return $value; return $value;
break; break;
case 'enum': case 'enum':
return $this->enumValue($field, $value); return $this->enumValue($fieldName, $value);
break; break;
case 'boolean': case 'boolean':
return (boolean) $value; return (boolean) $value;
...@@ -1706,9 +1826,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1706,9 +1826,9 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @param string $hydrationMode * @param string $hydrationMode
* @return void * @return void
*/ */
protected function findBy($column, $value, $hydrationMode = null) protected function findBy($fieldName, $value, $hydrationMode = null)
{ {
return $this->createQuery()->where($column . ' = ?')->execute(array($value), $hydrationMode); return $this->createQuery()->where($fieldName . ' = ?')->execute(array($value), $hydrationMode);
} }
/** /**
...@@ -1719,11 +1839,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1719,11 +1839,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
* @param string $hydrationMode * @param string $hydrationMode
* @return void * @return void
*/ */
protected function findOneBy($column, $value, $hydrationMode = null) protected function findOneBy($fieldName, $value, $hydrationMode = null)
{ {
$results = $this->createQuery()->where($column . ' = ?')->limit(1)->execute(array($value), $hydrationMode); $results = $this->createQuery()->where($fieldName . ' = ?')->limit(1)->execute(array($value), $hydrationMode);
return $hydrationMode === Doctrine::FETCH_ARRAY ? $results[0]:$results->getFirst(); return $hydrationMode === Doctrine::FETCH_ARRAY ? $results[0] : $results->getFirst();
} }
/** /**
...@@ -1746,15 +1866,15 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable ...@@ -1746,15 +1866,15 @@ class Doctrine_Table extends Doctrine_Configurable implements Countable
} }
if (isset($by)) { if (isset($by)) {
if (!isset($arguments[0])) { if ( ! isset($arguments[0])) {
throw new Doctrine_Table_Exception('You must specify the value to findBy'); throw new Doctrine_Table_Exception('You must specify the value to findBy');
} }
$column = Doctrine::tableize($by); $fieldName = Doctrine::tableize($by);
$hydrationMode = isset($arguments[1]) ? $arguments[1]:null; $hydrationMode = isset($arguments[1]) ? $arguments[1]:null;
if ($this->hasColumn($column)) { if ($this->hasColumn($fieldName)) {
return $this->$method($column, $arguments[0], $hydrationMode); return $this->$method($fieldName, $arguments[0], $hydrationMode);
} else if ($this->hasRelation($by)) { } else if ($this->hasRelation($by)) {
$relation = $this->getRelation($by); $relation = $this->getRelation($by);
......
...@@ -56,6 +56,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module ...@@ -56,6 +56,7 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
/** /**
* @var array $invalid an array containing all invalid records within this transaction * @var array $invalid an array containing all invalid records within this transaction
* @todo What about a more verbose name? $invalidRecords?
*/ */
protected $invalid = array(); protected $invalid = array();
...@@ -294,12 +295,19 @@ class Doctrine_Transaction extends Doctrine_Connection_Module ...@@ -294,12 +295,19 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
* @param string $savepoint name of a savepoint to rollback to * @param string $savepoint name of a savepoint to rollback to
* @throws Doctrine_Transaction_Exception if the rollback operation fails at database level * @throws Doctrine_Transaction_Exception if the rollback operation fails at database level
* @return boolean false if rollback couldn't be performed, true otherwise * @return boolean false if rollback couldn't be performed, true otherwise
* @todo Shouldnt this method only commit a rollback if the transactionLevel is 1
* (STATE_ACTIVE)? Explanation: Otherwise a rollback that is triggered from inside doctrine
* in an (emulated) nested transaction would lead to a complete database level
* rollback even though the client code did not yet want to do that.
* In other words: if the user starts a transaction doctrine shouldnt roll it back.
* Doctrine should only roll back transactions started by doctrine. Thoughts?
*/ */
public function rollback($savepoint = null) public function rollback($savepoint = null)
{ {
$this->conn->connect(); $this->conn->connect();
$currentState = $this->getState();
if ($this->transactionLevel == 0) {
if ($currentState != self::STATE_ACTIVE && $currentState != self::STATE_BUSY) {
return false; return false;
} }
......
...@@ -4,9 +4,12 @@ class ColumnAliasTest extends Doctrine_Record ...@@ -4,9 +4,12 @@ class ColumnAliasTest extends Doctrine_Record
public function setTableDefinition() public function setTableDefinition()
{ {
$this->hasColumn('column1 as alias1', 'string', 200); $this->hasColumn('column1 as alias1', 'string', 200);
$this->hasColumn('column2 as alias2', 'integer', 11); $this->hasColumn('column2 as alias2', 'integer', 4);
$this->hasColumn('another_column as anotherField', 'string', 50);
$this->hasColumn('book_id as bookId', 'integer', 4);
} }
public function setUp() public function setUp()
{ {
$this->hasOne('Book as book', array('local' => 'book_id', 'foreign' => 'id'));
} }
} }
...@@ -48,7 +48,7 @@ class Doctrine_Access_TestCase extends Doctrine_UnitTestCase ...@@ -48,7 +48,7 @@ class Doctrine_Access_TestCase extends Doctrine_UnitTestCase
public function testIsset() public function testIsset()
{ {
$user = new User(); $user = new User();
$this->assertTrue(isset($user->name)); $this->assertTrue(isset($user->name));
$this->assertFalse(isset($user->unknown)); $this->assertFalse(isset($user->unknown));
...@@ -70,7 +70,7 @@ class Doctrine_Access_TestCase extends Doctrine_UnitTestCase ...@@ -70,7 +70,7 @@ class Doctrine_Access_TestCase extends Doctrine_UnitTestCase
public function testOffsetMethods() public function testOffsetMethods()
{ {
$user = new User(); $user = new User();
$this->assertEqual($user['name'],null); $this->assertEqual($user['name'], null);
$user['name'] = 'Jack'; $user['name'] = 'Jack';
$this->assertEqual($user['name'], 'Jack'); $this->assertEqual($user['name'], 'Jack');
......
...@@ -109,7 +109,7 @@ class Doctrine_ClassTableInheritance_TestCase extends Doctrine_UnitTestCase ...@@ -109,7 +109,7 @@ class Doctrine_ClassTableInheritance_TestCase extends Doctrine_UnitTestCase
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$q->from('CTITest c')->where('c.id = 1'); $q->from('CTITest c')->where('c.id = 1');
$this->assertEqual($q->getSql(), 'SELECT c.id AS c__id, c2.name AS c__name, c2.verified AS c__verified, c3.added AS c__added, c.age AS c__age FROM c_t_i_test_parent4 c LEFT JOIN c_t_i_test_parent2 c2 ON c.id = c2.id LEFT JOIN c_t_i_test_parent3 c3 ON c.id = c3.id WHERE c.id = 1'); $this->assertEqual($q->getSql(), 'SELECT c.id AS c__id, c3.added AS c__added, c2.name AS c__name, c2.verified AS c__verified, c.age AS c__age FROM c_t_i_test_parent4 c LEFT JOIN c_t_i_test_parent2 c2 ON c.id = c2.id LEFT JOIN c_t_i_test_parent3 c3 ON c.id = c3.id WHERE c.id = 1');
$record = $q->fetchOne(); $record = $q->fetchOne();
......
...@@ -33,14 +33,60 @@ ...@@ -33,14 +33,60 @@
class Doctrine_ColumnAlias_TestCase extends Doctrine_UnitTestCase class Doctrine_ColumnAlias_TestCase extends Doctrine_UnitTestCase
{ {
public function prepareData() public function prepareData()
{ } {
$book1 = new Book();
$book1->name = 'Das Boot';
$book1->save();
$record1 = new ColumnAliasTest();
$record1->alias1 = 'first';
$record1->alias2 = 123;
$record1->anotherField = 'camelCase';
$record1->bookId = $book1->id;
$record1->save();
$record2 = new ColumnAliasTest();
$record2->alias1 = 'one';
$record2->alias2 = 456;
$record2->anotherField = 'KoQ';
$record2->save();
$record2->anotherField = 'foo';
}
public function prepareTables() public function prepareTables()
{ {
$this->tables = array('ColumnAliasTest'); $this->tables = array('ColumnAliasTest', 'Book');
parent::prepareTables(); parent::prepareTables();
} }
public function testAliasesAreSupportedForJoins()
{
$q = new Doctrine_Query();
$q->select('c.*, b.name')->from('ColumnAliasTest c')
->innerJoin('c.book b')
->where('c.anotherField = ?', 'camelCase');
$result = $q->execute();
$this->assertTrue(isset($result[0]->book));
$this->assertEqual($result[0]->book->name, 'Das Boot');
}
public function testAliasesAreSupportedForArrayFetching()
{
$q = new Doctrine_Query();
$q->select('c.*, b.name')->from('ColumnAliasTest c')
->innerJoin('c.book b')
->where('c.anotherField = ?', 'camelCase')
->setHydrationMode(Doctrine::HYDRATE_ARRAY);
$result = $q->execute();
$this->assertEqual($result[0]['alias1'], 'first');
$this->assertEqual($result[0]['alias2'], 123);
$this->assertEqual($result[0]['anotherField'], 'camelCase');
$this->assertTrue(isset($result[0]['book']));
$this->assertEqual($result[0]['book']['name'], 'Das Boot');
}
public function testAliasesAreSupportedForRecordPropertyAccessors() public function testAliasesAreSupportedForRecordPropertyAccessors()
{ {
$record = new ColumnAliasTest; $record = new ColumnAliasTest;
...@@ -50,58 +96,60 @@ class Doctrine_ColumnAlias_TestCase extends Doctrine_UnitTestCase ...@@ -50,58 +96,60 @@ class Doctrine_ColumnAlias_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($record->alias1, 'someone'); $this->assertEqual($record->alias1, 'someone');
$this->assertEqual($record->alias2, 187); $this->assertEqual($record->alias2, 187);
} catch(Doctrine_Record_Exception $e) { } catch (Doctrine_Record_Exception $e) {
$this->fail(); $this->fail();
} }
$record->save();
} }
public function testAliasesAreSupportedForDqlSelectPart() public function testAliasesAreSupportedForDqlSelectPart()
{ {
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$q->select('c.alias1, c.alias2, c.anotherField')->from('ColumnAliasTest c');
$q->select('c.alias1, c.alias2')->from('ColumnAliasTest c');
$coll = $q->execute(); $coll = $q->execute();
$this->assertEqual($coll[0]->alias1, 'someone'); $this->assertEqual($coll[0]->alias1, 'first');
$this->assertEqual($coll[0]->alias2, 187); $this->assertEqual($coll[0]->alias2, 123);
$this->assertEqual($coll[0]->anotherField, 'camelCase');
} }
public function testAliasesAreSupportedForDqlWherePart() public function testAliasesAreSupportedForDqlWherePart()
{ {
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$q->select('c.alias1, c.alias2') $q->select('c.alias1, c.alias2, c.anotherField')
->from('ColumnAliasTest c') ->from('ColumnAliasTest c')
->where('c.alias1 = ?'); ->where('c.anotherField = ?');
$coll = $q->execute(array('someone')); $coll = $q->execute(array('KoQ'));
$this->assertEqual($coll[0]->alias1, 'someone'); $this->assertEqual($coll[0]->alias1, 'one');
$this->assertEqual($coll[0]->alias2, 187); $this->assertEqual($coll[0]->alias2, 456);
$this->assertEqual($coll[0]->anotherField, 'KoQ');
} }
public function testAliasesAreSupportedForDqlAggregateFunctions() public function testAliasesAreSupportedForDqlAggregateFunctions()
{ {
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$q->select('MAX(c.alias1)') $q->select('MAX(c.alias2)')->from('ColumnAliasTest c');
->from('ColumnAliasTest c');
$coll = $q->execute(); $coll = $q->execute();
$this->assertEqual($coll[0]->max, 'someone'); $this->assertEqual($coll[0]->MAX, 456);
} }
public function testAliasesAreSupportedForDqlHavingPart() public function testAliasesAreSupportedForDqlHavingPart()
{ {
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$q->select('c.alias1') $q->select('c.alias2')
->from('ColumnAliasTest c') ->from('ColumnAliasTest c')
->having('MAX(c.alias2) = 187') ->groupby('c.id')
->groupby('c.id'); ->having('c.alias2 > 123');
$coll = $q->execute(); $coll = $q->execute();
$this->assertEqual($coll[0]->alias1, 'someone'); $this->assertEqual($coll[0]->alias2, 456);
} }
} }
...@@ -100,8 +100,8 @@ class Doctrine_Export_Record_TestCase extends Doctrine_UnitTestCase ...@@ -100,8 +100,8 @@ class Doctrine_Export_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($this->adapter->pop(), 'COMMIT'); $this->assertEqual($this->adapter->pop(), 'COMMIT');
$this->assertEqual($this->adapter->pop(), 'ALTER TABLE cms__category_languages ADD FOREIGN KEY (category_id) REFERENCES cms__category(id) ON DELETE CASCADE'); $this->assertEqual($this->adapter->pop(), 'ALTER TABLE cms__category_languages ADD FOREIGN KEY (category_id) REFERENCES cms__category(id) ON DELETE CASCADE');
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE cms__category (id BIGINT AUTO_INCREMENT, created DATETIME, parent BIGINT, position MEDIUMINT, active BIGINT, INDEX index_parent_idx (parent), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB');
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE cms__category_languages (id BIGINT AUTO_INCREMENT, name TEXT, category_id BIGINT, language_id BIGINT, INDEX index_category_idx (category_id), INDEX index_language_idx (language_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB'); $this->assertEqual($this->adapter->pop(), 'CREATE TABLE cms__category_languages (id BIGINT AUTO_INCREMENT, name TEXT, category_id BIGINT, language_id BIGINT, INDEX index_category_idx (category_id), INDEX index_language_idx (language_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB');
$this->assertEqual($this->adapter->pop(), 'CREATE TABLE cms__category (id BIGINT AUTO_INCREMENT, created DATETIME, parent BIGINT, position MEDIUMINT, active BIGINT, INDEX index_parent_idx (parent), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = INNODB');
$this->assertEqual($this->adapter->pop(), 'BEGIN TRANSACTION'); $this->assertEqual($this->adapter->pop(), 'BEGIN TRANSACTION');
} }
......
...@@ -280,3 +280,4 @@ $data->addTestCase(new Doctrine_Data_Export_TestCase()); ...@@ -280,3 +280,4 @@ $data->addTestCase(new Doctrine_Data_Export_TestCase());
$test->addTestCase($data); $test->addTestCase($data);
$test->run(); $test->run();
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment