Commit 71d1150e authored by romanb's avatar romanb

Second merge from experimental branch to trunk.

parent e01809d1
This diff is collapsed.
......@@ -60,6 +60,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
protected $dbh;
/**
*
*/
protected $_tableFactory;
/**
......@@ -169,6 +172,12 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
'Sqlite',
'Firebird'
);
/**
* The query count. Represents the number of executed database queries by the connection.
*
* @var integer
*/
protected $_count = 0;
/**
......@@ -184,9 +193,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
throw new Doctrine_Connection_Exception('First argument should be an instance of PDO or implement Doctrine_Adapter_Interface');
}
$this->dbh = $adapter;
$this->isConnected = true;
} else if (is_array($adapter)) {
$this->pendingAttributes[Doctrine::ATTR_DRIVER_NAME] = $adapter['scheme'];
......@@ -235,7 +242,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
public function getAttribute($attribute)
{
if ($attribute >= 100) {
if ( ! isset($this->attributes[$attribute])) {
return parent::getAttribute($attribute);
......@@ -353,14 +359,13 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
}
/**
* returns the database handler of which this connection uses
* returns the database handler which this connection uses
*
* @return PDO the database handler
*/
public function getDbh()
{
$this->connect();
return $this->dbh;
}
......@@ -372,13 +377,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
public function connect()
{
if ($this->isConnected) {
return false;
}
$event = new Doctrine_Event($this, Doctrine_Event::CONN_CONNECT);
$this->getListener()->preConnect($event);
$e = explode(':', $this->options['dsn']);
......@@ -515,21 +518,19 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*
* @throws Doctrine_Connection_Exception if something went wrong at the database level
* @param string $table The table to delete data from
* @param array $identifier An associateve array containing identifier column-value pairs.
* @param array $identifier An associateve array containing identifier fieldname-value pairs.
* @return integer The number of affected rows
*/
public function delete(Doctrine_Table $table, array $identifier)
{
$tmp = array();
$criteria = array();
foreach (array_keys($identifier) as $id) {
$tmp[] = $table->getColumnName($id) . ' = ?';
$criteria[] = $table->getColumnName($id) . ' = ?';
}
$query = 'DELETE FROM '
. $this->quoteIdentifier($table->getTableName())
. ' WHERE ' . implode(' AND ', $tmp);
. ' WHERE ' . implode(' AND ', $criteria);
return $this->exec($query, array_values($identifier));
}
......@@ -573,7 +574,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* Inserts a table row with specified data.
*
* @param string $table The table to insert data into.
* @param array $values An associateve array containing column-value pairs.
* @param array $fields An associateve array containing fieldname-value pairs.
* @return mixed boolean false if empty value array was given,
* otherwise returns the number of affected rows
*/
......@@ -610,50 +611,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
return $this->exec($query, array_values($fields));
}
/**
* @todo DESCRIBE WHAT THIS METHOD DOES, PLEASE!
*/
public function processSingleInsert(Doctrine_Record $record)
{
$fields = $record->getPrepared();
if (empty($fields)) {
return false;
}
$table = $record->getTable();
$identifier = (array) $table->getIdentifier();
$seq = $record->getTable()->getOption('sequenceName');
if ( ! empty($seq)) {
$id = $this->sequence->nextId($seq);
$seqName = $table->getIdentifier();
$fields[$seqName] = $id;
$record->assignIdentifier($id);
}
$this->insert($table, $fields);
if (empty($seq) && count($identifier) == 1 && $identifier[0] == $table->getIdentifier() &&
$table->getIdentifierType() != Doctrine::IDENTIFIER_NATURAL) {
if (strtolower($this->getName()) == 'pgsql') {
$seq = $table->getTableName() . '_' . $identifier[0];
}
$id = $this->sequence->lastInsertId($seq);
if ( ! $id) {
throw new Doctrine_Connection_Exception("Couldn't get last insert identifier.");
}
$record->assignIdentifier($id);
} else {
$record->assignIdentifier(true);
}
}
/**
* Set the charset on the current connection
*
......@@ -661,11 +618,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
*/
public function setCharset($charset)
{
return true;
}
/**
* Quote a string so it can be safely used as a table or column name
* Quote a string so it can be safely used as a table or column name.
*
* Delimiting style depends on which database driver is being used.
*
......@@ -1032,7 +989,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function rethrowException(Exception $e, $invoker)
{
$event = new Doctrine_Event($this, Doctrine_Event::CONN_ERROR);
$this->getListener()->preError($event);
$name = 'Doctrine_Connection_' . $this->driverName . '_Exception';
......@@ -1079,7 +1035,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
}
/**
* Gets a mapper for the specified domain class that is used map instances of
* Gets a mapper for the specified domain class that is used to map instances of
* the class between the relational database and their object representation.
*
* @return Doctrine_Mapper_Abstract The mapper object.
......@@ -1092,9 +1048,9 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$customMapperClass = $className . 'Mapper';
if (class_exists($customMapperClass, $this->getAttribute(Doctrine::ATTR_AUTOLOAD_TABLE_CLASSES)) &&
in_array('Doctrine_Mapper', class_parents($customMapperClass))) {
in_array('Doctrine_Mapper_Abstract', class_parents($customMapperClass))) {
$table = $this->getTable($className);
$mapper = new $customMapperClass($className, $this);
$mapper = new $customMapperClass($className, $table);
} else {
// instantiate correct mapper type
$table = $this->getTable($className);
......@@ -1250,7 +1206,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
public function close()
{
$event = new Doctrine_Event($this, Doctrine_Event::CONN_CLOSE);
$this->getAttribute(Doctrine::ATTR_LISTENER)->preClose($event);
$this->clear();
......
......@@ -73,7 +73,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
{
$tree = array();
foreach ($tables as $k => $table) {
if ( ! ($table instanceof Doctrine_Mapper)) {
if ( ! ($table instanceof Doctrine_Mapper_Abstract)) {
$table = $this->conn->getMapper($table);
}
$nm = $table->getComponentName();
......@@ -281,7 +281,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* @return boolean true on success, false on failure
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/
public function delete(Doctrine_Record $record)
/*public function delete(Doctrine_Record $record)
{
if ( ! $this->_autoflush) {
return true;
......@@ -331,7 +331,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$this->conn->commit();
return true;
}
}*/
/**
* @todo Description. See also the todo for deleteMultiple().
......@@ -356,6 +356,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
}*/
/**
* DOESNT SEEM TO BE USED ANYWHERE.
*
* deleteMultiple
* deletes all records from the pending delete list
*
......@@ -364,7 +366,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* queries itself and sometimes it leaves the sql construction to Connection.
* This should be changed.
*/
public function deleteMultiple(array $records)
/*public function deleteMultiple(array $records)
{
foreach ($this->delete as $name => $deletes) {
$record = false;
......@@ -414,7 +416,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
}
}
}
}
}*/
/**
* saveRelated
......@@ -498,7 +500,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
* @throws PDOException if something went wrong at database level
* @return void
*/
public function deleteComposites(Doctrine_Record $record)
/*public function deleteComposites(Doctrine_Record $record)
{
foreach ($record->getTable()->getRelations() as $fk) {
if ($fk->isComposite()) {
......@@ -509,7 +511,7 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
}
}
}
}
}*/
/**
* saveAll
......@@ -554,22 +556,19 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
//echo "<br /><br />flushin all.<br /><br />";
// get the flush tree
$tree = $this->buildFlushTree($this->conn->getMappers());
//foreach ($tree as $name) echo $name . "<br />";
// save all records
foreach ($tree as $name) {
$mapper = $this->conn->getMapper($name);
foreach ($mapper->getRepository() as $record) {
//echo $record->getOid() . "<br />";
$mapper->save($record);
$mapper->saveSingleRecord($record);
}
}
// save all associations
foreach ($tree as $name) {
$mapper = $this->conn->getMapper($name);
foreach ($mapper->getRepository() as $record) {
$mapper->saveAssociations($record);
}
......
......@@ -106,6 +106,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
// Initialize
foreach ($this->_queryComponents as $dqlAlias => $data) {
$data['mapper']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
$componentName = $data['mapper']->getComponentName();
$listeners[$componentName] = $data['table']->getRecordListener();
$identifierMap[$dqlAlias] = array();
......@@ -229,6 +230,11 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
$driver->flush();
// re-enable lazy loading
foreach ($this->_queryComponents as $dqlAlias => $data) {
$data['mapper']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, true);
}
//$e = microtime(true);
//echo 'Hydration took: ' . ($e - $s) . ' for '.count($result).' records<br />';
......@@ -290,8 +296,9 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
$e = explode('__', $key);
$last = strtolower(array_pop($e));
$cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))];
$table = $this->_queryComponents[$cache[$key]['dqlAlias']]['table'];
$fieldName = $table->getFieldName($last);
$mapper = $this->_queryComponents[$cache[$key]['dqlAlias']]['mapper'];
$table = $mapper->getTable();
$fieldName = $mapper->getFieldName($last);
$cache[$key]['fieldName'] = $fieldName;
if ($table->isIdentifier($fieldName)) {
$cache[$key]['isIdentifier'] = true;
......@@ -306,8 +313,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
}
}
$map = $this->_queryComponents[$cache[$key]['dqlAlias']];
$mapper = $map['mapper'];
$mapper = $this->_queryComponents[$cache[$key]['dqlAlias']]['mapper'];
$dqlAlias = $cache[$key]['dqlAlias'];
$fieldName = $cache[$key]['fieldName'];
......
......@@ -37,18 +37,22 @@ class Doctrine_Hydrator_ArrayDriver
{
return array();
}
public function getElement(array $data, $component)
{
return $data;
}
public function isIdentifiable(array $data, Doctrine_Table $table)
{
return ( ! empty($data));
}
public function registerCollection($coll)
{
}
public function initRelated(array &$data, $name)
{
if ( ! isset($data[$name])) {
......@@ -56,10 +60,12 @@ class Doctrine_Hydrator_ArrayDriver
}
return true;
}
public function getNullPointer()
{
return null;
}
public function getLastKey(&$data)
{
end($data);
......
......@@ -20,8 +20,8 @@
*/
/**
* Doctrine_Hydrate_Record
* defines a record fetching strategy for Doctrine_Hydrate
* Doctrine_Hydrate_RecordDriver
* Hydration strategy used for creating collections of entity objects.
*
* @package Doctrine
* @subpackage Hydrate
......@@ -30,14 +30,13 @@
* @since 1.0
* @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Roman Borschel <roman@code-factory.org>
*/
class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
{
protected $_collections = array();
protected $_records = array();
protected $_tables = array();
protected $_mappers = array();
public function getElementCollection($component)
{
......@@ -105,13 +104,12 @@ class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
public function getElement(array $data, $component)
{
if ( ! isset($this->_tables[$component])) {
$this->_tables[$component] = Doctrine_Manager::getInstance()->getMapper($component);
$this->_tables[$component]->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
if ( ! isset($this->_mappers[$component])) {
$this->_mappers[$component] = Doctrine_Manager::getInstance()->getMapper($component);
}
$this->_tables[$component]->setData($data);
$record = $this->_tables[$component]->getRecord();
$component = $this->_getClassnameToReturn($data, $component);
$record = $this->_mappers[$component]->getRecord($data);
if ( ! isset($this->_records[$record->getOid()]) ) {
$record->clearRelated();
......@@ -127,8 +125,38 @@ class Doctrine_Hydrator_RecordDriver extends Doctrine_Locator_Injectable
foreach ($this->_collections as $key => $coll) {
$coll->takeSnapshot();
}
foreach ($this->_tables as $table) {
$table->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, true);
}
/**
* Check the dataset for a discriminator column, to determine the correct
* class to instantiate. If no discriminator column is found, the given
* classname will be returned.
*
* @todo this function could use reflection to check the first time it runs
* if the subclassing option is not set.
*
* @return string The name of the class to instantiate.
*
*/
protected function _getClassnameToReturn(array $data, $className)
{
$subClasses = $this->_mappers[$className]->getTable()->getOption('subclasses');
if ( ! isset($subClasses)) {
return $className;
}
foreach ($subClasses as $subclass) {
if ( ! isset($this->_mappers[$subclass])) {
$this->_mappers[$subclass] = Doctrine_Manager::getInstance()->getMapper($subclass);
}
$mapper = $this->_mappers[$subclass];
$inheritanceMap = $mapper->getDiscriminatorColumn();
foreach ($inheritanceMap as $key => $value) {
if (isset($data[$key]) && $data[$key] == $value) {
return $mapper->getComponentName();
}
}
}
return $className;
}
}
......@@ -255,7 +255,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
}
$driverName = $adapter->getAttribute(Doctrine::ATTR_DRIVER_NAME);
} elseif (is_array($adapter)) {
} else if (is_array($adapter)) {
if ( ! isset($adapter[0])) {
throw new Doctrine_Manager_Exception('Empty data source name given.');
}
......
<?php
class Doctrine_Mapper_Joined extends Doctrine_Mapper
class Doctrine_Mapper_Joined extends Doctrine_Mapper_Abstract
{
protected $_columnNameFieldNameMap = array();
/**
* inserts a record into database
......@@ -10,7 +11,7 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
* @return boolean
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/
public function insert(Doctrine_Record $record)
protected function _doInsert(Doctrine_Record $record)
{
$table = $this->_table;
......@@ -20,19 +21,39 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
$classes = $table->getOption('joinedParents');
array_unshift($classes, $component);
try {
$this->_conn->beginInternalTransaction();
$identifier = null;
foreach (array_reverse($classes) as $k => $parent) {
if ($k === 0) {
$rootRecord = new $parent();
$rootRecord->merge($dataSet[$parent]);
parent::insert($rootRecord);
$record->assignIdentifier($rootRecord->identifier());
$parentTable = $this->_conn->getTable($parent);
if ($k == 0) {
$identifierType = $parentTable->getIdentifierType();
if ($identifierType == Doctrine::IDENTIFIER_AUTOINC) {
$this->_conn->insert($parentTable, $dataSet[$parent]);
$identifier = $this->_conn->sequence->lastInsertId();
} else if ($identifierType == Doctrine::IDENTIFIER_SEQUENCE) {
$seq = $record->getTable()->getOption('sequenceName');
if ( ! empty($seq)) {
$identifier = $this->_conn->sequence->nextId($seq);
$dataSet[$parent][$parentTable->getIdentifier()] = $identifier;
$this->_conn->insert($parentTable, $dataSet[$parent]);
}
} else {
throw new Doctrine_Mapper_Exception("Unsupported identifier type '$identifierType'.");
}
$record->assignIdentifier($identifier);
} else {
foreach ((array) $rootRecord->identifier() as $id => $value) {
foreach ((array) $record->identifier() as $id => $value) {
$dataSet[$parent][$id] = $value;
}
$this->_conn->insert($this->_conn->getTable($parent), $dataSet[$parent]);
$this->_conn->insert($parentTable, $dataSet[$parent]);
}
}
$this->_conn->commit();
} catch (Exception $e) {
$this->_conn->rollback();
throw $e;
}
return true;
}
......@@ -44,14 +65,9 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
* @return boolean whether or not the update was successful
* @todo Move to Doctrine_Table (which will become Doctrine_Mapper).
*/
public function update(Doctrine_Record $record)
protected function _doUpdate(Doctrine_Record $record)
{
$event = new Doctrine_Event($record, Doctrine_Event::RECORD_UPDATE);
$record->preUpdate($event);
$table = $this->_table;
$this->getRecordListener()->preUpdate($event);
if ( ! $event->skipOperation) {
$identifier = $record->identifier();
$dataSet = $this->_formatDataSet($record);
$component = $table->getComponentName();
......@@ -73,10 +89,34 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
}
$record->assignIdentifier(true);
return true;
}
protected function _doDelete(Doctrine_Record $record, Doctrine_Connection $conn)
{
try {
$table = $this->_table;
$conn->beginInternalTransaction();
$this->deleteComposites($record);
$record->state(Doctrine_Record::STATE_TDIRTY);
foreach ($table->getOption('joinedParents') as $parent) {
$parentTable = $conn->getTable($parent);
$conn->delete($parentTable, $record->identifier());
}
$this->getRecordListener()->postUpdate($event);
$record->postUpdate($event);
$conn->delete($table, $record->identifier());
$record->state(Doctrine_Record::STATE_TCLEAN);
$this->removeRecord($record);
$conn->commit();
} catch (Exception $e) {
$conn->rollback();
throw $e;
}
return true;
}
......@@ -87,13 +127,33 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
*/
public function getCustomJoins()
{
return $this->_table->getOption('joinedParents');
$customJoins = array();
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$customJoins[$parentClass] = 'INNER';
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
if ($subClass != $this->_domainClassName) {
$customJoins[$subClass] = 'LEFT';
}
}
return $customJoins;
}
public function getCustomFields()
{
$fields = array();
if ($this->_table->getOption('subclasses')) {
foreach ($this->_table->getOption('subclasses') as $subClass) {
$fields = array_merge($this->_conn->getTable($subClass)->getFieldNames(), $fields);
}
}
return array_unique($fields);
}
/**
*
*/
public function getDiscriminatorColumn($domainClassName)
public function getDiscriminatorColumn()
{
$joinedParents = $this->_table->getOption('joinedParents');
if (count($joinedParents) <= 0) {
......@@ -101,7 +161,7 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
} else {
$inheritanceMap = $this->_conn->getTable(array_pop($joinedParents))->getOption('inheritanceMap');
}
return isset($inheritanceMap[$domainClassName]) ? $inheritanceMap[$domainClassName] : array();
return isset($inheritanceMap[$this->_domainClassName]) ? $inheritanceMap[$this->_domainClassName] : array();
}
/**
......@@ -115,14 +175,67 @@ class Doctrine_Mapper_Joined extends Doctrine_Mapper
$fieldNames = $this->_table->getFieldNames();
foreach ($this->_table->getOption('joinedParents') as $parent) {
$fieldNames = array_merge($this->_conn->getTable($parent)->getFieldNames(),
$fieldNames);
$parentTable = $this->_conn->getTable($parent);
$fieldNames = array_merge($parentTable->getFieldNames(), $fieldNames);
}
$this->_fieldNames = $fieldNames;
$this->_fieldNames = array_unique($fieldNames);
return $fieldNames;
}
public function getFieldName($columnName)
{
if (isset($this->_columnNameFieldNameMap[$columnName])) {
return $this->_columnNameFieldNameMap[$columnName];
}
if ($this->_table->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $this->_table->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$parentTable = $this->_conn->getTable($parentClass);
if ($parentTable->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $parentTable->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
$subTable = $this->_conn->getTable($subClass);
if ($subTable->hasColumn($columnName)) {
$this->_columnNameFieldNameMap[$columnName] = $subTable->getFieldName($columnName);
return $this->_columnNameFieldNameMap[$columnName];
}
}
throw new Doctrine_Mapper_Exception("No field name found for column name '$columnName'.");
}
public function getOwningTable($fieldName)
{
if ($this->_table->hasField($fieldName)) {
return $this->_table;
}
foreach ($this->_table->getOption('joinedParents') as $parentClass) {
$parentTable = $this->_conn->getTable($parentClass);
if ($parentTable->hasField($fieldName)) {
return $parentTable;
}
}
foreach ((array)$this->_table->getOption('subclasses') as $subClass) {
$subTable = $this->_conn->getTable($subClass);
if ($subTable->hasField($fieldName)) {
return $subTable;
}
}
throw new Doctrine_Mapper_Exception("Unable to find owner of field '$fieldName'.");
}
/**
*
*/
......
<?php
class Doctrine_Mapper_SingleTable extends Doctrine_Mapper
class Doctrine_Mapper_SingleTable extends Doctrine_Mapper_Abstract
{
public function getDiscriminatorColumn($domainClassName)
public function getDiscriminatorColumn()
{
$inheritanceMap = $this->_table->getOption('inheritanceMap');
return isset($inheritanceMap[$domainClassName]) ? $inheritanceMap[$domainClassName] : array();
return isset($inheritanceMap[$this->_domainClassName]) ? $inheritanceMap[$this->_domainClassName] : array();
}
/*public function addToWhere($componentAlias, array &$sqlWhereParts, Doctrine_Query $query)
{
$array = array();
$componentParts = $query->getQueryComponent($componentAlias);
$sqlTableAlias = $query->getSqlTableAlias($componentAlias);
$array[$sqlTableAlias][] = $this->getDiscriminatorColumn();
// apply inheritance maps
$str = '';
$c = array();
$index = 0;
foreach ($array as $tableAlias => $maps) {
$a = array();
// don't use table aliases if the query isn't a select query
if ($query->getType() !== Doctrine_Query::SELECT) {
$tableAlias = '';
} else {
$tableAlias .= '.';
}
foreach ($maps as $map) {
$b = array();
foreach ($map as $field => $value) {
$identifier = $this->_conn->quoteIdentifier($tableAlias . $field);
if ($index > 0) {
$b[] = '(' . $identifier . ' = ' . $this->_conn->quote($value)
. ' OR ' . $identifier . ' IS NULL)';
} else {
$b[] = $identifier . ' = ' . $this->_conn->quote($value);
}
}
if ( ! empty($b)) {
$a[] = implode(' AND ', $b);
}
}
if ( ! empty($a)) {
$c[] = implode(' AND ', $a);
}
$index++;
}
$str .= implode(' AND ', $c);
return $str;
}*/
}
<?php
class Doctrine_Mapper_TablePerClass extends Doctrine_Mapper
class Doctrine_Mapper_TablePerClass extends Doctrine_Mapper_Abstract
{
......
......@@ -400,54 +400,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
}
}
/**
* parseQueryPart
* parses given DQL query part
*
* @param string $queryPartName the name of the query part
* @param string $queryPart query part to be parsed
* @param boolean $append whether or not to append the query part to its stack
* if false is given, this method will overwrite
* the given query part stack with $queryPart
* @return Doctrine_Query this object
*/
/*protected function parseQueryPart($queryPartName, $queryPart, $append = false)
{
if ($this->_state === self::STATE_LOCKED) {
throw new Doctrine_Query_Exception('This query object is locked. No query parts can be manipulated.');
}
// sanity check
if ($queryPart === '' || $queryPart === null) {
throw new Doctrine_Query_Exception('Empty ' . $queryPartName . ' part given.');
}
// add query part to the dql part array
if ($append) {
$this->_dqlParts[$queryPartName][] = $queryPart;
} else {
$this->_dqlParts[$queryPartName] = array($queryPart);
}
if ($this->_state === self::STATE_DIRECT) {
$parser = $this->_getParser($queryPartName);
$sql = $parser->parse($queryPart);
if (isset($sql)) {
if ($append) {
$this->addSqlQueryPart($queryPartName, $sql);
} else {
$this->setSqlQueryPart($queryPartName, $sql);
}
}
}
$this->_state = Doctrine_Query::STATE_DIRTY;
return $this;
}*/
/**
* getDqlPart
* returns a specific DQL query part.
......@@ -480,8 +432,9 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
*/
public function processPendingFields($componentAlias)
{
$tableAlias = $this->getTableAlias($componentAlias);
$table = $this->_queryComponents[$componentAlias]['table'];
$tableAlias = $this->getSqlTableAlias($componentAlias);
$baseTable = $this->_queryComponents[$componentAlias]['table'];
$mapper = $this->_queryComponents[$componentAlias]['mapper'];
if ( ! isset($this->_pendingFields[$componentAlias])) {
return;
......@@ -489,41 +442,39 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$fields = $this->_pendingFields[$componentAlias];
// check for wildcards
if (in_array('*', $fields)) {
//echo "<br />";Doctrine::dump($table->getColumnNames()); echo "<br />";
$fields = $table->getFieldNames();
$fields = $mapper->getFieldNames();
} else {
// only auto-add the primary key fields if this query object is not
// a subquery of another query object
if ( ! $this->_isSubquery) {
$fields = array_unique(array_merge((array) $table->getIdentifier(), $fields));
$fields = array_unique(array_merge((array) $baseTable->getIdentifier(), $fields));
}
}
$fields = array_unique(array_merge($fields, $mapper->getCustomFields()));
$sql = array();
foreach ($fields as $fieldName) {
$columnName = $table->getColumnName($fieldName);
if (($owner = $table->getColumnOwner($columnName)) !== null &&
$owner !== $table->getComponentName()) {
$parent = $this->_conn->getTable($owner);
$columnName = $parent->getColumnName($fieldName);
$parentAlias = $this->getTableAlias($componentAlias . '.' . $parent->getComponentName());
$sql[] = $this->_conn->quoteIdentifier($parentAlias . '.' . $columnName)
. ' AS '
. $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName);
$table = $mapper->getOwningTable($fieldName);
if ($table !== $baseTable) {
$tableAlias = $this->getSqlTableAlias($componentAlias . '.' . $table->getComponentName());
} else {
$tableAlias = $this->getSqlTableAlias($componentAlias);
}
$columnName = $table->getColumnName($fieldName);
$columnName = $table->getColumnName($fieldName);
$sql[] = $this->_conn->quoteIdentifier($tableAlias . '.' . $columnName)
. ' AS '
. $this->_conn->quoteIdentifier($tableAlias . '__' . $columnName);
. $this->_conn->quoteIdentifier($this->getSqlTableAlias($componentAlias) . '__' . $columnName);
if ( ! in_array($tableAlias, $this->_neededTables)) {
$this->_neededTables[] = $tableAlias;
}
}
$this->_neededTables[] = $tableAlias;
//Doctrine::dump(implode(', ', $sql));
//echo "<br /><br />";
return implode(', ', $sql);
}
......@@ -617,7 +568,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
// check for DISTINCT keyword
if ($first === 'DISTINCT') {
$this->_sqlParts['distinct'] = true;
$refs[0] = substr($refs[0], ++$pos);
}
......@@ -670,7 +620,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$componentAlias = key($this->_queryComponents);
$field = $e[0];
}
$this->_pendingFields[$componentAlias][] = $field;
}
}
......@@ -1156,7 +1105,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
}
// append discriminator column conditions (if any)
$string = $this->_createDiscriminatorSql();
$string = $this->_createDiscriminatorConditionSql();
//echo "orig:$string<br /><br />";
if ( ! empty($string)) {
if (substr($string, 0, 1) === '(' && substr($string, -1) === ')') {
$this->_sqlParts['where'][] = $string;
......@@ -1482,18 +1432,16 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$componentAlias = $prevPath;
}
// if the current alias already exists, skip it
// if the current alias already exists, it's user error
if (isset($this->_queryComponents[$componentAlias])) {
continue;
throw new Doctrine_Query_Exception("Duplicate alias '$componentAlias' in query.");
}
if ( ! isset($table)) {
// process the root of the path
$table = $this->loadRoot($name, $componentAlias);
} else {
$join = ($delimeter == ':') ? 'INNER JOIN ' : 'LEFT JOIN ';
//echo "!!!!!!" . $prevPath . "!!!!!<br />";
$relation = $table->getRelation($name);
$localTable = $table;
......@@ -1536,7 +1484,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
}
$assocPath = $prevPath . '.' . $asf->getComponentName();
//var_dump($name); echo "hrrrr";
//echo "<br /><br />" . $asf->getComponentName() . "---2---" . $relation->getForeignComponentName() . "<br /><br />";
$this->_queryComponents[$assocPath] = array(
'parent' => $prevPath,
......@@ -1592,7 +1539,6 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
}
}
} else {
$queryPart = $join . $foreignSql;
if ( ! $overrideJoin) {
......@@ -1632,8 +1578,8 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
if (isset($e[1])) {
$indexBy = $e[1];
}
} else if ($mapper->getBoundQueryPart('indexBy') !== null) {
$indexBy = $mapper->getBoundQueryPart('indexBy');
} else if ($table->getBoundQueryPart('indexBy') !== null) {
$indexBy = $table->getBoundQueryPart('indexBy');
}
if ($indexBy !== null) {
......@@ -1733,7 +1679,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable, Seria
$q .= ' FROM ' . $this->_buildSqlFromPart();
// append discriminator column conditions (if any)
$string = $this->_createDiscriminatorSql();
$string = $this->_createDiscriminatorConditionSql();
if ( ! empty($string)) {
$where[] = $string;
}
......
......@@ -532,11 +532,11 @@ abstract class Doctrine_Query_Abstract
$tableAlias = $this->getSqlTableAlias($componentAlias, $table->getTableName());
$customJoins = $this->_conn->getMapper($componentName)->getCustomJoins();
$sql = '';
foreach ($customJoins as $componentName) {
foreach ($customJoins as $componentName => $joinType) {
$joinedTable = $this->_conn->getTable($componentName);
$joinedAlias = $componentAlias . '.' . $componentName;
$joinedTableAlias = $this->getSqlTableAlias($joinedAlias, $joinedTable->getTableName());
$sql .= ' LEFT JOIN ' . $this->_conn->quoteIdentifier($joinedTable->getTableName())
$sql .= " $joinType JOIN " . $this->_conn->quoteIdentifier($joinedTable->getTableName())
. ' ' . $this->_conn->quoteIdentifier($joinedTableAlias) . ' ON ';
foreach ($table->getIdentifierColumnNames() as $column) {
......@@ -556,23 +556,16 @@ abstract class Doctrine_Query_Abstract
*
* @return string The created SQL snippet.
*/
protected function _createDiscriminatorSql()
protected function _createDiscriminatorConditionSql()
{
$array = array();
foreach ($this->_queryComponents as $componentAlias => $data) {
$tableAlias = $this->getSqlTableAlias($componentAlias);
//echo $data['table']->getComponentName() . " -- ";
/*if (!isset($data['mapper'])) {
//echo $data['table']->getComponentName();
echo $this->getDql();
}*/
/*if ($data['mapper']->getComponentName() != $data['table']->getComponentName()) {
//echo $this->getDql() . "<br />";
}*/
//echo $data['mapper']->getComponentName() . "_<br />";
//var_dump($data['mapper']->getDiscriminatorColumn($data['mapper']->getComponentName()));
$array[$tableAlias][] = $data['mapper']->getDiscriminatorColumn($data['mapper']->getComponentName());
$sqlTableAlias = $this->getSqlTableAlias($componentAlias);
if ( ! $data['mapper'] instanceof Doctrine_Mapper_SingleTable) {
$array[$sqlTableAlias][] = array();
} else {
$array[$sqlTableAlias][] = $data['mapper']->getDiscriminatorColumn();
}
}
//var_dump($array);
// apply inheritance maps
......
......@@ -238,7 +238,7 @@ class Doctrine_RawSql extends Doctrine_Query_Abstract
}
}
$string = $this->_createDiscriminatorSql();
$string = $this->_createDiscriminatorConditionSql();
if ( ! empty($string)) {
$this->_sqlParts['where'][] = $string;
}
......
......@@ -146,7 +146,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* open connections
* @throws Doctrine_Record_Exception if the cleanData operation fails somehow
*/
public function __construct($mapper = null, $isNewEntry = false)
public function __construct($mapper = null, $isNewEntry = false, array $data = array())
{
//echo get_class($this) . "<br />";
if (isset($mapper) && $mapper instanceof Doctrine_Table) {
......@@ -155,18 +155,10 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
//$this->_mapper = Doctrine_Manager::getInstance()->getMapper(get_class($this));
$exists = ! $isNewEntry;
return;
} else if (isset($mapper) && $mapper instanceof Doctrine_Mapper) {
} else if (isset($mapper) && $mapper instanceof Doctrine_Mapper_Abstract) {
//echo "two<br />";
$class = get_class($this);
$this->_mapper = Doctrine_Manager::getInstance()->getMapper($class);
if ($class != $this->_mapper->getComponentName()) {
try {
throw new Exception("ddd");
} catch (Exception $e) {
echo "MISMATCH: " . get_class($this) . "---" . $mapper->getComponentName();
echo $e->getTraceAsString() . "<br /><br />";
}
}
$this->_table = $this->_mapper->getTable();
$exists = ! $isNewEntry;
} else {
......@@ -182,7 +174,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
self::$_index++;
// get the data array
$this->_data = $this->_mapper->getData();
$this->_data = $data;
// get the column count
$count = count($this->_data);
......@@ -202,7 +194,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->assignDefaultValues();
} else {
$this->_state = Doctrine_Record::STATE_CLEAN;
// @TODO table->getColumnCount is not correct in CTI
if ($count < $this->_table->getColumnCount()) {
$this->_state = Doctrine_Record::STATE_PROXY;
}
......@@ -213,7 +205,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$repository->add($this);
$this->construct();
}
/**
......@@ -257,11 +248,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
return $this->_oid;
}
public function oid()
{
return $this->_oid;
}
/**
* isValid
*
......@@ -534,22 +520,22 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
/**
* serialize
* this method is automatically called when this Doctrine_Record is serialized
* Serializes the entity.
* This method is automatically called when the entity is serialized.
*
* Part of the implementation of the Serializable interface.
*
* @return array
*/
public function serialize()
{
$event = new Doctrine_Event($this, Doctrine_Event::RECORD_SERIALIZE);
$this->preSerialize($event);
$vars = get_object_vars($this);
unset($vars['_references']);
unset($vars['_mapper']);
//unset($vars['_table']);
unset($vars['_errorStack']);
unset($vars['_filter']);
unset($vars['_node']);
......@@ -586,8 +572,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
/**
* unseralize
* this method is automatically called everytime a Doctrine_Record object is unserialized
* Reconstructs the entity from it's serialized form.
* This method is automatically called everytime the entity is unserialized.
*
* @param string $serialized Doctrine_Record as serialized string
* @throws Doctrine_Record_Exception if the cleanData operation fails somehow
......@@ -634,6 +620,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->_mapper->getRepository()->add($this);
$this->cleanData($this->_data);
$this->prepareIdentifiers($this->exists());
$this->postUnserialize($event);
}
......@@ -676,7 +663,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
if ($err) {
throw new Doctrine_Record_Exception('Unknown record state ' . $state);
throw new Doctrine_Record_Exception("Unknown record state '$state'.");
}
}
......@@ -863,12 +850,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
if ( ! isset($this->_references[$fieldName]) && $load) {
$rel = $this->_table->getRelation($fieldName);
$this->_references[$fieldName] = $rel->fetchRelatedFor($this);
/*if (count($this->_references[$fieldName]) > 0) {
echo $this->_references[$fieldName][0]->state() . "<br />";
}*/
}
return $this->_references[$fieldName];
} catch (Doctrine_Table_Exception $e) {
//echo $e->getTraceAsString();
//echo "<br /><br />";
......@@ -937,12 +920,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
$this->_modified[] = $fieldName;
switch ($this->_state) {
case Doctrine_Record::STATE_CLEAN:
/*try {
throw new Exception();
} catch (Exception $e) {
echo $e->getTraceAsString() . "<br /><br />";
}
echo "setting dirty ... <br />";*/
$this->_state = Doctrine_Record::STATE_DIRTY;
break;
case Doctrine_Record::STATE_TCLEAN:
......@@ -1004,7 +981,6 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
}
}
} else if ($rel instanceof Doctrine_Relation_Association) {
// join table relation found
if ( ! ($value instanceof Doctrine_Collection)) {
......@@ -1070,7 +1046,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/
public function save(Doctrine_Connection $conn = null)
{
$this->_mapper->saveGraph($this, $conn);
$this->_mapper->save($this, $conn);
}
/**
......@@ -1209,7 +1185,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
}
}
//$map = $this->_table->getOption('inheritanceMap');
$map = $this->_mapper->getDiscriminatorColumn($this->_domainClassName);
$map = $this->_mapper->getDiscriminatorColumn();
foreach ($map as $k => $v) {
$old = $this->get($k, false);
if ((string) $old !== (string) $v || $old === null) {
......@@ -1225,6 +1201,8 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* count
* this class implements countable interface
*
* Implementation of the Countable interface.
*
* @return integer the number of columns in this record
*/
public function count()
......@@ -1436,10 +1414,7 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
*/
public function delete(Doctrine_Connection $conn = null)
{
if ($conn == null) {
$conn = $this->_mapper->getConnection();
}
return $conn->unitOfWork->delete($this);
return $this->_mapper->delete($this, $conn);
}
/**
......
......@@ -107,7 +107,10 @@ class Doctrine_Relation_Association extends Doctrine_Relation
public function fetchRelatedFor(Doctrine_Record $record)
{
$id = $record->getIncremented();
//var_dump($id);
//echo "<br /><br />";
if (empty($id) || ! $this->_foreignMapper->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) {
//echo "here" . $this->_foreignMapper->getAttribute(Doctrine::ATTR_LOAD_REFERENCES);
$coll = new Doctrine_Collection($this->getForeignComponentName());
} else {
$query = Doctrine_Query::create()->parseQuery($this->getRelationDql(1));
......
......@@ -47,10 +47,8 @@ class Doctrine_Sequence_Mysql extends Doctrine_Sequence
$query = 'INSERT INTO ' . $sequenceName . ' (' . $seqcolName . ') VALUES (NULL)';
try {
$this->conn->exec($query);
} catch(Doctrine_Connection_Exception $e) {
} catch (Doctrine_Connection_Exception $e) {
if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
try {
$this->conn->export->createSequence($seqName);
......
......@@ -47,7 +47,7 @@ class Doctrine_Sequence_Pgsql extends Doctrine_Sequence
$query = "SELECT NEXTVAL('" . $sequenceName . "')";
try {
$result = (int) $this->conn->fetchOne($query);
} catch(Doctrine_Connection_Exception $e) {
} catch (Doctrine_Connection_Exception $e) {
if ($onDemand && $e->getPortableCode() == Doctrine::ERR_NOSUCHTABLE) {
try {
......@@ -70,6 +70,7 @@ class Doctrine_Sequence_Pgsql extends Doctrine_Sequence
* @param string name of the table into which a new row was inserted
* @param string name of the field into which a new row was inserted
* @return integer the autoincremented id
* @todo Why not use $this->conn->getDbh()->lastInsertId($sequenceName) ?
*/
public function lastInsertId($table = null, $field = null)
{
......
......@@ -437,6 +437,11 @@ class Doctrine_Table extends Doctrine_Configurable implements Serializable
$fieldName = $parts[0];
}
$name = strtolower($parts[0]);
if (isset($this->_columnNames[$fieldName])) {
return;
}
if ($prepend) {
$this->_columnNames = array_merge(array($fieldName => $name), $this->_columnNames);
$this->_fieldNames = array_merge(array($name => $fieldName), $this->_fieldNames);
......@@ -493,6 +498,8 @@ class Doctrine_Table extends Doctrine_Configurable implements Serializable
if (isset($options['default'])) {
$this->hasDefaultValues = true;
}
$this->columnCount++;
}
/**
......@@ -634,11 +641,6 @@ class Doctrine_Table extends Doctrine_Configurable implements Serializable
return $this->columnCount;
}
public function setColumnCount($count)
{
$this->columnCount = $count;
}
/**
* returns all columns and their definitions
*
......
......@@ -200,11 +200,9 @@ class Doctrine_Table_Factory
$table->setOption('declaringClass', $class);
// set the table definition for the given tree implementation
if ($table->isTree()) {
/*if ($table->isTree()) {
$table->getTree()->setTableDefinition();
}
$table->setColumnCount(count($table->getColumns()));
}*/
$tableName = $table->getOption('tableName');
if ( ! isset($tableName)) {
......@@ -217,9 +215,9 @@ class Doctrine_Table_Factory
$record->setUp();
// if tree, set up tree relations
if ($table->isTree()) {
/*if ($table->isTree()) {
$table->getTree()->setUp();
}
}*/
return $table;
}
......@@ -304,8 +302,6 @@ class Doctrine_Table_Factory
$table->setIdentifier('id');
$table->setIdentifierType(Doctrine::IDENTIFIER_AUTOINC);
}
$currentCount = $table->getColumnCount();
$table->setColumnCount(++$currentCount);
break;
case 1:
foreach ($table->getIdentifier() as $pk) {
......
......@@ -51,9 +51,9 @@ class Doctrine_Table_Repository implements Countable, IteratorAggregate
*
* @param Doctrine_Table $table
*/
public function __construct(Doctrine_Mapper $table)
public function __construct(Doctrine_Mapper_Abstract $mapper)
{
$this->table = $table;
$this->table = $mapper;
}
/**
......
......@@ -326,11 +326,6 @@ class Doctrine_Transaction extends Doctrine_Connection_Module
public function rollback($savepoint = null)
{
if ($this->_nestingLevel == 0) {
/*try {
throw new Doctrine_Transaction_Exception("Rollback failed. There is no active transaction.");
} catch (Exception $e) {
echo $e->getTraceAsString() . "<br />";
}*/
throw new Doctrine_Transaction_Exception("Rollback failed. There is no active transaction.");
}
......
......@@ -319,39 +319,4 @@ class Doctrine_Tree_NestedSet extends Doctrine_Tree implements Doctrine_Tree_Int
$this->_baseQuery = $this->_createBaseQuery();
}
/**
* Enter description here...
*
* @param unknown_type $graph
*/
/*
public function computeLevels($tree)
{
$right = array();
$isArray = is_array($tree);
$rootColumnName = $this->getAttribute('rootColumnName');
for ($i = 0, $count = count($tree); $i < $count; $i++) {
if ($rootColumnName && $i > 0 && $tree[$i][$rootColumnName] != $tree[$i-1][$rootColumnName]) {
$right = array();
}
if (count($right) > 0) {
while (count($right) > 0 && $right[count($right)-1] < $tree[$i]['rgt']) {
//echo count($right);
array_pop($right);
}
}
if ($isArray) {
$tree[$i]['level'] = count($right);
} else {
$tree[$i]->getNode()->setLevel(count($right));
}
$right[] = $tree[$i]['rgt'];
}
return $tree;
}
*/
}
\ No newline at end of file
......@@ -151,9 +151,9 @@ class Doctrine_Connection_TestCase extends Doctrine_UnitTestCase
public function testDelete()
{
$user = $this->connection->create('User');
$this->connection->unitOfWork->delete($user);
$this->assertEqual($user->state(),Doctrine_Record::STATE_TCLEAN);
//$user = $this->connection->create('User');
//$this->connection->unitOfWork->delete($user);
//$this->assertEqual($user->state(),Doctrine_Record::STATE_TCLEAN);
}
public function testGetTable()
......
......@@ -140,6 +140,40 @@ class Doctrine_Inheritance_Joined_TestCase extends Doctrine_UnitTestCase
$this->assertEqual('Billy the Kid', $superManager->gosutitle);
$this->assertEqual(4, $superManager->type);
}
public function testDqlQueryJoinsTransparentlyAcrossParents()
{
$this->_createManager();
$this->conn->getMapper('CTI_Manager')->clear();
$query = $this->conn->createQuery();
$query->parseQuery("SELECT m.* FROM CTI_Manager m");
$manager = $query->execute()->getFirst();
$this->assertTrue($manager instanceof CTI_Manager);
$this->assertEqual(1, $manager->id);
$this->assertEqual(80000, $manager->salary);
$this->assertEqual('John Smith', $manager->name);
$this->assertEqual(2, $manager->type);
}
public function testQueryingBaseClassOuterJoinsSubClassesAndReturnsSubclassInstances()
{
$this->_createManager();
$this->conn->getMapper('CTI_Manager')->clear();
$this->conn->getMapper('CTI_User')->clear();
$query = $this->conn->createQuery();
$query->parseQuery("SELECT u.* FROM CTI_User u");
//echo $query->getSql();
$user = $query->execute()->getFirst();
$this->assertTrue($user instanceof CTI_Manager);
$this->assertEqual(1, $user->id);
$this->assertEqual(80000, $user->salary);
$this->assertEqual('John Smith', $user->name);
$this->assertEqual(2, $user->type);
}
}
......@@ -152,7 +186,15 @@ class CTI_User extends Doctrine_Record
'CTI_Manager' => array('type' => 2),
'CTI_Customer' => array('type' => 3),
'CTI_SuperManager' => array('type' => 4))
);
);/*
$class->setInheritanceType(Doctrine::INHERITANCETYPE_JOINED, array(
'discriminatorColumn' => 'type',
'map' => array(1 => 'CTI_User', 2 => 'CTI_Manager', 3 => 'CTI_Customer',
4 => 'CTI_SuperManager')
));
$class->setDiscriminatorValue(1);
$class->setInheritanceOption('fetchType', 'explicit');
*/
$this->setTableName('cti_user');
$this->hasColumn('cti_id as id', 'integer', 4, array('primary' => true, 'autoincrement' => true));
$this->hasColumn('cti_foo as foo', 'integer', 4);
......
......@@ -58,6 +58,16 @@ class Doctrine_Inheritance_SingleTable_TestCase extends Doctrine_UnitTestCase
$this->fail("Saving record in single table inheritance failed: " . $e->getMessage());
}
}
public function testQuery()
{
//$this->_createManager();
$query = $this->conn->createQuery();
$query->select("m.*")->from("STI_Manager m");
//echo $query->getSql();
//$managers = $query->execute();
}
}
......
......@@ -85,7 +85,7 @@ class Doctrine_Query_MultiJoin2_TestCase extends Doctrine_UnitTestCase
->execute();
// Test that accessing a loaded (but empty) relation doesnt trigger an extra query
$this->assertEqual($queryCount + 1, $this->connection->count());
$this->assertEqual(0, count($categories[0]->subCategories));
$categories[0]->subCategories;
$this->assertEqual($queryCount + 1, $this->connection->count());
} catch (Doctrine_Exception $e) {
......
......@@ -101,6 +101,27 @@ class Doctrine_Query_TestCase extends Doctrine_UnitTestCase
//Doctrine::dump($q->getCachedForm(array('foo' => 'bar')));
$this->assertEqual($q->parseClause("CONCAT('u.name', u.name)"), "'u.name' || e.name");
}
public function testUsingDuplicateClassAliasThrowsException()
{
$q = new Doctrine_Query();
$q->from('User u')->leftJoin('u.Phonenumber u');
try {
$q->getSqlQuery();
$this->fail();
} catch (Doctrine_Query_Exception $e) {
$this->pass();
}
$q = new Doctrine_Query();
$q->parseDqlQuery('FROM User u, u.Phonenumber u');
try {
$q->getSqlQuery();
$this->fail();
} catch (Doctrine_Query_Exception $e) {
$this->pass();
}
}
}
class MyQuery extends Doctrine_Query
{
......
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