diff --git a/lib/Doctrine/ClassMetadata.php b/lib/Doctrine/ClassMetadata.php
index 84b4c0c30..4db380493 100644
--- a/lib/Doctrine/ClassMetadata.php
+++ b/lib/Doctrine/ClassMetadata.php
@@ -1,4 +1,4 @@
- null,
'treeOptions' => null,
'queryParts' => array()
- );
-
+ );
+
/**
* Inheritance options.
*/
protected $_inheritanceOptions = array(
- // JOINED & TABLE_PER_CLASS options
+ // JOINED & TABLE_PER_CLASS options
'discriminatorColumn' => null,
'discriminatorMap' => array(),
- // JOINED options
+ // JOINED options
'joinSubclasses' => true
- );
-
+ );
+
/**
* Specific options that can be set for the database table the class is mapped to.
* Some of them are dbms specific and they are only used if the table is generated
* by Doctrine (NOT when using Migrations).
- *
+ *
* -- type table type (mysql example: INNODB)
*
* -- charset character set
@@ -252,29 +251,29 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
'collate' => null,
'indexes' => array(),
'checks' => array()
- );
-
+ );
+
/**
* @var array $_invokedMethods method invoker cache
*/
protected $_invokedMethods = array();
-
-
+
+
/**
* Constructs a new ClassMetadata instance.
*
* @param string $entityName Name of the entity class the metadata info is used for.
*/
public function __construct($entityName, Doctrine_Connection $conn)
- {
+ {
$this->_entityName = $entityName;
$this->_rootEntityName = $entityName;
$this->_conn = $conn;
$this->_parser = new Doctrine_Relation_Parser($this);
$this->_filters[] = new Doctrine_Record_Filter_Standard();
- $this->setConfigurableParent($this->_conn);
+ $this->setConfigurableParent($this->_conn);
}
-
+
/**
*
*/
@@ -282,7 +281,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_conn;
}
-
+
/**
* getComponentName
*
@@ -292,7 +291,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_entityName;
}
-
+
/**
* Gets the name of the root class of the entity hierarchy. If the entity described
* by the ClassMetadata is not participating in a hierarchy, this is the same as the
@@ -304,7 +303,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_rootEntityName;
}
-
+
/**
* @deprecated
*/
@@ -312,19 +311,22 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->getClassName();
}
-
+
/**
* Checks whether a field is part of the 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),
+ * @return boolean TRUE if the field is part of the table identifier/primary key field(s),
* FALSE otherwise.
*/
public function isIdentifier($fieldName)
{
- return in_array($fieldName, $this->getIdentifier());
+ if ($this->_identifierType != Doctrine::IDENTIFIER_COMPOSITE) {
+ return $fieldName === $this->_identifier[0];
+ }
+ return in_array($fieldName, $this->_identifier);
}
-
+
/**
* addIndex
*
@@ -350,7 +352,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return false;
}
-
+
/**
* setOption
* sets an option and returns this object in order to
@@ -365,21 +367,21 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
public function setOption($name, $value)
{
/*switch ($name) {
- case 'tableName':
- case 'index':
- case 'sequenceName':
- case 'type':
- case 'charset':
- case 'collation':
- case 'collate':
- return $this->setTableOption($name, $value);
- case 'enumMap':
- $this->_enumMap = $value;
- return;
- }*/
+ case 'tableName':
+ case 'index':
+ case 'sequenceName':
+ case 'type':
+ case 'charset':
+ case 'collation':
+ case 'collate':
+ return $this->setTableOption($name, $value);
+ case 'enumMap':
+ $this->_enumMap = $value;
+ return;
+ }*/
$this->_options[$name] = $value;
}
-
+
/**
* Sets a table option.
*/
@@ -388,9 +390,9 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ( ! array_key_exists($name, $this->_tableOptions)) {
throw new Doctrine_ClassMetadata_Exception("Unknown table option: '$name'.");
}
- $this->_tableOptions[$name] = $value;
+ $this->_tableOptions[$name] = $value;
}
-
+
/**
* Gets a table option.
*/
@@ -399,16 +401,16 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ( ! array_key_exists($name, $this->_tableOptions)) {
throw new Doctrine_ClassMetadata_Exception("Unknown table option: '$name'.");
}
-
+
return $this->_tableOptions[$name];
}
-
+
public function getBehaviorForMethod($method)
{
return (isset($this->_invokedMethods[$method])) ?
- $this->_invokedMethods[$method] : false;
+ $this->_invokedMethods[$method] : false;
}
-
+
public function addBehaviorMethod($method, $behavior)
{
$this->_invokedMethods[$method] = $class;
@@ -430,7 +432,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
}
return null;
}
-
+
/**
* getOptions
* returns all options of this table and the associated values
@@ -441,7 +443,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_options;
}
-
+
/**
* getTableOptions
* returns all table options.
@@ -452,7 +454,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_tableOptions;
}
-
+
/**
* getColumnName
*
@@ -466,9 +468,9 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
public function getColumnName($fieldName)
{
return isset($this->_columnNames[$fieldName]) ?
- $this->_columnNames[$fieldName] : $fieldName;
+ $this->_columnNames[$fieldName] : $fieldName;
}
-
+
/**
* @deprecated
*/
@@ -476,17 +478,17 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->getColumnMapping($columnName);
}
-
+
public function getColumnMapping($columnName)
{
return isset($this->_mappedColumns[$columnName]) ?
- $this->_mappedColumns[$columnName] : false;
+ $this->_mappedColumns[$columnName] : false;
}
-
+
/**
* getFieldName
- *
- * returns the field name for a column name
+ *
+ * returns the field name for a column name
* if no field name can be found the column name is returned.
*
* @param string $columnName column name
@@ -495,9 +497,9 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
public function getFieldName($columnName)
{
return isset($this->_fieldNames[$columnName]) ?
- $this->_fieldNames[$columnName] : $columnName;
+ $this->_fieldNames[$columnName] : $columnName;
}
-
+
/**
* @deprecated
*/
@@ -507,12 +509,12 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$this->setColumn($name, $options['type'], $options['length'], $options);
}
}
-
+
/**
* Maps a column of the class' database table to a field of the entity.
*
* @param string $name The name of the column to map. Syntax: columnName [as propertyName].
- * The property name is optional. If not used the column will be
+ * The property name is optional. If not used the column will be
* mapped to a property with the same name.
* @param string $type The type of the column.
* @param integer $length The length of the column.
@@ -524,6 +526,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
*/
public function mapColumn($name, $type, $length = null, $options = array(), $prepend = false)
{
+ // converts 0 => 'primary' to 'primary' => true etc.
foreach ($options as $k => $option) {
if (is_numeric($k)) {
if ( ! empty($option) && $option !== false) {
@@ -532,7 +535,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
unset($options[$k]);
}
}
-
+
// extract column name & field name
$parts = explode(' as ', $name);
if (count($parts) > 1) {
@@ -541,11 +544,11 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$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);
@@ -553,56 +556,68 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$this->_columnNames[$fieldName] = $name;
$this->_fieldNames[$name] = $fieldName;
}
-
- if ($length == null) {
- switch ($type) {
- case 'string':
- case 'clob':
- case 'float':
- case 'integer':
- case 'array':
- case 'object':
- case 'blob':
- case 'gzip':
- // use php int max
- $length = 2147483647;
- break;
- case 'boolean':
- $length = 1;
- case 'date':
- // YYYY-MM-DD ISO 8601
- $length = 10;
- case 'time':
- // HH:NN:SS+00:00 ISO 8601
- $length = 14;
- case 'timestamp':
- // YYYY-MM-DDTHH:MM:SS+00:00 ISO 8601
- $length = 25;
- break;
- }
- }
+ // Inspect & fill $options
+
+ if ($length == null) {
+ $length = $this->_getDefaultLength($type);
+ }
+
$options['type'] = $type;
$options['length'] = $length;
+ if ( ! $this->_hasDefaultValues && isset($options['default'])) {
+ $this->_hasDefaultValues = true;
+ }
+ if ( ! empty($options['primary'])) {
+ if ( ! in_array($fieldName, $this->_identifier)) {
+ $this->_identifier[] = $fieldName;
+ }
+ /*if (isset($options['autoincrement']) && $options['autoincrement'] === true) {
+
+ }*/
+ }
+ /*
+ if ( ! isset($options['immutable'])) {
+ $options['immutable'] = false;
+ }*/
+
if ($prepend) {
$this->_mappedColumns = array_merge(array($name => $options), $this->_mappedColumns);
} else {
$this->_mappedColumns[$name] = $options;
}
- if ( ! empty($options['primary'])) {
- if ( ! in_array($fieldName, $this->_identifier)) {
- $this->_identifier[] = $fieldName;
- }
- }
- if (isset($options['default'])) {
- $this->_hasDefaultValues = true;
- }
-
$this->_columnCount++;
}
-
+
+ private function _getDefaultLength($type)
+ {
+ switch ($type) {
+ case 'string':
+ case 'clob':
+ case 'float':
+ case 'integer':
+ case 'array':
+ case 'object':
+ case 'blob':
+ case 'gzip':
+ // use php int max
+ return 2147483647;
+ case 'boolean':
+ return 1;
+ case 'date':
+ // YYYY-MM-DD ISO 8601
+ return 10;
+ case 'time':
+ // HH:NN:SS+00:00 ISO 8601
+ return 14;
+ case 'timestamp':
+ // YYYY-MM-DDTHH:MM:SS+00:00 ISO 8601
+ return 25;
+ }
+ }
+
/**
* setColumn
*
@@ -620,7 +635,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->mapColumn($name, $type, $length, $options, $prepend);
}
-
+
/**
* Gets the names of all validators that are applied on a field.
*
@@ -631,9 +646,9 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
$columnName = $this->getColumnName($fieldName);
return isset($this->_mappedColumns[$columnName]['validators']) ?
- $this->_mappedColumns[$columnName]['validators'] : array();
+ $this->_mappedColumns[$columnName]['validators'] : array();
}
-
+
/**
* Checks whether the class mapped class has a default value on any field.
*
@@ -663,7 +678,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return null;
}
}
-
+
/**
* Gets the identifier (primary key) field(s) of the mapped class.
*
@@ -674,7 +689,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_identifier;
}
-
+
/**
* Gets the identifier (primary key) field(s) of the mapped class.
*
@@ -684,7 +699,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_identifier;
}
-
+
public function setIdentifier(array $identifier)
{
$this->_identifier = $identifier;
@@ -694,14 +709,14 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
* Gets the type of the identifier (primary key) used by the mapped class. The type
* can be either Doctrine::IDENTIFIER_NATURAL, Doctrine::IDENTIFIER_AUTOINCREMENT,
* Doctrine::IDENTIFIER_SEQUENCE or Doctrine::IDENTIFIER_COMPOSITE.
- *
+ *
* @return integer
*/
public function getIdentifierType()
{
return $this->_identifierType;
}
-
+
/**
* Sets the identifier type used by the mapped class.
*/
@@ -719,12 +734,12 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return isset($this->_mappedColumns[$columnName]);
}
-
+
public function hasMappedColumn($columnName)
{
return isset($this->_mappedColumns[$columnName]);
}
-
+
/**
* hasField
* @return boolean
@@ -733,7 +748,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return isset($this->_columnNames[$fieldName]);
}
-
+
/**
* @param string $fieldName
* @return array
@@ -756,24 +771,24 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
* @return mixed
*/
public function enumValue($fieldName, $index)
- {
+ {
if ($index instanceof Doctrine_Null) {
return $index;
}
-
+
if (isset($this->_enumValues[$fieldName][$index])) {
return $this->_enumValues[$fieldName][$index];
}
-
+
$columnName = $this->getColumnName($fieldName);
if ( ! $this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM) &&
- isset($this->_mappedColumns[$columnName]['values'][$index])) {
+ isset($this->_mappedColumns[$columnName]['values'][$index])) {
$enumValue = $this->_mappedColumns[$columnName]['values'][$index];
} else {
$enumValue = $index;
}
$this->_enumValues[$fieldName][$index] = $enumValue;
-
+
return $enumValue;
}
@@ -791,10 +806,10 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ($index === false || ! $this->_conn->getAttribute(Doctrine::ATTR_USE_NATIVE_ENUM)) {
return $index;
}
-
+
return $value;
}
-
+
/**
* getColumnCount
*
@@ -805,7 +820,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_columnCount;
}
-
+
/**
* getMappedColumnCount
*
@@ -815,9 +830,9 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_columnCount;
}
-
+
/**
- *
+ *
* @return string The name of the accessor (getter) method or NULL if the field does
* not have a custom accessor.
*/
@@ -825,11 +840,11 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
$columnName = $this->getColumnName($fieldName);
return isset($this->_mappedColumns[$columnName]['accessor']) ?
- $this->_mappedColumns[$columnName]['accessor'] : null;
+ $this->_mappedColumns[$columnName]['accessor'] : null;
}
-
+
/**
- *
+ *
* @return string The name of the mutator (setter) method or NULL if the field does
* not have a custom mutator.
*/
@@ -837,7 +852,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
$columnName = $this->getColumnName($fieldName);
return isset($this->_mappedColumns[$columnName]['mutator']) ?
- $this->_mappedColumns[$columnName]['mutator'] : null;
+ $this->_mappedColumns[$columnName]['mutator'] : null;
}
/**
@@ -850,7 +865,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_mappedColumns;
}
-
+
/**
* Gets all mapped columns and their mapping definitions.
*
@@ -869,7 +884,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
*/
public function removeColumn($fieldName)
{
- $columnName = array_search($fieldName, $this->_fieldNames);
+ $columnName = array_search($fieldName, $this->_fieldNames);
unset($this->_fieldNames[$columnName]);
@@ -878,7 +893,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return true;
}
$this->_columnCount--;
-
+
return false;
}
@@ -892,15 +907,15 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ($fieldNames === null) {
return array_keys($this->_mappedColumns);
} else {
- $columnNames = array();
- foreach ($fieldNames as $fieldName) {
- $columnNames[] = $this->getColumnName($fieldName);
- }
-
- return $columnNames;
+ $columnNames = array();
+ foreach ($fieldNames as $fieldName) {
+ $columnNames[] = $this->getColumnName($fieldName);
+ }
+
+ return $columnNames;
}
}
-
+
/**
* returns an array with all the identifier column names.
*
@@ -910,7 +925,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->getColumnNames((array) $this->getIdentifier());
}
-
+
/**
* returns an array containing all the field names.
*
@@ -930,14 +945,14 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
public function getDefinitionOf($fieldName)
{
$columnName = $this->getColumnName($fieldName);
-
+
return $this->getColumnDefinition($columnName);
}
-
+
public function getMappingForField($fieldName)
{
$columnName = $this->getColumnName($fieldName);
-
+
return $this->getColumnDefinition($columnName);
}
@@ -951,12 +966,12 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->getTypeOfColumn($this->getColumnName($fieldName));
}
-
+
public function getTypeOfField($fieldName)
{
return $this->getTypeOfColumn($this->getColumnName($fieldName));
}
-
+
/**
* getTypeOfColumn
*
@@ -966,7 +981,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return isset($this->_mappedColumns[$columnName]) ? $this->_mappedColumns[$columnName]['type'] : false;
}
-
+
/**
* Gets the (maximum) length of a field.
*/
@@ -974,7 +989,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_mappedColumns[$this->getColumnName($fieldName)]['length'];
}
-
+
/**
* getTableName
*
@@ -984,12 +999,12 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->getTableOption('tableName');
}
-
+
public function getInheritedFields()
{
-
+
}
-
+
/**
* Adds a named query.
*
@@ -999,15 +1014,15 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
*/
public function addNamedQuery($name, $query)
{
-
+
}
-
+
public function bindRelation($args, $type)
{
return $this->bind($args, $type);
}
-
- /**
+
+ /**
* DESCRIBE WHAT THIS METHOD DOES, PLEASE!
*
* @todo Name proposal: addRelation
@@ -1030,7 +1045,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$options = array_merge($args[1], $options);
$this->_parser->bind($args[0], $options);
}
-
+
/**
* hasRelation
*
@@ -1051,7 +1066,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_parser->getRelation($alias, $recursive);
}
-
+
public function getRelationParser()
{
return $this->_parser;
@@ -1067,7 +1082,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_parser->getRelations();
}
-
+
/**
* getBehaviors
* returns all behaviors attached to the class.
@@ -1079,7 +1094,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_behaviors;
}
-
+
/**
* Gets the inheritance type used by the class.
*
@@ -1089,7 +1104,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_inheritanceType;
}
-
+
/**
* Sets the subclasses of the class.
* All entity classes that participate in a hierarchy and have subclasses
@@ -1099,9 +1114,9 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
*/
public function setSubclasses(array $subclasses)
{
- $this->_subClasses = $subclasses;
+ $this->_subClasses = $subclasses;
}
-
+
/**
* Gets the names of all subclasses.
*
@@ -1111,7 +1126,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_subClasses;
}
-
+
/**
* Checks whether the class has any persistent subclasses.
*
@@ -1121,7 +1136,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return ! $this->_subClasses;
}
-
+
/**
* Gets the names of all parent classes.
*
@@ -1131,7 +1146,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_parentClasses;
}
-
+
/**
* Sets the parent class names.
*/
@@ -1142,7 +1157,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$this->_rootEntityName = array_pop($classNames);
}
}
-
+
/**
* Checks whether the class has any persistent parent classes.
*
@@ -1152,7 +1167,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return ! $this->_parentClasses;
}
-
+
/**
* Sets the inheritance type used by the class and it's subclasses.
*
@@ -1163,26 +1178,26 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ($parentClassNames = $this->getParentClasses()) {
if ($this->_conn->getClassMetadata($parentClassNames[0])->getInheritanceType() != $type) {
throw new Doctrine_ClassMetadata_Exception("All classes in an inheritance hierarchy"
- . " must share the same inheritance mapping type. Mixing is not allowed.");
+ . " must share the same inheritance mapping type. Mixing is not allowed.");
}
}
-
+
if ($type == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) {
$this->_checkRequiredDiscriminatorOptions($options);
} else if ($type == Doctrine::INHERITANCE_TYPE_JOINED) {
$this->_checkRequiredDiscriminatorOptions($options);
} else if ($type == Doctrine::INHERITANCE_TYPE_TABLE_PER_CLASS) {
;
- } else {
+ } else {
throw new Doctrine_ClassMetadata_Exception("Invalid inheritance type '$type'.");
}
-
+
$this->_inheritanceType = $type;
foreach ($options as $name => $value) {
$this->setInheritanceOption($name, $value);
}
}
-
+
/**
* Checks if the 2 options 'discriminatorColumn' and 'discriminatorMap' are present.
* If either of them is missing an exception is thrown.
@@ -1195,13 +1210,13 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
if ( ! isset($options['discriminatorColumn'])) {
throw new Doctrine_ClassMetadata_Exception("Missing option 'discriminatorColumn'."
- . " Inheritance types JOINED and SINGLE_TABLE require this option.");
+ . " Inheritance types JOINED and SINGLE_TABLE require this option.");
} else if ( ! isset($options['discriminatorMap'])) {
throw new Doctrine_ClassMetadata_Exception("Missing option 'discriminatorMap'."
- . " Inheritance types JOINED and SINGLE_TABLE require this option.");
+ . " Inheritance types JOINED and SINGLE_TABLE require this option.");
}
}
-
+
/**
* Gets an inheritance option.
*
@@ -1211,10 +1226,10 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ( ! array_key_exists($name, $this->_inheritanceOptions)) {
throw new Doctrine_ClassMetadata_Exception("Unknown inheritance option: '$name'.");
}
-
+
return $this->_inheritanceOptions[$name];
}
-
+
/**
* Gets all inheritance options.
*/
@@ -1222,7 +1237,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_inheritanceOptions;
}
-
+
/**
* Sets an inheritance option.
*/
@@ -1231,25 +1246,25 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ( ! array_key_exists($name, $this->_inheritanceOptions)) {
throw new Doctrine_ClassMetadata_Exception("Unknown inheritance option: '$name'.");
}
-
+
switch ($name) {
case 'discriminatorColumn':
if ($value !== null && ! is_string($value)) {
throw new Doctrine_ClassMetadata_Exception("Invalid value '$value' for option"
- . " 'discriminatorColumn'.");
+ . " 'discriminatorColumn'.");
}
break;
case 'discriminatorMap':
if ( ! is_array($value)) {
throw new Doctrine_ClassMetadata_Exception("Value for option 'discriminatorMap'"
- . " must be an array.");
+ . " must be an array.");
}
break;
}
-
+
$this->_inheritanceOptions[$name] = $value;
}
-
+
/**
* export
* exports this class to the database based on its mapping.
@@ -1276,7 +1291,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$columns = array();
$primary = array();
$allColumns = $this->getColumns();
-
+
// If the class is part of a Single Table Inheritance hierarchy, collect the fields
// of all classes in the hierarchy.
if ($this->_inheritanceType == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) {
@@ -1337,11 +1352,11 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$primary[] = $name;
}
}
-
+
// Collect foreign keys from the relations
$options['foreignKeys'] = array();
if ($parseForeignKeys && $this->getAttribute(Doctrine::ATTR_EXPORT)
- & Doctrine::EXPORT_CONSTRAINTS) {
+ & Doctrine::EXPORT_CONSTRAINTS) {
$constraints = array();
$emptyIntegrity = array('onUpdate' => null, 'onDelete' => null);
foreach ($this->getRelations() as $name => $relation) {
@@ -1380,16 +1395,16 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
}
$options['primary'] = $primary;
-
+
return array('tableName' => $this->getTableOption('tableName'),
'columns' => $columns,
'options' => array_merge($options, $this->getTableOptions()));
}
-
+
/**
* getTemplate
*
- * @param string $template
+ * @param string $template
* @return void
* @todo Unify under 'Behaviors'.
*/
@@ -1401,7 +1416,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return $this->_behaviors[$behaviorName];
}
-
+
/**
* @todo Unify under 'Behaviors'.
*/
@@ -1409,7 +1424,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return isset($this->_behaviors[$behaviorName]);
}
-
+
/**
* @todo Unify under 'Behaviors'.
*/
@@ -1419,7 +1434,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return $this;
}
-
+
/**
* @todo Unify under 'Behaviors'.
*/
@@ -1427,7 +1442,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_generators;
}
-
+
/**
* @todo Unify under 'Behaviors'.
*/
@@ -1439,7 +1454,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return $this->_generators[$plugin];
}
-
+
/**
* @todo Unify under 'Behaviors'.
*/
@@ -1447,20 +1462,20 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return isset($this->_generators[$generator]);
}
-
+
/**
* @todo Unify under 'Behaviors'.
*/
public function addGenerator(Doctrine_Record_Generator $generator, $name = null)
{
- if ($name === null) {
+ if ($name === null) {
$this->_generators[] = $generator;
} else {
$this->_generators[$name] = $generator;
}
return $this;
}
-
+
/**
* loadBehavior
*
@@ -1471,16 +1486,16 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
$this->actAs($behavior, $options);
}
-
+
/**
* @todo Unify under 'Behaviors'.
*/
public function loadGenerator(Doctrine_Record_Generator $generator)
{
- $generator->initialize($this->_table);
+ $generator->initialize($this->_table);
$this->addGenerator($generator, get_class($generator));
}
-
+
/**
* unshiftFilter
*
@@ -1492,10 +1507,10 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
$filter->setTable($this);
array_unshift($this->_filters, $filter);
-
+
return $this;
}
-
+
/**
* getTree
*
@@ -1510,13 +1525,13 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
if ( ! $this->_tree) {
$options = $this->getOption('treeOptions') ? $this->getOption('treeOptions') : array();
$this->_tree = Doctrine_Tree::factory($this,
- $this->getOption('treeImpl'), $options);
+ $this->getOption('treeImpl'), $options);
}
return $this->_tree;
}
return false;
}
-
+
/**
* isTree
*
@@ -1529,7 +1544,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return ( ! is_null($this->getOption('treeImpl'))) ? true : false;
}
-
+
/**
* getFilters
*
@@ -1540,7 +1555,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return $this->_filters;
}
-
+
/**
* Checks whether a persistent field is inherited from a superclass.
*
@@ -1550,7 +1565,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return isset($this->_mappedColumns[$this->getColumnName($fieldName)]['inherited']);
}
-
+
/**
* bindQueryParts
* binds query parts to given component
@@ -1560,7 +1575,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
*/
public function bindQueryParts(array $queryParts)
{
- $this->_options['queryParts'] = $queryParts;
+ $this->_options['queryParts'] = $queryParts;
return $this;
}
@@ -1574,14 +1589,14 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
*/
public function bindQueryPart($queryPart, $value)
{
- $this->_options['queryParts'][$queryPart] = $value;
+ $this->_options['queryParts'][$queryPart] = $value;
return $this;
}
-
+
/**
* getBoundQueryPart
*
- * @param string $queryPart
+ * @param string $queryPart
* @return string $queryPart
*/
public function getBoundQueryPart($queryPart)
@@ -1601,7 +1616,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
$this->setTableOption('tableName', $this->_conn->formatter->getTableName($tableName));
}
-
+
/**
* Serializes the metadata.
*
@@ -1616,7 +1631,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
//return serialize($contents);
return "";
}
-
+
/**
* Reconstructs the metadata class from it's serialized representation.
*
@@ -1628,37 +1643,37 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return true;
}
-
+
/**
* @todo Implementation.
*/
public function oneToOne($targetEntity, $definition)
{
-
+
}
-
+
/**
* @todo Implementation.
*/
public function oneToMany($targetEntity, $definition)
{
-
+
}
-
+
/**
* @todo Implementation.
*/
public function manyToOne($targetEntity, $definition)
{
-
+
}
-
+
/**
* @todo Implementation.
*/
public function manyToMany($targetEntity, $definition)
{
-
+
}
/**
@@ -1697,7 +1712,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return $this;
}
-
+
/**
* check
* adds a check constraint
@@ -1716,10 +1731,10 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
} else {
$this->_addCheckConstraint($constraint, $name);
}
-
+
return $this;
}
-
+
protected function _addCheckConstraint($definition, $name)
{
if (is_string($name)) {
@@ -1728,53 +1743,75 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
$this->_tableOptions['checks'][] = $definition;
}
}
-
+
/**
* Registers a custom mapper for the entity class.
*
* @param string $mapperClassName The class name of the custom mapper.
+ * @deprecated
*/
public function setCustomMapperClass($mapperClassName)
{
if ( ! is_subclass_of($mapperClassName, 'Doctrine_Mapper')) {
throw new Doctrine_ClassMetadata_Exception("The custom mapper must be a subclass"
- . " of Doctrine_Mapper.");
+ . " of Doctrine_Mapper.");
}
- $this->_customMapperClassName = $mapperClassName;
+ $this->_customRepositoryClassName = $mapperClassName;
}
+ /**
+ * Registers a custom mapper for the entity class.
+ *
+ * @param string $mapperClassName The class name of the custom mapper.
+ * @deprecated
+ */
+ public function setCustomRepositoryClass($repositoryClassName)
+ {
+ if ( ! is_subclass_of($repositoryClassName, 'Doctrine_EntityRepository')) {
+ throw new Doctrine_ClassMetadata_Exception("The custom repository must be a subclass"
+ . " of Doctrine_EntityRepository.");
+ }
+ $this->_customRepositoryClassName = $repositoryClassName;
+ }
+
/**
* Gets the name of the custom mapper class used for the entity class.
*
* @return string|null The name of the custom mapper class or NULL if the entity
* class does not have a custom mapper class.
+ * @deprecated
*/
public function getCustomMapperClass()
{
- return $this->_customMapperClassName;
+ return $this->_customRepositoryClassName;
}
+ public function getCustomRepositoryClass()
+ {
+ return $this->_customRepositoryClassName;
+ }
+
/**
* @todo Thoughts & Implementation.
*/
- public function setType($type)
+ public function setEntityType($type)
{
//Doctrine::CLASSTYPE_ENTITY
//Doctrine::CLASSTYPE_MAPPED_SUPERCLASS
//Doctrine::CLASSTYPE_TRANSIENT
}
-
+
/**
- *
+ *
* @todo Implementation. Replaces the bindComponent() methods on the old Doctrine_Manager.
* Binding an Entity to a specific EntityManager in 2.0 is the same as binding
* it to a Connection in 1.0.
*/
public function bindToEntityManager($emName)
{
-
+
}
-
+
/**
* @todo Implementation. Immutable entities can not be updated or deleted once
* they are created. This means the entity can only be modified as long as it's
@@ -1784,12 +1821,12 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
{
return false;
}
-
+
public function isDiscriminatorColumn($columnName)
{
return $columnName === $this->_inheritanceOptions['discriminatorColumn'];
}
-
+
/**
* hasOne
* binds One-to-One aggregate relation
@@ -1821,7 +1858,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
return $this;
}
-
+
public function hasAttribute($key)
{
switch ($key) {
@@ -1837,7 +1874,7 @@ class Doctrine_ClassMetadata extends Doctrine_Configurable implements Serializab
}
}
-
+
/**
*
*/
diff --git a/lib/Doctrine/Collection.php b/lib/Doctrine/Collection.php
index c1c9ec22e..d83bce568 100644
--- a/lib/Doctrine/Collection.php
+++ b/lib/Doctrine/Collection.php
@@ -449,7 +449,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
} else {
// @todo does not take composite keys into account
- $list[] = $record->getIncremented();
+ $ids = $record->identifier();
+ $list[] = count($ids) > 0 ? array_pop($ids) : null;
}
}
@@ -564,7 +565,9 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
if ( ! isset($name)) {
foreach ($this->data as $record) {
- $value = $record->getIncremented();
+ // FIXME: composite key support
+ $ids = $record->identifier();
+ $value = count($ids) > 0 ? array_pop($ids) : null;
if ($value !== null) {
$list[] = $value;
}
@@ -583,7 +586,8 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
} else {
foreach ($this->data as $record) {
- $value = $record->getIncremented();
+ $ids = $record->identifier();
+ $value = count($ids) > 0 ? array_pop($ids) : null;
if ($value !== null) {
$list[] = $value;
}
diff --git a/lib/Doctrine/Connection.php b/lib/Doctrine/Connection.php
index 2cabb24ab..cacfa6136 100644
--- a/lib/Doctrine/Connection.php
+++ b/lib/Doctrine/Connection.php
@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* .
*/
-Doctrine::autoload('Doctrine_Configurable');
+
/**
* Doctrine_Connection
*
@@ -56,16 +56,94 @@ Doctrine::autoload('Doctrine_Configurable');
* @todo Split up into Doctrine::DBAL::Connection & Doctrine::ORM::EntityManager.
* Doctrine::DBAL::Connection must have no dependencies on ORM components since
* it sits one layer below.
+ * Right now, this is the unification of these two classes.
*/
abstract class Doctrine_Connection extends Doctrine_Configurable implements Countable, IteratorAggregate
{
+ /*
+ * ----------- Connection attributes ---------------
+ */
/**
* The PDO database handle.
*
* @var PDO
*/
protected $dbh;
-
+
+ /**
+ * $_name
+ *
+ * Name of the connection
+ *
+ * @var string $_name
+ */
+ protected $_name;
+
+ /**
+ * The name of this connection driver.
+ *
+ * @var string $driverName
+ */
+ protected $driverName;
+
+ /**
+ * Whether or not a connection has been established.
+ *
+ * @var boolean $isConnected
+ */
+ protected $isConnected = false;
+
+ /**
+ * An array containing all features this driver supports, keys representing feature
+ * names and values as one of the following (true, false, 'emulated').
+ *
+ * @var array $supported
+ */
+ protected $supported = array();
+
+ /**
+ * @var array $properties an array of connection properties
+ */
+ protected $properties = array(
+ 'sql_comments' => array(array('start' => '--', 'end' => "\n", 'escape' => false),
+ array('start' => '/*', 'end' => '*/', 'escape' => false)),
+ 'identifier_quoting' => array('start' => '"', 'end' => '"','escape' => '"'),
+ 'string_quoting' => array('start' => "'", 'end' => "'", 'escape' => false,
+ 'escape_pattern' => false),
+ 'wildcards' => array('%', '_'),
+ 'varchar_max_length' => 255,
+ );
+
+ /**
+ * @var array $serverInfo
+ */
+ protected $serverInfo = array();
+
+ /**
+ *
+ */
+ protected $options = array();
+
+ /**
+ * List of all available drivers.
+ *
+ * @var array $availableDrivers
+ */
+ private static $availableDrivers = array(
+ 'Mysql', 'Pgsql', 'Oracle', 'Informix', 'Mssql', 'Sqlite', 'Firebird'
+ );
+
+ /**
+ * The query count. Represents the number of executed database queries by the connection.
+ *
+ * @var integer
+ */
+ protected $_count = 0;
+
+
+ /*
+ * ----------- EntityManager attributes ---------------
+ */
/**
* The metadata factory is used to retrieve the metadata of entity classes.
*
@@ -81,38 +159,18 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
* @todo package:orm
*/
protected $_mappers = array();
-
+
/**
- * $_name
+ * The EntityRepository instances.
*
- * Name of the connection
- *
- * @var string $_name
+ * @var array
*/
- protected $_name;
+ private $_repositories = array();
- /**
- * The name of this connection driver.
- *
- * @var string $driverName
+
+ /*
+ * ----------- Mixed attributes (need to split up) ---------------
*/
- protected $driverName;
-
- /**
- * Whether or not a connection has been established.
- *
- * @var boolean $isConnected
- */
- protected $isConnected = false;
-
- /**
- * An array containing all features this driver supports, keys representing feature
- * names and values as one of the following (true, false, 'emulated').
- *
- * @var array $supported
- */
- protected $supported = array();
-
/**
* @var array $pendingAttributes An array of pending attributes. When setting attributes
* no connection is needed. When connected all the pending
@@ -158,50 +216,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
'formatter' => false,
'util' => false,
);
-
- /**
- * @var array $properties an array of connection properties
- */
- protected $properties = array('sql_comments' => array(array('start' => '--', 'end' => "\n", 'escape' => false),
- array('start' => '/*', 'end' => '*/', 'escape' => false)),
- 'identifier_quoting' => array('start' => '"', 'end' => '"','escape' => '"'),
- 'string_quoting' => array('start' => "'",
- 'end' => "'",
- 'escape' => false,
- 'escape_pattern' => false),
- 'wildcards' => array('%', '_'),
- 'varchar_max_length' => 255,
- );
-
- /**
- * @var array $serverInfo
- */
- protected $serverInfo = array();
-
- /**
- *
- */
- protected $options = array();
-
- /**
- * @var array $availableDrivers an array containing all available drivers
- */
- private static $availableDrivers = array(
- 'Mysql',
- 'Pgsql',
- 'Oracle',
- 'Informix',
- 'Mssql',
- 'Sqlite',
- 'Firebird'
- );
-
- /**
- * The query count. Represents the number of executed database queries by the connection.
- *
- * @var integer
- */
- protected $_count = 0;
+
/**
* the constructor
@@ -239,7 +254,11 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->getAttribute(Doctrine::ATTR_LISTENER)->onOpen($this);
}
-
+
+
+ /*
+ * ----------- Connection methods ---------------
+ */
/**
* getOption
*
@@ -267,39 +286,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return $this->options[$option] = $value;
}
-
- /**
- * getAttribute
- * retrieves a database connection attribute
- *
- * @param integer $attribute
- * @return mixed
- */
- public function getAttribute($attribute)
- {
- if ($attribute >= 100) {
- if ( ! isset($this->_attributes[$attribute])) {
- return parent::getAttribute($attribute);
- }
- return $this->_attributes[$attribute];
- }
-
- if ($this->isConnected) {
- try {
- return $this->dbh->getAttribute($attribute);
- } catch (Exception $e) {
- throw new Doctrine_Connection_Exception('Attribute ' . $attribute . ' not found.');
- }
- } else {
- if ( ! isset($this->pendingAttributes[$attribute])) {
- $this->connect();
- $this->getAttribute($attribute);
- }
-
- return $this->pendingAttributes[$attribute];
- }
- }
-
+
/**
* returns an array of available PDO drivers
*/
@@ -307,32 +294,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return PDO::getAvailableDrivers();
}
-
- /**
- * setAttribute
- * sets an attribute
- *
- * @todo why check for >= 100? has this any special meaning when creating
- * attributes?
- *
- * @param integer $attribute
- * @param mixed $value
- * @return boolean
- */
- public function setAttribute($attribute, $value)
- {
- if ($attribute >= 100) {
- parent::setAttribute($attribute, $value);
- } else {
- if ($this->isConnected) {
- $this->dbh->setAttribute($attribute, $value);
- } else {
- $this->pendingAttributes[$attribute] = $value;
- }
- }
- return $this;
- }
-
+
/**
* getName
* returns the name of this driver
@@ -343,7 +305,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return $this->_name;
}
-
+
/**
* setName
*
@@ -368,56 +330,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return $this->driverName;
}
-
- /**
- * __get
- * lazy loads given module and returns it
- *
- * @see Doctrine_DataDict
- * @see Doctrine_Expression
- * @see Doctrine_Export
- * @see Doctrine_Transaction
- * @see Doctrine_Connection::$modules all availible modules
- * @param string $name the name of the module to get
- * @throws Doctrine_Connection_Exception if trying to get an unknown module
- * @return Doctrine_Connection_Module connection module
- */
- public function __get($name)
- {
- if (isset($this->properties[$name])) {
- return $this->properties[$name];
- }
-
- if ( ! isset($this->modules[$name])) {
- throw new Doctrine_Connection_Exception('Unknown module / property ' . $name);
- }
- if ($this->modules[$name] === false) {
- switch ($name) {
- case 'unitOfWork':
- $this->modules[$name] = new Doctrine_Connection_UnitOfWork($this);
- break;
- case 'formatter':
- $this->modules[$name] = new Doctrine_Formatter($this);
- break;
- default:
- $class = 'Doctrine_' . ucwords($name) . '_' . $this->getDriverName();
- $this->modules[$name] = new $class($this);
- }
- }
-
- return $this->modules[$name];
- }
-
- /**
- * returns the manager that created this connection
- *
- * @return Doctrine_Manager
- */
- public function getManager()
- {
- return $this->getParent();
- }
-
+
/**
* returns the database handler which this connection uses
*
@@ -429,7 +342,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
return $this->dbh;
}
-
+
/**
* Establishes the connection with the database.
*
@@ -510,7 +423,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
&& ($this->supported[$feature] === 'emulated'
|| $this->supported[$feature]));
}
-
+
/**
* Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
* query, except that if there is already a row in the table with the same
@@ -849,32 +762,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return $this->execute($statement, $params)->fetchAll(Doctrine::FETCH_BOTH);
}
-
- /**
- * query
- * queries the database using Doctrine Query Language
- * returns a collection of Doctrine_Record objects
- *
- *
- * $users = $conn->query('SELECT u.* FROM User u');
- *
- * $users = $conn->query('SELECT u.* FROM User u WHERE u.name LIKE ?', array('someone'));
- *
- *
- * @param string $query DQL query
- * @param array $params query parameters
- * @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD
- * @see Doctrine_Query
- * @return Doctrine_Collection Collection of Doctrine_Record objects
- * @todo package:orm
- */
- public function query($query, array $params = array(), $hydrationMode = null)
- {
- $parser = new Doctrine_Query($this);
-
- return $parser->query($query, $params, $hydrationMode);
- }
-
+
/**
* prepare
*
@@ -903,37 +791,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->rethrowException($e, $this);
}
-
- /**
- * query
- * queries the database using Doctrine Query Language and returns
- * the first record found
- *
- *
- * $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.id = ?', array(1));
- *
- * $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.name LIKE ? AND u.password = ?',
- * array('someone', 'password')
- * );
- *
- *
- * @param string $query DQL query
- * @param array $params query parameters
- * @see Doctrine_Query
- * @return Doctrine_Record|false Doctrine_Record object on success,
- * boolean false on failure
- */
- public function queryOne($query, array $params = array())
- {
- $parser = new Doctrine_Query($this);
-
- $coll = $parser->query($query, $params);
- if ( ! $coll->contains(0)) {
- return false;
- }
- return $coll[0];
- }
-
+
/**
* queries the database with limit and offset
* added to the query and returns a Doctrine_Connection_Statement object
@@ -977,7 +835,6 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
try {
if ( ! empty($params)) {
- //echo $query . "
";
$stmt = $this->prepare($query);
$stmt->execute($params);
return $stmt;
@@ -987,14 +844,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->getAttribute(Doctrine::ATTR_LISTENER)->preQuery($event);
if ( ! $event->skipOperation) {
- //try {
- $stmt = $this->dbh->query($query);
- /*} catch (Exception $e) {
- if (strstr($e->getMessage(), 'no such column')) {
- echo $query . "
";
- }
- }*/
-
+ $stmt = $this->dbh->query($query);
$this->_count++;
}
$this->getAttribute(Doctrine::ATTR_LISTENER)->postQuery($event);
@@ -1021,6 +871,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
if ( ! empty($params)) {
$stmt = $this->prepare($query);
$stmt->execute($params);
+
return $stmt->rowCount();
} else {
$event = new Doctrine_Event($this, Doctrine_Event::CONN_EXEC, $query, $params);
@@ -1052,7 +903,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->getListener()->preError($event);
$name = 'Doctrine_Connection_' . $this->driverName . '_Exception';
-
+
$exc = new $name($e->getMessage(), (int) $e->getCode());
if ( ! is_array($e->errorInfo)) {
$e->errorInfo = array(null, null, null, null);
@@ -1065,151 +916,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
$this->getListener()->postError($event);
}
-
- /**
- * hasTable
- * whether or not this connection has table $name initialized
- *
- * @param mixed $name
- * @return boolean
- * @deprecated
- * @todo package:orm
- */
- public function hasTable($name)
- {
- return isset($this->tables[$name]);
- }
-
- /**
- * Returns the metadata for a class.
- *
- * @return Doctrine_Metadata
- * @deprecated Use getClassMetadata()
- * @todo package:orm
- */
- public function getMetadata($className)
- {
- return $this->getClassMetadata($className);
- }
-
- /**
- * Returns the metadata for a class.
- *
- * @return Doctrine_Metadata
- * @todo package:orm
- */
- public function getClassMetadata($className)
- {
- if ( ! $this->_metadataFactory) {
- $this->_metadataFactory = new Doctrine_ClassMetadata_Factory($this,
- new Doctrine_ClassMetadata_CodeDriver());
- }
-
- return $this->_metadataFactory->getMetadataFor($className);
- }
-
- /**
- * Sets the driver that is used to obtain metadata informations about entity
- * classes.
- *
- * @param $driver The driver to use.
- * @todo package:orm
- */
- public function setClassMetadataDriver($driver)
- {
- $this->_metadataFactory->setDriver($driver);
- }
- /**
- * 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.
- *
- * @param string $entityClassName The name of the entity class.
- * @return Doctrine_Mapper The mapper object.
- * @todo package:orm
- */
- /*public function getMapper($entityName)
- {
- if (isset($this->_mappers[$entityName])) {
- return $this->_mappers[$entityName];
- }
-
- $metadata = $this->getClassMetadata($entityName);
- $customMapperClassName = $metadata->getCustomMapperClass();
- if ($customMapperClassName !== null) {
- $mapper = new $customMapperClassName($entityName, $metadata);
- } else {
- // instantiate correct mapper type
- $inheritanceType = $metadata->getInheritanceType();
- if ($inheritanceType == Doctrine::INHERITANCE_TYPE_JOINED) {
- $mapper = new Doctrine_Mapper_Joined($entityName, $metadata);
- } else if ($inheritanceType == Doctrine::INHERITANCE_TYPE_SINGLE_TABLE) {
- $mapper = new Doctrine_Mapper_SingleTable($entityName, $metadata);
- } else if ($inheritanceType == Doctrine::INHERITANCE_TYPE_TABLE_PER_CLASS) {
- $mapper = new Doctrine_Mapper_TablePerClass($entityName, $metadata);
- } else {
- throw new Doctrine_Connection_Exception("Unknown inheritance type '$inheritanceType'. Can't create mapper.");
- }
- }
-
- $this->_mappers[$entityName] = $mapper;
-
- return $mapper;
- }*/
-
- /**
- * 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.
- *
- * @param string $entityClassName The name of the entity class.
- * @return Doctrine_Mapper The mapper object.
- * @todo package:orm
- */
- public function getMapper($entityName)
- {
- if (isset($this->_mappers[$entityName])) {
- return $this->_mappers[$entityName];
- }
-
- $metadata = $this->getClassMetadata($entityName);
- $customMapperClassName = $metadata->getCustomMapperClass();
- if ($customMapperClassName !== null) {
- $mapper = new $customMapperClassName($entityName, $metadata);
- } else {
- $mapper = new Doctrine_Mapper($entityName, $metadata);
- }
- $this->_mappers[$entityName] = $mapper;
-
- return $mapper;
- }
-
- /**
- * Gets all mappers that are currently maintained by the connection.
- *
- * @todo package:orm
- */
- public function getMappers()
- {
- return $this->_mappers;
- }
-
- /**
- * returns an iterator that iterates through all
- * initialized table objects
- *
- *
- * foreach ($conn as $index => $table) {
- * print $table; // get a string representation of each table object
- * }
- *
- *
- * @return ArrayIterator SPL ArrayIterator object
- */
- public function getIterator()
- {
- return new ArrayIterator($this->_mappers);
- }
-
/**
* Returns the number of queries executed by the connection.
*
@@ -1220,85 +927,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return $this->_count;
}
-
- /**
- * create
- * creates a record
- *
- * create creates a record
- * @param string $name component name
- * @return Doctrine_Record Doctrine_Record object
- * @todo Any strong reasons why this should not be removed?
- * @todo package:orm
- */
- public function create($name)
- {
- return $this->getMapper($name)->create();
- }
-
- /**
- * Creates a new Doctrine_Query object that operates on this connection.
- *
- * @return Doctrine_Query
- * @todo package:orm
- */
- public function createQuery($dql = "")
- {
- $query = new Doctrine_Query($this);
- if ( ! empty($dql)) {
- $query->parseQuery($dql);
- }
-
- return $query;
- }
-
- /**
- * flush
- * saves all the records from all tables
- * this operation is isolated using a transaction
- *
- * @throws PDOException if something went wrong at database level
- * @return void
- * @todo package:orm
- */
- public function flush()
- {
- $this->beginInternalTransaction();
- $this->unitOfWork->flush();
- $this->commit();
- }
-
- /**
- * clear
- * clears all repositories
- *
- * @return void
- * @todo package:orm
- */
- public function clear()
- {
- $this->unitOfWork->detachAll();
- foreach ($this->_mappers as $mapper) {
- $mapper->clear(); // clear identity map of each mapper
- }
- }
-
- /**
- * evictTables
- * evicts all tables
- *
- * @return void
- * @todo package:orm
- * @deprecated
- */
- public function evictTables()
- {
- $this->clear();
- $this->tables = array();
- $this->_mappers = array();
- $this->exported = array();
- }
-
+
/**
* Closes the connection.
*
@@ -1326,18 +955,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return $this->transaction->getTransactionLevel();
}
-
- /**
- * Returns the current internal transaction nesting level.
- *
- * @return integer The nesting level. A value of 0 means theres no active transaction.
- * @todo package:orm???
- */
- public function getInternalTransactionLevel()
- {
- return $this->transaction->getInternalTransactionLevel();
- }
-
+
/**
* errorCode
* Fetch the SQLSTATE associated with the last operation on the database handle
@@ -1363,48 +981,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
return $this->dbh->errorInfo();
}
-
- /**
- * getCacheDriver
- *
- * @return Doctrine_Cache_Interface
- * @deprecated Use getResultCacheDriver()
- */
- public function getCacheDriver()
- {
- return $this->getResultCacheDriver();
- }
-
- /**
- * getResultCacheDriver
- *
- * @return Doctrine_Cache_Interface
- * @todo package:orm
- */
- public function getResultCacheDriver()
- {
- if ( ! $this->getAttribute(Doctrine::ATTR_RESULT_CACHE)) {
- throw new Doctrine_Exception('Result Cache driver not initialized.');
- }
-
- return $this->getAttribute(Doctrine::ATTR_RESULT_CACHE);
- }
-
- /**
- * getQueryCacheDriver
- *
- * @return Doctrine_Cache_Interface
- * @todo package:orm
- */
- public function getQueryCacheDriver()
- {
- if ( ! $this->getAttribute(Doctrine::ATTR_QUERY_CACHE)) {
- throw new Doctrine_Exception('Query Cache driver not initialized.');
- }
-
- return $this->getAttribute(Doctrine::ATTR_QUERY_CACHE);
- }
-
+
/**
* lastInsertId
*
@@ -1439,20 +1016,7 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
{
return $this->transaction->beginTransaction($savepoint);
}
-
- /**
- * Initiates a transaction.
- *
- * This method must only be used by Doctrine itself to initiate transactions.
- * Userland-code must use {@link beginTransaction()}.
- *
- * @todo package:orm???
- */
- public function beginInternalTransaction($savepoint = null)
- {
- return $this->transaction->beginInternalTransaction($savepoint);
- }
-
+
/**
* commit
* Commit the database changes done during a transaction that is in
@@ -1564,47 +1128,491 @@ abstract class Doctrine_Connection extends Doctrine_Configurable implements Coun
return Doctrine_Lib::getConnectionAsString($this);
}
- public function hasAttribute($key)
+
+ /*
+ * ----------- EntityManager methods ---------------
+ */
+
+ /**
+ * query
+ * queries the database using Doctrine Query Language
+ * returns a collection of Doctrine_Record objects
+ *
+ *
+ * $users = $conn->query('SELECT u.* FROM User u');
+ *
+ * $users = $conn->query('SELECT u.* FROM User u WHERE u.name LIKE ?', array('someone'));
+ *
+ *
+ * @param string $query DQL query
+ * @param array $params query parameters
+ * @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD
+ * @see Doctrine_Query
+ * @return Doctrine_Collection Collection of Doctrine_Record objects
+ * @todo package:orm
+ */
+ public function query($query, array $params = array(), $hydrationMode = null)
{
- switch ($key) {
- case Doctrine::ATTR_COLL_KEY:
- case Doctrine::ATTR_LISTENER:
- case Doctrine::ATTR_RECORD_LISTENER:
- case Doctrine::ATTR_QUOTE_IDENTIFIER:
- case Doctrine::ATTR_SEQCOL_NAME:
- case Doctrine::ATTR_FIELD_CASE:
- case Doctrine::ATTR_IDXNAME_FORMAT:
- case Doctrine::ATTR_SEQNAME_FORMAT:
- case Doctrine::ATTR_DBNAME_FORMAT:
- case Doctrine::ATTR_TBLCLASS_FORMAT:
- case Doctrine::ATTR_TBLNAME_FORMAT:
- case Doctrine::ATTR_EXPORT:
- case Doctrine::ATTR_DECIMAL_PLACES:
- case Doctrine::ATTR_PORTABILITY:
- case Doctrine::ATTR_VALIDATE:
- case Doctrine::ATTR_QUERY_LIMIT:
- case Doctrine::ATTR_DEFAULT_TABLE_TYPE:
- case Doctrine::ATTR_DEF_TEXT_LENGTH:
- case Doctrine::ATTR_DEF_VARCHAR_LENGTH:
- case Doctrine::ATTR_DEF_TABLESPACE:
- case Doctrine::ATTR_EMULATE_DATABASE:
- case Doctrine::ATTR_USE_NATIVE_ENUM:
- case Doctrine::ATTR_CREATE_TABLES:
- case Doctrine::ATTR_COLL_LIMIT:
- case Doctrine::ATTR_CACHE: // deprecated
- case Doctrine::ATTR_RESULT_CACHE:
- case Doctrine::ATTR_CACHE_LIFESPAN: // deprecated
- case Doctrine::ATTR_RESULT_CACHE_LIFESPAN:
- case Doctrine::ATTR_LOAD_REFERENCES:
- case Doctrine::ATTR_THROW_EXCEPTIONS:
- case Doctrine::ATTR_QUERY_CACHE:
- case Doctrine::ATTR_QUERY_CACHE_LIFESPAN:
- case Doctrine::ATTR_MODEL_LOADING:
- case Doctrine::ATTR_METADATA_CACHE:
- case Doctrine::ATTR_METADATA_CACHE_LIFESPAN:
- return true;
- default:
- return false;
+ $parser = new Doctrine_Query($this);
+
+ return $parser->query($query, $params, $hydrationMode);
+ }
+
+ /**
+ * query
+ * queries the database using Doctrine Query Language and returns
+ * the first record found
+ *
+ *
+ * $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.id = ?', array(1));
+ *
+ * $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.name LIKE ? AND u.password = ?',
+ * array('someone', 'password')
+ * );
+ *
+ *
+ * @param string $query DQL query
+ * @param array $params query parameters
+ * @see Doctrine_Query
+ * @return Doctrine_Record|false Doctrine_Record object on success,
+ * boolean false on failure
+ */
+ public function queryOne($query, array $params = array())
+ {
+ $parser = new Doctrine_Query($this);
+
+ $coll = $parser->query($query, $params);
+ if ( ! $coll->contains(0)) {
+ return false;
+ }
+ return $coll[0];
+ }
+
+ /**
+ * hasTable
+ * whether or not this connection has table $name initialized
+ *
+ * @param mixed $name
+ * @return boolean
+ * @deprecated
+ * @todo package:orm
+ */
+ public function hasTable($name)
+ {
+ return isset($this->tables[$name]);
+ }
+
+ /**
+ * Returns the metadata for a class.
+ *
+ * @return Doctrine_Metadata
+ * @deprecated Use getClassMetadata()
+ * @todo package:orm
+ */
+ public function getMetadata($className)
+ {
+ return $this->getClassMetadata($className);
+ }
+
+ /**
+ * Returns the metadata for a class.
+ *
+ * @return Doctrine_Metadata
+ * @todo package:orm
+ */
+ public function getClassMetadata($className)
+ {
+ if ( ! $this->_metadataFactory) {
+ $this->_metadataFactory = new Doctrine_ClassMetadata_Factory($this,
+ new Doctrine_ClassMetadata_CodeDriver());
+ }
+
+ return $this->_metadataFactory->getMetadataFor($className);
+ }
+
+ /**
+ * Sets the driver that is used to obtain metadata informations about entity
+ * classes.
+ *
+ * @param $driver The driver to use.
+ * @todo package:orm
+ */
+ public function setClassMetadataDriver($driver)
+ {
+ $this->_metadataFactory->setDriver($driver);
+ }
+
+ /**
+ * 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.
+ *
+ * @param string $entityClassName The name of the entity class.
+ * @return Doctrine_Mapper The mapper object.
+ * @todo package:orm
+ */
+ public function getMapper($entityName)
+ {
+ if (isset($this->_mappers[$entityName])) {
+ return $this->_mappers[$entityName];
+ }
+
+ $metadata = $this->getClassMetadata($entityName);
+ $customMapperClassName = $metadata->getCustomMapperClass();
+ if ($customMapperClassName !== null) {
+ $mapper = new $customMapperClassName($entityName, $metadata);
+ } else {
+ $mapper = new Doctrine_Mapper($entityName, $metadata);
+ }
+ $this->_mappers[$entityName] = $mapper;
+
+ return $mapper;
+ }
+
+ /**
+ * Gets all mappers that are currently maintained by the connection.
+ *
+ * @todo package:orm
+ */
+ public function getMappers()
+ {
+ return $this->_mappers;
+ }
+
+ /**
+ * returns an iterator that iterates through all
+ * initialized table objects
+ *
+ *
+ * foreach ($conn as $index => $table) {
+ * print $table; // get a string representation of each table object
+ * }
+ *
+ *
+ * @return ArrayIterator SPL ArrayIterator object
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->_mappers);
+ }
+
+ /**
+ * create
+ * creates a record
+ *
+ * create creates a record
+ * @param string $name component name
+ * @return Doctrine_Record Doctrine_Record object
+ * @todo Any strong reasons why this should not be removed?
+ * @todo package:orm
+ */
+ public function create($name)
+ {
+ return $this->getMapper($name)->create();
+ }
+
+ /**
+ * Creates a new Doctrine_Query object that operates on this connection.
+ *
+ * @return Doctrine_Query
+ * @todo package:orm
+ */
+ public function createQuery($dql = "")
+ {
+ $query = new Doctrine_Query($this);
+ if ( ! empty($dql)) {
+ $query->parseQuery($dql);
+ }
+
+ return $query;
+ }
+
+ /**
+ * flush
+ * saves all the records from all tables
+ * this operation is isolated using a transaction
+ *
+ * @throws PDOException if something went wrong at database level
+ * @return void
+ * @todo package:orm
+ */
+ public function flush()
+ {
+ $this->beginInternalTransaction();
+ $this->unitOfWork->flush();
+ $this->commit();
+ }
+
+ /**
+ * clear
+ * clears all repositories
+ *
+ * @return void
+ * @todo package:orm
+ */
+ public function clear($entityName = null)
+ {
+ if ($entityName === null) {
+ $this->unitOfWork->detachAll();
+ foreach ($this->_mappers as $mapper) {
+ $mapper->clear(); // clear identity map of each mapper
+ }
+ } else {
+ $this->getMapper($entityName)->clear();
}
}
+
+ /**
+ * evictTables
+ * evicts all tables
+ *
+ * @return void
+ * @todo package:orm
+ * @deprecated
+ */
+ public function evictTables()
+ {
+ $this->clear();
+ $this->tables = array();
+ $this->_mappers = array();
+ $this->exported = array();
+ }
+
+ public function save(Doctrine_Record $entity, $conn = null)
+ {
+ $this->getMapper($entity->getClassName())->save($entity, $conn);
+ }
+
+ public function remove(Doctrine_Record $entity, $conn = null)
+ {
+ $this->getMapper($entity->getClassName())->delete($entity, $conn);
+ }
+
+ public function createEntity($entityName, array $data = array())
+ {
+ return $this->getMapper($entityName)->create($data);
+ }
+
+ public function detach(Doctrine_Record $entity)
+ {
+ $this->getMapper($entity->getClassName())->detach($entity);
+ }
+
+ public function removeRecord(Doctrine_Record $entity)
+ {
+ $this->getMapper($entity->getClassName())->removeRecord($entity);
+ }
+
+ public function manage(Doctrine_Record $entity)
+ {
+ $this->getMapper($entity->getClassName())->manage($entity);
+ }
+
+ public function executeNamedQuery($name, $params = array(), $hydrationMode = Doctrine::HYDRATE_RECORD)
+ {
+ return Doctrine_Manager::getInstance()
+ ->createNamedQuery($name)
+ ->execute($params, $hydrationMode);
+ }
+
+
+
+ /**
+ * Returns the current internal transaction nesting level.
+ *
+ * @return integer The nesting level. A value of 0 means theres no active transaction.
+ * @todo package:orm???
+ */
+ public function getInternalTransactionLevel()
+ {
+ return $this->transaction->getInternalTransactionLevel();
+ }
+
+ /**
+ * getCacheDriver
+ *
+ * @return Doctrine_Cache_Interface
+ * @deprecated Use getResultCacheDriver()
+ */
+ public function getCacheDriver()
+ {
+ return $this->getResultCacheDriver();
+ }
+
+ /**
+ * getResultCacheDriver
+ *
+ * @return Doctrine_Cache_Interface
+ * @todo package:orm
+ */
+ public function getResultCacheDriver()
+ {
+ if ( ! $this->getAttribute(Doctrine::ATTR_RESULT_CACHE)) {
+ throw new Doctrine_Exception('Result Cache driver not initialized.');
+ }
+
+ return $this->getAttribute(Doctrine::ATTR_RESULT_CACHE);
+ }
+
+ /**
+ * getQueryCacheDriver
+ *
+ * @return Doctrine_Cache_Interface
+ * @todo package:orm
+ */
+ public function getQueryCacheDriver()
+ {
+ if ( ! $this->getAttribute(Doctrine::ATTR_QUERY_CACHE)) {
+ throw new Doctrine_Exception('Query Cache driver not initialized.');
+ }
+
+ return $this->getAttribute(Doctrine::ATTR_QUERY_CACHE);
+ }
+
+ /**
+ * Initiates a transaction.
+ *
+ * This method must only be used by Doctrine itself to initiate transactions.
+ * Userland-code must use {@link beginTransaction()}.
+ *
+ * @todo package:orm???
+ */
+ public function beginInternalTransaction($savepoint = null)
+ {
+ return $this->transaction->beginInternalTransaction($savepoint);
+ }
+
+ /**
+ * Enter description here...
+ *
+ * @todo To EntityManager
+ */
+ public function getRepository($entityName)
+ {
+ if (isset($this->_repositories[$entityName])) {
+ return $this->_repositories[$entityName];
+ }
+
+ $metadata = $this->getClassMetadata($entityName);
+ $customRepositoryClassName = $metadata->getCustomRepositoryClass();
+ if ($customRepositoryClassName !== null) {
+ $repository = new $customRepositoryClassName($entityName, $metadata);
+ } else {
+ $repository = new Doctrine_EntityRepository($entityName, $metadata);
+ }
+ $this->_repositories[$entityName] = $repository;
+
+ return $repository;
+ }
+
+
+ /*
+ * ----------- Mixed methods (need to figure out where they go) ---------------
+ */
+
+ /**
+ * getAttribute
+ * retrieves a database connection attribute
+ *
+ * @param integer $attribute
+ * @return mixed
+ */
+ public function getAttribute($attribute)
+ {
+ if ($attribute >= 100) {
+ if ( ! isset($this->_attributes[$attribute])) {
+ return parent::getAttribute($attribute);
+ }
+ return $this->_attributes[$attribute];
+ }
+
+ if ($this->isConnected) {
+ try {
+ return $this->dbh->getAttribute($attribute);
+ } catch (Exception $e) {
+ throw new Doctrine_Connection_Exception('Attribute ' . $attribute . ' not found.');
+ }
+ } else {
+ if ( ! isset($this->pendingAttributes[$attribute])) {
+ $this->connect();
+ $this->getAttribute($attribute);
+ }
+
+ return $this->pendingAttributes[$attribute];
+ }
+ }
+
+ /**
+ * setAttribute
+ * sets an attribute
+ *
+ * @todo why check for >= 100? has this any special meaning when creating
+ * attributes?
+ *
+ * @param integer $attribute
+ * @param mixed $value
+ * @return boolean
+ */
+ public function setAttribute($attribute, $value)
+ {
+ if ($attribute >= 100) {
+ parent::setAttribute($attribute, $value);
+ } else {
+ if ($this->isConnected) {
+ $this->dbh->setAttribute($attribute, $value);
+ } else {
+ $this->pendingAttributes[$attribute] = $value;
+ }
+ }
+ return $this;
+ }
+
+ /**
+ * __get
+ * lazy loads given module and returns it
+ *
+ * @see Doctrine_DataDict
+ * @see Doctrine_Expression
+ * @see Doctrine_Export
+ * @see Doctrine_Transaction
+ * @see Doctrine_Connection::$modules all availible modules
+ * @param string $name the name of the module to get
+ * @throws Doctrine_Connection_Exception if trying to get an unknown module
+ * @return Doctrine_Connection_Module connection module
+ */
+ public function __get($name)
+ {
+ if (isset($this->properties[$name])) {
+ return $this->properties[$name];
+ }
+
+ if ( ! isset($this->modules[$name])) {
+ throw new Doctrine_Connection_Exception('Unknown module / property ' . $name);
+ }
+ if ($this->modules[$name] === false) {
+ switch ($name) {
+ case 'unitOfWork':
+ $this->modules[$name] = new Doctrine_Connection_UnitOfWork($this);
+ break;
+ case 'formatter':
+ $this->modules[$name] = new Doctrine_Formatter($this);
+ break;
+ default:
+ $class = 'Doctrine_' . ucwords($name) . '_' . $this->getDriverName();
+ $this->modules[$name] = new $class($this);
+ }
+ }
+
+ return $this->modules[$name];
+ }
+
+ /**
+ * returns the manager that created this connection
+ *
+ * @return Doctrine_Manager
+ */
+ public function getManager()
+ {
+ return $this->getParent();
+ }
+
}
diff --git a/lib/Doctrine/Connection/UnitOfWork.php b/lib/Doctrine/Connection/UnitOfWork.php
index 7c8f09438..082bac886 100644
--- a/lib/Doctrine/Connection/UnitOfWork.php
+++ b/lib/Doctrine/Connection/UnitOfWork.php
@@ -20,7 +20,23 @@
*/
/**
- * Doctrine_Connection_UnitOfWork
+ * The UnitOfWork is responsible for writing out changes to the database at
+ * the correct time and in the correct order.
+ *
+ * Some terminology:
+ *
+ * New entity: From the point of view of the unitOfWork is an entity that
+ * already has an identity but is not yet persisted into the database. This
+ * is usually the case for all newly saved entities that use a SEQUENCE id
+ * generator. Entities with an IDENTITY id generator get persisted as soon
+ * as they're saved in order to obtain the identifier. Therefore entities that
+ * use an IDENTITY id generator never appear in the list of new entities of the UoW.
+ *
+ * Dirty entity: ...
+ *
+ * Removed entity: ...
+ *
+ * Clean entity: ...
*
* @package Doctrine
* @subpackage Connection
@@ -105,12 +121,19 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
*/
public function registerNew(Doctrine_Record $entity)
{
- if (isset($this->_dirtyEntities[$entity->getOid()])) {
- throw new Doctrine_Connection_Exception("Dirty object can't be registered as new.");
- } else if (isset($this->_removedEntities[$entity->getOid()])) {
- throw new Doctrine_Connection_Exception("Removed object can't be registered as new.");
+ if ( ! $entity->identifier()) {
+ throw new Doctrine_Connection_Exception("Entity without identity "
+ . "can't be registered as new.");
}
- $this->_newEntities[$entity->getOid()] = $entity;
+ $oid = $entity->getOid();
+ if (isset($this->_dirtyEntities[$oid])) {
+ throw new Doctrine_Connection_Exception("Dirty object can't be registered as new.");
+ } else if (isset($this->_removedEntities[$oid])) {
+ throw new Doctrine_Connection_Exception("Removed object can't be registered as new.");
+ } else if (isset($this->_newEntities[$oid])) {
+ throw new Doctrine_Connection_Exception("Object already registered as new. Can't register twice.");
+ }
+ $this->_newEntities[$oid] = $entity;
}
public function isRegisteredNew(Doctrine_Record $entity)
@@ -131,12 +154,17 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
*/
public function registerDirty(Doctrine_Record $entity)
{
+ if ( ! $entity->identifier()) {
+ throw new Doctrine_Connection_Exception("Entity without identity "
+ . "can't be registered as dirty.");
+ }
+ $oid = $entity->getOid();
if (isset($this->_removedEntities[$entity->getOid()])) {
throw new Doctrine_Connection_Exception("Removed object can't be registered as dirty.");
- } else if (isset($this->_newEntities[$entity->getOid()])) {
- throw new Doctrine_Connection_Exception("");
}
- $this->_dirtyEntities[$entity->getOid()] = $entity;
+ if ( ! isset($this->_dirtyEntities[$oid], $this->_newEntities[$oid])) {
+ $this->_dirtyEntities[$entity->getOid()] = $entity;
+ }
}
public function isRegisteredDirty(Doctrine_Record $entity)
@@ -149,8 +177,21 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
*/
public function registerRemoved(Doctrine_Record $entity)
{
+ if ($entity->isTransient()) {
+ return;
+ }
$this->unregisterIdentity($entity);
- $this->_removedEntities[$entity->getOid()] = $entity;
+ $oid = $entity->getOid();
+ if (isset($this->_newEntities[$oid])) {
+ unset($this->_newEntities[$oid]);
+ return;
+ }
+ if (isset($this->_dirtyEntities[$oid])) {
+ unset($this->_dirtyEntities[$oid]);
+ }
+ if ( ! isset($this->_removedEntities[$oid])) {
+ $this->_removedEntities[$oid] = $entity;
+ }
}
public function isRegisteredRemoved(Doctrine_Record $entity)
diff --git a/lib/Doctrine/EntityRepository.php b/lib/Doctrine/EntityRepository.php
new file mode 100644
index 000000000..d4e66ebe8
--- /dev/null
+++ b/lib/Doctrine/EntityRepository.php
@@ -0,0 +1,225 @@
+.
+ */
+
+/**
+ * Base class for all custom user-defined repositories.
+ * Provides basic finder methods, common to all repositories.
+ *
+ * @package Doctrine
+ * @subpackage EntityRepository
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link www.phpdoctrine.org
+ * @since 2.0
+ * @version $Revision$
+ * @author Roman Borschel
+ * @todo package:orm
+ */
+class Doctrine_EntityRepository
+{
+ protected $_entityName;
+ protected $_conn;
+ protected $_classMetadata;
+
+ public function __construct($entityName, Doctrine_ClassMetadata $classMetadata)
+ {
+ $this->_entityName = $entityName;
+ $this->_conn = $classMetadata->getConnection();
+ $this->_classMetadata = $classMetadata;
+ }
+
+ /**
+ * createQuery
+ * creates a new Doctrine_Query object and adds the component name
+ * of this table as the query 'from' part
+ *
+ * @param string Optional alias name for component aliasing.
+ *
+ * @return Doctrine_Query
+ */
+ protected function _createQuery($alias = '')
+ {
+ if ( ! empty($alias)) {
+ $alias = ' ' . trim($alias);
+ }
+ return Doctrine_Query::create($this->_conn)->from($this->_entityName . $alias);
+ }
+
+ /**
+ * clear
+ * clears the first level cache (identityMap)
+ *
+ * @return void
+ * @todo what about a more descriptive name? clearIdentityMap?
+ */
+ public function clear()
+ {
+ $this->_conn->unitOfWork->clearIdentitiesForEntity($this->_classMetadata->getRootClassName());
+ }
+
+ /**
+ * Finds an entity by its primary key.
+ *
+ * @param $id database row id
+ * @param int $hydrationMode Doctrine::HYDRATE_ARRAY or Doctrine::HYDRATE_RECORD
+ * @return mixed Array or Doctrine_Record or false if no result
+ * @todo Remove. Move to EntityRepository.
+ */
+ public function find($id, $hydrationMode = null)
+ {
+ if (is_null($id)) {
+ return false;
+ }
+
+ if (is_array($id) && count($id) > 1) {
+ // it's a composite key. keys = field names, values = values.
+ $values = array_values($id);
+ $keys = array_keys($id);
+ } else {
+ $values = is_array($id) ? array_values($id) : array($id);
+ $keys = $this->_classMetadata->getIdentifier();
+ }
+
+ return $this->_createQuery()
+ ->where(implode(' = ? AND ', $keys) . ' = ?')
+ ->fetchOne($values, $hydrationMode);
+ }
+
+ /**
+ * Finds all entities of the mapper's class.
+ * Use with care.
+ *
+ * @param int $hydrationMode Doctrine::HYDRATE_ARRAY or Doctrine::HYDRATE_RECORD
+ * @return Doctrine_Collection
+ */
+ public function findAll($hydrationMode = null)
+ {
+ return $this->_createQuery()->execute(array(), $hydrationMode);
+ }
+
+ /**
+ * findBy
+ *
+ * @param string $column
+ * @param string $value
+ * @param string $hydrationMode
+ * @return void
+ */
+ protected function findBy($fieldName, $value, $hydrationMode = null)
+ {
+ return $this->_createQuery()->where($fieldName . ' = ?')->execute(array($value), $hydrationMode);
+ }
+
+ /**
+ * findOneBy
+ *
+ * @param string $column
+ * @param string $value
+ * @param string $hydrationMode
+ * @return void
+ */
+ protected function findOneBy($fieldName, $value, $hydrationMode = null)
+ {
+ $results = $this->_createQuery()->where($fieldName . ' = ?')->limit(1)->execute(
+ array($value), $hydrationMode);
+ return $hydrationMode === Doctrine::HYDRATE_ARRAY ? array_shift($results) : $results->getFirst();
+ }
+
+ /**
+ * findBySql
+ * finds records with given SQL where clause
+ * returns a collection of records
+ *
+ * @param string $dql DQL after WHERE clause
+ * @param array $params query parameters
+ * @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD
+ * @return Doctrine_Collection
+ *
+ * @todo This actually takes DQL, not SQL, but it requires column names
+ * instead of field names. This should be fixed to use raw SQL instead.
+ */
+ public function findBySql($dql, array $params = array(), $hydrationMode = null)
+ {
+ return $this->_createQuery()->where($dql)->execute($params, $hydrationMode);
+ }
+
+ /**
+ * findByDql
+ * finds records with given DQL where clause
+ * returns a collection of records
+ *
+ * @param string $dql DQL after WHERE clause
+ * @param array $params query parameters
+ * @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD
+ * @return Doctrine_Collection
+ */
+ public function findByDql($dql, array $params = array(), $hydrationMode = null)
+ {
+ $query = new Doctrine_Query($this->_conn);
+ $component = $this->getComponentName();
+ $dql = 'FROM ' . $component . ' WHERE ' . $dql;
+
+ return $query->query($dql, $params, $hydrationMode);
+ }
+
+ /**
+ * Adds support for magic finders.
+ * findByColumnName, findByRelationAlias
+ * findById, findByContactId, etc.
+ *
+ * @return void
+ * @throws Doctrine_Mapper_Exception If the method called is an invalid find* method
+ * or no find* method at all and therefore an invalid
+ * method call.
+ */
+ public function __call($method, $arguments)
+ {
+ if (substr($method, 0, 6) == 'findBy') {
+ $by = substr($method, 6, strlen($method));
+ $method = 'findBy';
+ } else if (substr($method, 0, 9) == 'findOneBy') {
+ $by = substr($method, 9, strlen($method));
+ $method = 'findOneBy';
+ } else {
+ throw new Doctrine_Mapper_Exception("Undefined method '$method'.");
+ }
+
+ if (isset($by)) {
+ if ( ! isset($arguments[0])) {
+ throw new Doctrine_Mapper_Exception('You must specify the value to findBy.');
+ }
+
+ $fieldName = Doctrine::tableize($by);
+ $hydrationMode = isset($arguments[1]) ? $arguments[1]:null;
+
+ if ($this->_classMetadata->hasField($fieldName)) {
+ return $this->$method($fieldName, $arguments[0], $hydrationMode);
+ } else if ($this->_classMetadata->hasRelation($by)) {
+ $relation = $this->_classMetadata->getRelation($by);
+ if ($relation['type'] === Doctrine_Relation::MANY) {
+ throw new Doctrine_Mapper_Exception('Cannot findBy many relationship.');
+ }
+ return $this->$method($relation['local'], $arguments[0], $hydrationMode);
+ } else {
+ throw new Doctrine_Mapper_Exception('Cannot find by: ' . $by . '. Invalid field or relationship alias.');
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/lib/Doctrine/Hydrator.php b/lib/Doctrine/Hydrator.php
index 331237a08..f424f51d0 100644
--- a/lib/Doctrine/Hydrator.php
+++ b/lib/Doctrine/Hydrator.php
@@ -52,13 +52,14 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
* 'table' => Table object,
* 'parent' => Parent DQL alias (if any),
* 'relation' => Relation object (if any),
- * 'map' => Custom index to use as the key in the result (if any)
+ * 'map' => Custom index to use as the key in the result (if any),
+ * 'agg' => List of aggregate values (sql alias => dql alias)
* )
* )
* @return mixed The created object/array graph.
*/
public function hydrateResultSet($stmt, $tableAliases, $hydrationMode = null)
- {
+ {
if ($hydrationMode === null) {
$hydrationMode = $this->_hydrationMode;
}
@@ -82,7 +83,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
// Used variables during hydration
reset($this->_queryComponents);
$rootAlias = key($this->_queryComponents);
- $rootComponentName = $this->_queryComponents[$rootAlias]['mapper']->getComponentName();
+ $rootComponentName = $this->_queryComponents[$rootAlias]['table']->getComponentName();
// if only one component is involved we can make our lives easier
$isSimpleQuery = count($this->_queryComponents) <= 1;
// Holds hydration listeners that get called during hydration
@@ -110,7 +111,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
foreach ($this->_queryComponents as $dqlAlias => $component) {
// disable lazy-loading of related elements during hydration
$component['table']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
- $componentName = $component['mapper']->getComponentName();
+ $componentName = $component['table']->getClassName();
$listeners[$componentName] = $component['table']->getRecordListener();
$identifierMap[$dqlAlias] = array();
$prev[$dqlAlias] = array();
@@ -127,9 +128,8 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
//
// hydrate the data of the root entity from the current row
//
- $table = $this->_queryComponents[$rootAlias]['table'];
- $mapper = $this->_queryComponents[$rootAlias]['mapper'];
- $componentName = $mapper->getComponentName();
+ $class = $this->_queryComponents[$rootAlias]['table'];
+ $componentName = $class->getComponentName();
// just event stuff
$event->set('data', $rowData[$rootAlias]);
@@ -175,9 +175,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
foreach ($rowData as $dqlAlias => $data) {
$index = false;
$map = $this->_queryComponents[$dqlAlias];
- $table = $map['table'];
- $mapper = $map['mapper'];
- $componentName = $mapper->getComponentName();
+ $componentName = $map['table']->getComponentName();
// just event stuff
$event->set('data', $data);
@@ -186,7 +184,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
$parent = $map['parent'];
$relation = $map['relation'];
- $relationAlias = $map['relation']->getAlias();
+ $relationAlias = $relation->getAlias();
$path = $parent . '.' . $dqlAlias;
@@ -195,16 +193,19 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
}
// check the type of the relation
- if ( ! $relation->isOneToOne() && $driver->initRelated($prev[$parent], $relationAlias)) {
+ if ( ! $relation->isOneToOne()) {
$oneToOne = false;
// append element
if (isset($nonemptyComponents[$dqlAlias])) {
+ $driver->initRelated($prev[$parent], $relationAlias);
if ( ! isset($identifierMap[$path][$id[$parent]][$id[$dqlAlias]])) {
$element = $driver->getElement($data, $componentName);
+
// just event stuff
$event->set('data', $element);
$listeners[$componentName]->postHydrate($event);
//--
+
if ($field = $this->_getCustomIndexField($dqlAlias)) {
// TODO: we should check this earlier. Fields used in INDEXBY
// must be unique. Then this can be removed here.
@@ -223,7 +224,7 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
$index = $identifierMap[$path][$id[$parent]][$id[$dqlAlias]];
}
// register collection for later snapshots
- $driver->registerCollection($prev[$parent][$relationAlias]);
+ //$driver->registerCollection($prev[$parent][$relationAlias]);
}
} else {
// 1-1 relation
@@ -315,11 +316,17 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
if ( ! isset($cache[$key])) {
// cache general information like the column name <-> field name mapping
$e = explode('__', $key);
- $columnName = strtolower(array_pop($e));
+ $columnName = strtolower(array_pop($e));
$cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))];
$mapper = $this->_queryComponents[$cache[$key]['dqlAlias']]['mapper'];
$classMetadata = $mapper->getClassMetadata();
- $fieldName = $mapper->getFieldName($columnName);
+ // check whether it's an aggregate value or a regular field
+ if (isset($this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName])) {
+ $fieldName = $this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName];
+ } else {
+ $fieldName = $mapper->getFieldName($columnName);
+ }
+
$cache[$key]['fieldName'] = $fieldName;
// cache identifier information
@@ -343,10 +350,6 @@ class Doctrine_Hydrator extends Doctrine_Hydrator_Abstract
$dqlAlias = $cache[$key]['dqlAlias'];
$fieldName = $cache[$key]['fieldName'];
- if (isset($this->_queryComponents[$dqlAlias]['agg'][$fieldName])) {
- $fieldName = $this->_queryComponents[$dqlAlias]['agg'][$fieldName];
- }
-
if ($cache[$key]['isIdentifier']) {
$id[$dqlAlias] .= '|' . $value;
}
diff --git a/lib/Doctrine/Hydrator/ArrayDriver.php b/lib/Doctrine/Hydrator/ArrayDriver.php
index 52e9101df..8bdcc81dc 100644
--- a/lib/Doctrine/Hydrator/ArrayDriver.php
+++ b/lib/Doctrine/Hydrator/ArrayDriver.php
@@ -71,8 +71,6 @@ class Doctrine_Hydrator_ArrayDriver
if ( ! isset($data[$name])) {
$data[$name] = array();
}
-
- return true;
}
/**
diff --git a/lib/Doctrine/Hydrator/RecordDriver.php b/lib/Doctrine/Hydrator/RecordDriver.php
index 7c70203be..fe6094cf2 100644
--- a/lib/Doctrine/Hydrator/RecordDriver.php
+++ b/lib/Doctrine/Hydrator/RecordDriver.php
@@ -20,7 +20,7 @@
*/
/**
- * Doctrine_Hydrate_RecordDriver
+ * Doctrine_Hydrator_RecordDriver
* Hydration strategy used for creating graphs of entity objects.
*
* @package Doctrine
@@ -34,8 +34,13 @@
*/
class Doctrine_Hydrator_RecordDriver
{
+ /** Collections initialized by the driver */
protected $_collections = array();
+ /** Mappers */
protected $_mappers = array();
+ /** Memory for initialized relations */
+ private $_initializedRelations = array();
+ /** Null object */
private $_nullObject;
public function __construct()
@@ -53,54 +58,32 @@ class Doctrine_Hydrator_RecordDriver
public function getLastKey($coll)
{
- $coll->end();
-
- return $coll->key();
+ // check needed because of mixed results
+ if (is_array($coll)) {
+ end($coll);
+ return key($coll);
+ } else {
+ $coll->end();
+ return $coll->key();
+ }
}
- public function initRelated($record, $name)
+ public function initRelated(Doctrine_Record $record, $name)
{
- return true;
- /*
- if ( ! is_array($record)) {
- $record[$name];
- return true;
+ if ( ! isset($this->_initializedRelations[$record->getOid()][$name])) {
+ $relation = $record->getClassMetadata()->getRelation($name);
+ $relatedClass = $relation->getTable();
+ $coll = $this->getElementCollection($relatedClass->getClassName());
+ $coll->setReference($record, $relation);
+ $record[$name] = $coll;
+ $this->_initializedRelations[$record->getOid()][$name] = true;
}
- return false;
- */
}
public function registerCollection(Doctrine_Collection $coll)
{
$this->_collections[] = $coll;
}
-
- /**
- * isIdentifiable
- * returns whether or not a given data row is identifiable (it contains
- * all primary key fields specified in the second argument)
- *
- * @param array $row
- * @param Doctrine_Table $table
- * @return boolean
- */
- /*public function isIdentifiable(array $row, Doctrine_Table $table)
- {
- $primaryKeys = $table->getIdentifierColumnNames();
-
- if (is_array($primaryKeys)) {
- foreach ($primaryKeys as $id) {
- if ( ! isset($row[$id])) {
- return false;
- }
- }
- } else {
- if ( ! isset($row[$primaryKeys])) {
- return false;
- }
- }
- return true;
- }*/
public function getNullPointer()
{
@@ -127,6 +110,7 @@ class Doctrine_Hydrator_RecordDriver
}
$this->_collections = array();
$this->_mappers = array();
+ $this->_initializedRelations = array();
}
/**
diff --git a/lib/Doctrine/HydratorNew.php b/lib/Doctrine/HydratorNew.php
new file mode 100644
index 000000000..b730ab38d
--- /dev/null
+++ b/lib/Doctrine/HydratorNew.php
@@ -0,0 +1,422 @@
+.
+ */
+
+/**
+ * The hydrator has the tedious task to construct object or array graphs out of
+ * a database result set.
+ *
+ * @package Doctrine
+ * @subpackage Hydrator
+ * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
+ * @link www.phpdoctrine.org
+ * @since 1.0
+ * @version $Revision: 3192 $
+ * @author Konsta Vesterinen
+ * @author Roman Borschel
+ */
+class Doctrine_HydratorNew extends Doctrine_Hydrator_Abstract
+{
+ /**
+ * hydrateResultSet
+ * parses the data returned by statement object
+ *
+ * This is method defines the core of Doctrine's object population algorithm.
+ *
+ * The key idea is the loop over the rowset only once doing all the needed operations
+ * within this massive loop.
+ *
+ * @todo: Detailed documentation. Refactor (too long & nesting level).
+ *
+ * @param mixed $stmt
+ * @param array $tableAliases Array that maps table aliases (SQL alias => DQL alias)
+ * @param array $aliasMap Array that maps DQL aliases to their components
+ * (DQL alias => array(
+ * 'table' => Table object,
+ * 'parent' => Parent DQL alias (if any),
+ * 'relation' => Relation object (if any),
+ * 'map' => Custom index to use as the key in the result (if any),
+ * 'agg' => List of aggregate value names (sql alias => dql alias)
+ * )
+ * )
+ * @return mixed The created object/array graph.
+ */
+ public function hydrateResultSet($stmt, $tableAliases, $hydrationMode = null)
+ {
+ if ($hydrationMode === null) {
+ $hydrationMode = $this->_hydrationMode;
+ }
+
+ if ($hydrationMode == Doctrine::HYDRATE_NONE) {
+ return $stmt->fetchAll(PDO::FETCH_NUM);
+ }
+
+ $this->_tableAliases = $tableAliases;
+
+ if ($hydrationMode == Doctrine::HYDRATE_ARRAY) {
+ $driver = new Doctrine_Hydrator_ArrayDriver();
+ } else {
+ $driver = new Doctrine_Hydrator_RecordDriver();
+ }
+
+ $event = new Doctrine_Event(null, Doctrine_Event::HYDRATE, null);
+
+ //$s = microtime(true);
+
+ // Used variables during hydration
+ reset($this->_queryComponents);
+ $rootAlias = key($this->_queryComponents);
+ $rootComponentName = $this->_queryComponents[$rootAlias]['table']->getClassName();
+ // if only one class is involved we can make our lives easier
+ $isSimpleQuery = count($this->_queryComponents) <= 1;
+ // Holds hydration listeners that get called during hydration
+ $listeners = array();
+ // Lookup map to quickly discover/lookup existing records in the result
+ // It's the identifier "memory"
+ $identifierMap = array();
+ // Holds for each class a pointer to the last previously seen element in the result set
+ $resultPointers = array();
+ // holds the values of the identifier/primary key fields of components,
+ // separated by a pipe '|' and grouped by component alias (r, u, i, ... whatever)
+ // the $idTemplate is a prepared template. $id is set to a fresh template when
+ // starting to process a row.
+ $id = array();
+ $idTemplate = array();
+
+ // Holds the resulting hydrated data structure
+ if ($this->_isResultMixed) {
+ $result = array();
+ } else {
+ $result = $driver->getElementCollection($rootComponentName);
+ }
+
+ if ($stmt === false || $stmt === 0) {
+ return $result;
+ }
+
+ // Initialize
+ foreach ($this->_queryComponents as $dqlAlias => $component) {
+ // disable lazy-loading of related elements during hydration
+ $component['table']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, false);
+ $componentName = $component['table']->getClassName();
+ $listeners[$componentName] = $component['table']->getRecordListener();
+ $identifierMap[$dqlAlias] = array();
+ $resultPointers[$dqlAlias] = array();
+ $idTemplate[$dqlAlias] = '';
+ }
+
+ // Process result set
+ $cache = array();
+ while ($data = $stmt->fetch(Doctrine::FETCH_ASSOC)) {
+ $id = $idTemplate; // initialize the id-memory
+ $nonemptyComponents = array();
+ $rowData = $this->_gatherRowData($data, $cache, $id, $nonemptyComponents);
+
+ //
+ // hydrate the data of the root entity from the current row
+ //
+ $class = $this->_queryComponents[$rootAlias]['table'];
+ $componentName = $class->getComponentName();
+
+ // just event stuff
+ $event->set('data', $rowData[$rootAlias]);
+ $listeners[$componentName]->preHydrate($event);
+ //--
+
+ // Check for an existing element
+ $index = false;
+ if ($isSimpleQuery || ! isset($identifierMap[$rootAlias][$id[$rootAlias]])) {
+ $element = $driver->getElement($rowData[$rootAlias], $componentName);
+
+ // just event stuff
+ $event->set('data', $element);
+ $listeners[$componentName]->postHydrate($event);
+ //--
+
+ // do we need to index by a custom field?
+ if ($field = $this->_getCustomIndexField($rootAlias)) {
+ if (isset($result[$field])) {
+ throw new Doctrine_Hydrator_Exception("Couldn't hydrate. Found non-unique key mapping.");
+ } else if ( ! isset($element[$field])) {
+ throw new Doctrine_Hydrator_Exception("Couldn't hydrate. Found a non-existent key.");
+ }
+ if ($this->_isResultMixed) {
+ $result[] = array($element[$field] => $element);
+ } else {
+ $result[$element[$field]] = $element;
+ }
+ } else {
+ if ($this->_isResultMixed) {
+ $result[] = array($element);
+ } else {
+ $result[] = $element;
+ }
+ }
+
+ $identifierMap[$rootAlias][$id[$rootAlias]] = $driver->getLastKey($result);
+ } else {
+ $index = $identifierMap[$rootAlias][$id[$rootAlias]];
+ }
+
+ $this->_setLastElement($resultPointers, $result, $index, $rootAlias, false);
+ unset($rowData[$rootAlias]);
+ // end hydrate data of the root component for the current row
+
+ // Check for scalar values
+ if (isset($rowData['scalars'])) {
+ $scalars = $rowData['scalars'];
+ unset($rowData['scalars']);
+ }
+
+ // $prev[$rootAlias] now points to the last element in $result.
+ // now hydrate the rest of the data found in the current row, that belongs to other
+ // (related) components.
+ foreach ($rowData as $dqlAlias => $data) {
+ $index = false;
+ $map = $this->_queryComponents[$dqlAlias];
+ $componentName = $map['table']->getComponentName();
+
+ // just event stuff
+ $event->set('data', $data);
+ $listeners[$componentName]->preHydrate($event);
+ //--
+
+ $parent = $map['parent'];
+ $relation = $map['relation'];
+ $relationAlias = $relation->getAlias();
+
+ $path = $parent . '.' . $dqlAlias;
+
+ $key = key(reset($resultPointers));
+ if ($this->_isResultMixed && $parent == $rootAlias && isset($resultPointers[$parent][$key])) {
+ $baseElement =& $resultPointers[$parent][$key];
+ } else if (isset($resultPointers[$parent])) {
+ $baseElement =& $resultPointers[$parent];
+ } else {
+ continue;
+ }
+
+ // check the type of the relation (many or single-valued)
+ if ( ! $relation->isOneToOne()) {
+ // x-many relation
+ $oneToOne = false;
+ if (isset($nonemptyComponents[$dqlAlias])) {
+ $driver->initRelated($baseElement, $relationAlias);
+ if ( ! isset($identifierMap[$path][$id[$parent]][$id[$dqlAlias]])) {
+ $element = $driver->getElement($data, $componentName);
+
+ // just event stuff
+ $event->set('data', $element);
+ $listeners[$componentName]->postHydrate($event);
+ //--
+
+ if ($field = $this->_getCustomIndexField($dqlAlias)) {
+ // TODO: we should check this earlier. Fields used in INDEXBY
+ // must be unique. Then this can be removed here.
+ if (isset($baseElement[$relationAlias][$field])) {
+ throw Doctrine_Hydrator_Exception::nonUniqueKeyMapping();
+ } else if ( ! isset($element[$field])) {
+ throw Doctrine_Hydrator_Exception::nonExistantFieldUsedAsIndex($field);
+ }
+ $baseElement[$relationAlias][$element[$field]] = $element;
+ } else {
+ $baseElement[$relationAlias][] = $element;
+ }
+
+ $identifierMap[$path][$id[$parent]][$id[$dqlAlias]] = $driver->getLastKey($baseElement[$relationAlias]);
+ } else {
+ $index = $identifierMap[$path][$id[$parent]][$id[$dqlAlias]];
+ }
+ }
+ } else {
+ // x-1 relation
+ $oneToOne = true;
+ if ( ! isset($nonemptyComponents[$dqlAlias])) {
+ $baseElement[$relationAlias] = $driver->getNullPointer();
+ } else if ( ! isset($baseElement[$relationAlias])) {
+ $baseElement[$relationAlias] = $driver->getElement($data, $componentName);
+ }
+ }
+ $coll =& $baseElement[$relationAlias];
+ $this->_setLastElement($resultPointers, $coll, $index, $dqlAlias, $oneToOne);
+ }
+
+ // append scalar values
+ if (isset($scalars)) {
+ $rowNumber = count($result) - 1;
+ foreach ($scalars as $name => $value) {
+ $result[$rowNumber][$name] = $value;
+ }
+ }
+ }
+
+ $stmt->closeCursor();
+ $driver->flush();
+
+ // re-enable lazy loading
+ foreach ($this->_queryComponents as $dqlAlias => $data) {
+ $data['table']->setAttribute(Doctrine::ATTR_LOAD_REFERENCES, true);
+ }
+
+ //$e = microtime(true);
+ //echo 'Hydration took: ' . ($e - $s) . ' for '.count($result).' records
';
+
+ return $result;
+ }
+
+ /**
+ * _setLastElement
+ *
+ * sets the last element of given data array / collection
+ * as previous element
+ *
+ * @param array $prev The array that contains the pointers to the latest element of each class.
+ * @param array|Collection The object collection.
+ * @param boolean|integer $index Index of the element in the collection.
+ * @param string $dqlAlias
+ * @param boolean $oneToOne Whether it is a single-valued association or not.
+ * @return void
+ * @todo Detailed documentation
+ */
+ protected function _setLastElement(&$resultPointers, &$coll, $index, $dqlAlias, $oneToOne)
+ {
+ if ($coll === $this->_nullObject) {
+ return false;
+ }
+
+ if ($index !== false) {
+ // Link element at $index to previous element for the component
+ // identified by the DQL alias $alias
+ $resultPointers[$dqlAlias] =& $coll[$index];
+ return;
+ }
+
+ if (is_array($coll) && $coll) {
+ if ($oneToOne) {
+ $resultPointers[$dqlAlias] =& $coll;
+ } else {
+ end($coll);
+ $resultPointers[$dqlAlias] =& $coll[key($coll)];
+ }
+ } else if ($coll instanceof Doctrine_Record) {
+ $resultPointers[$dqlAlias] = $coll;
+ } else if (count($coll) > 0) {
+ $resultPointers[$dqlAlias] = $coll->getLast();
+ } else if (isset($resultPointers[$dqlAlias])) {
+ unset($resultPointers[$dqlAlias]);
+ }
+ }
+
+ /**
+ * Puts the fields of a data row into a new array, grouped by the component
+ * they belong to. The column names in the result set are mapped to their
+ * field names during this procedure.
+ *
+ * @return array An array with all the fields (name => value) of the data row,
+ * grouped by their component (alias).
+ */
+ protected function _gatherRowData(&$data, &$cache, &$id, &$nonemptyComponents)
+ {
+ $rowData = array();
+
+ foreach ($data as $key => $value) {
+ // Parse each column name only once. Cache the results.
+ if ( ! isset($cache[$key])) {
+ // cache general information like the column name <-> field name mapping
+ $e = explode('__', $key);
+ $columnName = strtolower(array_pop($e));
+ $cache[$key]['dqlAlias'] = $this->_tableAliases[strtolower(implode('__', $e))];
+ $mapper = $this->_queryComponents[$cache[$key]['dqlAlias']]['mapper'];
+ $classMetadata = $mapper->getClassMetadata();
+ // check whether it's an aggregate value or a regular field
+ if (isset($this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName])) {
+ $fieldName = $this->_queryComponents[$cache[$key]['dqlAlias']]['agg'][$columnName];
+ $cache[$key]['isScalar'] = true;
+ } else {
+ $fieldName = $mapper->getFieldName($columnName);
+ $cache[$key]['isScalar'] = false;
+ }
+
+ $cache[$key]['fieldName'] = $fieldName;
+
+ // cache identifier information
+ if ($classMetadata->isIdentifier($fieldName)) {
+ $cache[$key]['isIdentifier'] = true;
+ } else {
+ $cache[$key]['isIdentifier'] = false;
+ }
+
+ // cache type information
+ $type = $classMetadata->getTypeOfColumn($columnName);
+ if ($type == 'integer' || $type == 'string') {
+ $cache[$key]['isSimpleType'] = true;
+ } else {
+ $cache[$key]['type'] = $type;
+ $cache[$key]['isSimpleType'] = false;
+ }
+ }
+
+ $mapper = $this->_queryComponents[$cache[$key]['dqlAlias']]['mapper'];
+ $dqlAlias = $cache[$key]['dqlAlias'];
+ $fieldName = $cache[$key]['fieldName'];
+
+ if ($cache[$key]['isScalar']) {
+ $rowData['scalars'][$fieldName] = $value;
+ continue;
+ }
+
+ if ($cache[$key]['isIdentifier']) {
+ $id[$dqlAlias] .= '|' . $value;
+ }
+
+ if ($cache[$key]['isSimpleType']) {
+ $rowData[$dqlAlias][$fieldName] = $value;
+ } else {
+ $rowData[$dqlAlias][$fieldName] = $mapper->prepareValue(
+ $fieldName, $value, $cache[$key]['type']);
+ }
+
+ if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) {
+ $nonemptyComponents[$dqlAlias] = true;
+ }
+ }
+
+ return $rowData;
+ }
+
+ /**
+ * Gets the custom field used for indexing for the specified component alias.
+ *
+ * @return string The field name of the field used for indexing or NULL
+ * if the component does not use any custom field indices.
+ */
+ protected function _getCustomIndexField($alias)
+ {
+ return isset($this->_queryComponents[$alias]['map']) ? $this->_queryComponents[$alias]['map'] : null;
+ }
+
+
+ private $_isResultMixed = false;
+ public function setResultMixed($bool)
+ {
+ $this->_isResultMixed = $bool;
+ }
+
+}
diff --git a/lib/Doctrine/Mapper.php b/lib/Doctrine/Mapper.php
index 282373063..bc3237413 100644
--- a/lib/Doctrine/Mapper.php
+++ b/lib/Doctrine/Mapper.php
@@ -90,23 +90,6 @@ class Doctrine_Mapper
}
}
- /**
- * createQuery
- * creates a new Doctrine_Query object and adds the component name
- * of this table as the query 'from' part
- *
- * @param string Optional alias name for component aliasing.
- *
- * @return Doctrine_Query
- */
- public function createQuery($alias = '')
- {
- if ( ! empty($alias)) {
- $alias = ' ' . trim($alias);
- }
- return Doctrine_Query::create($this->_conn)->from($this->getComponentName() . $alias);
- }
-
/**
* sets the connection for this class
*
@@ -139,7 +122,7 @@ class Doctrine_Mapper
*/
public function create(array $array = array())
{
- $record = new $this->_domainClassName($this, true);
+ $record = new $this->_domainClassName();
$record->fromArray($array);
return $record;
@@ -177,79 +160,6 @@ class Doctrine_Mapper
{
return $this->_conn->unitOfWork->detach($entity);
}
-
- /**
- * Finds an entity by its primary key.
- *
- * @param $id database row id
- * @param int $hydrationMode Doctrine::HYDRATE_ARRAY or Doctrine::HYDRATE_RECORD
- * @return mixed Array or Doctrine_Record or false if no result
- * @todo Remove. Move to EntityRepository.
- */
- public function find($id, $hydrationMode = null)
- {
- if (is_null($id)) {
- return false;
- }
-
- $id = is_array($id) ? array_values($id) : array($id);
-
- return $this->createQuery()
- ->where(implode(' = ? AND ', (array) $this->_classMetadata->getIdentifier()) . ' = ?')
- ->fetchOne($id, $hydrationMode);
- }
-
- /**
- * Finds all entities of the mapper's class.
- * Use with care.
- *
- * @param int $hydrationMode Doctrine::HYDRATE_ARRAY or Doctrine::HYDRATE_RECORD
- * @return Doctrine_Collection
- * @todo Remove. Move to EntityRepository.
- */
- public function findAll($hydrationMode = null)
- {
- return $this->createQuery()->execute(array(), $hydrationMode);
- }
-
- /**
- * findBySql
- * finds records with given SQL where clause
- * returns a collection of records
- *
- * @param string $dql DQL after WHERE clause
- * @param array $params query parameters
- * @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD
- * @return Doctrine_Collection
- *
- * @todo This actually takes DQL, not SQL, but it requires column names
- * instead of field names. This should be fixed to use raw SQL instead.
- * @todo Remove. Move to EntityRepository.
- */
- public function findBySql($dql, array $params = array(), $hydrationMode = null)
- {
- return $this->createQuery()->where($dql)->execute($params, $hydrationMode);
- }
-
- /**
- * findByDql
- * finds records with given DQL where clause
- * returns a collection of records
- *
- * @param string $dql DQL after WHERE clause
- * @param array $params query parameters
- * @param int $hydrationMode Doctrine::FETCH_ARRAY or Doctrine::FETCH_RECORD
- * @return Doctrine_Collection
- * @todo Remove. Move to EntityRepository.
- */
- public function findByDql($dql, array $params = array(), $hydrationMode = null)
- {
- $query = new Doctrine_Query($this->_conn);
- $component = $this->getComponentName();
- $dql = 'FROM ' . $component . ' WHERE ' . $dql;
-
- return $query->query($dql, $params, $hydrationMode);
- }
/**
* Executes a named query.
@@ -349,9 +259,7 @@ class Doctrine_Mapper
}
if ($found) {
- $record = new $this->_domainClassName($this, true, $data);
- $data = array();
- return $record;
+ return new $this->_domainClassName(true, $data);
}
$idHash = $this->_conn->unitOfWork->getIdentifierHash($id);
@@ -360,12 +268,12 @@ class Doctrine_Mapper
$this->_classMetadata->getRootClassName())) {
$record->hydrate($data);
} else {
- $record = new $this->_domainClassName($this, false, $data);
+ $record = new $this->_domainClassName(false, $data);
$this->_conn->unitOfWork->registerIdentity($record);
}
$data = array();
} else {
- $record = new $this->_domainClassName($this, true, $data);
+ $record = new $this->_domainClassName(true, $data);
}
return $record;
@@ -545,83 +453,6 @@ class Doctrine_Mapper
return $this->_domainClassName;
}
- /**
- * findBy
- *
- * @param string $column
- * @param string $value
- * @param string $hydrationMode
- * @return void
- * @todo Remove. Move to EntityRepository.
- */
- protected function findBy($fieldName, $value, $hydrationMode = null)
- {
- return $this->createQuery()->where($fieldName . ' = ?')->execute(array($value), $hydrationMode);
- }
-
- /**
- * findOneBy
- *
- * @param string $column
- * @param string $value
- * @param string $hydrationMode
- * @return void
- * @todo Remove. Move to EntityRepository.
- */
- protected function findOneBy($fieldName, $value, $hydrationMode = null)
- {
- $results = $this->createQuery()->where($fieldName . ' = ?')->limit(1)->execute(
- array($value), $hydrationMode);
- return $hydrationMode === Doctrine::HYDRATE_ARRAY ? array_shift($results) : $results->getFirst();
- }
-
- /**
- * __call
- *
- * Adds support for magic finders.
- * findByColumnName, findByRelationAlias
- * findById, findByContactId, etc.
- *
- * @return void
- * @throws Doctrine_Mapper_Exception If the method called is an invalid find* method
- * or no find* method at all and therefore an invalid
- * method call.
- * @todo Remove. Move to EntityRepository.
- */
- public function __call($method, $arguments)
- {
- if (substr($method, 0, 6) == 'findBy') {
- $by = substr($method, 6, strlen($method));
- $method = 'findBy';
- } else if (substr($method, 0, 9) == 'findOneBy') {
- $by = substr($method, 9, strlen($method));
- $method = 'findOneBy';
- } else {
- throw new Doctrine_Mapper_Exception("Undefined method '$method'.");
- }
-
- if (isset($by)) {
- if ( ! isset($arguments[0])) {
- throw new Doctrine_Mapper_Exception('You must specify the value to findBy.');
- }
-
- $fieldName = Doctrine::tableize($by);
- $hydrationMode = isset($arguments[1]) ? $arguments[1]:null;
-
- if ($this->_classMetadata->hasField($fieldName)) {
- return $this->$method($fieldName, $arguments[0], $hydrationMode);
- } else if ($this->_classMetadata->hasRelation($by)) {
- $relation = $this->_classMetadata->getRelation($by);
- if ($relation['type'] === Doctrine_Relation::MANY) {
- throw new Doctrine_Mapper_Exception('Cannot findBy many relationship.');
- }
- return $this->$method($relation['local'], $arguments[0], $hydrationMode);
- } else {
- throw new Doctrine_Mapper_Exception('Cannot find by: ' . $by . '. Invalid field or relationship alias.');
- }
- }
- }
-
/**
* Saves an entity and all it's related entities.
*
@@ -795,7 +626,12 @@ class Doctrine_Mapper
$query = 'DELETE FROM ' . $assocTable->getTableName()
. ' WHERE ' . $rel->getForeign() . ' = ?'
. ' AND ' . $rel->getLocal() . ' = ?';
- $this->_conn->execute($query, array($r->getIncremented(), $record->getIncremented()));
+ // FIXME: composite key support
+ $ids1 = $r->identifier();
+ $id1 = count($ids1) > 0 ? array_pop($ids1) : null;
+ $ids2 = $record->identifier();
+ $id2 = count($ids2) > 0 ? array_pop($ids2) : null;
+ $this->_conn->execute($query, array($id1, $id2));
}
$assocMapper = $this->_conn->getMapper($assocTable->getComponentName());
@@ -804,7 +640,6 @@ class Doctrine_Mapper
$assocRecord->set($assocTable->getFieldName($rel->getForeign()), $r);
$assocRecord->set($assocTable->getFieldName($rel->getLocal()), $record);
$assocMapper->save($assocRecord);
- //$this->saveSingleRecord($assocRecord);
}
}
}
@@ -890,19 +725,6 @@ class Doctrine_Mapper
return true;
}
- public function hasAttribute($key)
- {
- switch ($key) {
- case Doctrine::ATTR_LOAD_REFERENCES:
- case Doctrine::ATTR_QUERY_LIMIT:
- case Doctrine::ATTR_COLL_KEY:
- case Doctrine::ATTR_VALIDATE:
- return true;
- default:
- return false;
- }
- }
-
public function executeQuery(Doctrine_Query $query)
{
diff --git a/lib/Doctrine/Mapper/JoinedStrategy.php b/lib/Doctrine/Mapper/JoinedStrategy.php
index 237395f0e..205bd7141 100644
--- a/lib/Doctrine/Mapper/JoinedStrategy.php
+++ b/lib/Doctrine/Mapper/JoinedStrategy.php
@@ -111,7 +111,8 @@ class Doctrine_Mapper_JoinedStrategy extends Doctrine_Mapper_Strategy
if ( ! $value->exists()) {
$value->save();
}
- $record->set($field, $value->getIncremented());
+ $idValues = $value->identifier();
+ $record->set($field, $idValues[0]);
}
}
diff --git a/lib/Doctrine/Query.php b/lib/Doctrine/Query.php
index 4d9af09cb..7e9bb166c 100644
--- a/lib/Doctrine/Query.php
+++ b/lib/Doctrine/Query.php
@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* .
*/
-Doctrine::autoload('Doctrine_Query_Abstract');
+
/**
* Doctrine_Query
* A Doctrine_Query object represents a DQL query. It is used to query databases for
diff --git a/lib/Doctrine/Record.php b/lib/Doctrine/Record.php
index 1308057a0..5a551f619 100644
--- a/lib/Doctrine/Record.php
+++ b/lib/Doctrine/Record.php
@@ -117,12 +117,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* @var Doctrine_ClassMetadata
*/
protected $_class;
-
- /**
- *
- * @var Doctrine_Mapper
- */
- protected $_mapper;
/**
*
@@ -186,6 +180,13 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* @var array
*/
protected $_references = array();
+
+ /**
+ * The EntityManager that is responsible for the persistence of the entity.
+ *
+ * @var Doctrine_EntityManager
+ */
+ protected $_em;
/**
* The object identifier of the object. Each object has a unique identifier during runtime.
@@ -206,23 +207,13 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* open connections
* @throws Doctrine_Record_Exception if the cleanData operation fails somehow
*/
- public function __construct($mapper = null, $isNewEntry = false, array $data = array())
+ public function __construct($isNewEntry = true, array $data = array())
{
- if (isset($mapper) && $mapper instanceof Doctrine_Mapper) {
- $class = get_class($this);
- $this->_mapper = $mapper;
- $this->_class = $this->_mapper->getClassMetadata();
- $exists = ! $isNewEntry;
- } else {
- $this->_mapper = Doctrine_Manager::getInstance()->getMapper(get_class($this));
- $this->_class = $this->_mapper->getClassMetadata();
- $exists = false;
- }
-
- $this->_entityName = $this->_mapper->getMappedClassName();
- $this->_oid = self::$_index;
+ $this->_entityName = get_class($this);
+ $this->_em = Doctrine_Manager::getInstance()->getCurrentConnection();
+ $this->_class = $this->_em->getClassMetadata($this->_entityName);
- self::$_index++;
+ $this->_oid = self::$_index++;
// get the data array
$this->_data = $data;
@@ -232,9 +223,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->_values = $this->cleanData($this->_data);
- $this->_extractIdentifier($exists);
+ $this->_extractIdentifier( ! $isNewEntry);
- if ( ! $exists) {
+ if ($isNewEntry) {
if ($count > count($this->_values)) {
$this->_state = Doctrine_Record::STATE_TDIRTY;
} else {
@@ -252,7 +243,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
self::$_useAutoAccessorOverride = false; // @todo read from attribute the first time
- $this->_mapper->manage($this);
+ $this->_em->manage($this);
$this->construct();
}
@@ -510,13 +501,13 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$tmp = $data;
$data = array();
- $fieldNames = $this->_mapper->getFieldNames();
+ $fieldNames = $this->_em->getMapper($this->_entityName)->getFieldNames();
foreach ($fieldNames as $fieldName) {
if (isset($tmp[$fieldName])) {
$data[$fieldName] = $tmp[$fieldName];
} else if (array_key_exists($fieldName, $tmp)) {
$data[$fieldName] = Doctrine_Null::$INSTANCE;
- } else if (!isset($this->_data[$fieldName])) {
+ } else if ( ! isset($this->_data[$fieldName])) {
$data[$fieldName] = Doctrine_Null::$INSTANCE;
}
unset($tmp[$fieldName]);
@@ -554,7 +545,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
case Doctrine::IDENTIFIER_AUTOINC:
case Doctrine::IDENTIFIER_SEQUENCE:
case Doctrine::IDENTIFIER_NATURAL:
- $name = (array)$this->_class->getIdentifier();
+ $name = $this->_class->getIdentifier();
$name = $name[0];
if ($exists) {
if (isset($this->_data[$name]) && $this->_data[$name] !== Doctrine_Null::$INSTANCE) {
@@ -563,7 +554,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
break;
case Doctrine::IDENTIFIER_COMPOSITE:
- $names = (array)$this->_class->getIdentifier();
+ $names = $this->_class->getIdentifier();
foreach ($names as $name) {
if ($this->_data[$name] === Doctrine_Null::$INSTANCE) {
@@ -575,6 +566,14 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
break;
}
}
+
+ /**
+ * INTERNAL:
+ */
+ final public function setIdentifier(array $identifier)
+ {
+ $this->_id = $identifier;
+ }
/**
* Serializes the entity.
@@ -596,6 +595,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
unset($vars['_errorStack']);
unset($vars['_filter']);
unset($vars['_node']);
+ unset($vars['_em']);
//$name = (array)$this->_table->getIdentifier();
$this->_data = array_merge($this->_data, $this->_id);
@@ -642,13 +642,13 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->preUnserialize($event);
- $manager = Doctrine_Manager::getInstance();
+ $manager = Doctrine_Manager::getInstance();
$connection = $manager->getConnectionForComponent(get_class($this));
$this->_oid = self::$_index;
self::$_index++;
- $this->_mapper = $connection->getMapper(get_class($this));
+ $this->_em = $connection;
$array = unserialize($serialized);
@@ -656,7 +656,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->$k = $v;
}
- $this->_class = $this->_mapper->getTable();
+ $this->_entityName = get_class($this);
+ $this->_class = $this->_em->getClassMetadata($this->_entityName);
foreach ($this->_data as $k => $v) {
switch ($this->_class->getTypeOf($k)) {
@@ -674,7 +675,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
}
- $this->_mapper->manage($this);
+ $this->_em->manage($this);
$this->cleanData($this->_data);
$this->_extractIdentifier($this->exists());
@@ -749,7 +750,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$id = array_values($id);
if ($deep) {
- $query = $this->_mapper->createQuery();
+ $query = $this->_class->getConnection()->createQuery()->from($this->_entityName);
foreach (array_keys($this->_references) as $name) {
$query->leftJoin(get_class($this) . '.' . $name);
}
@@ -758,7 +759,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$record = $query->fetchOne($id);
} else {
// Use FETCH_ARRAY to avoid clearing object relations
- $record = $this->_mapper->find($id, Doctrine::HYDRATE_ARRAY);
+ $record = $this->getRepository()->find($this->identifier(), Doctrine::HYDRATE_ARRAY);
if ($record) {
$this->hydrate($record);
}
@@ -929,8 +930,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
}
return $this->_references[$fieldName];
} catch (Doctrine_Relation_Exception $e) {
- echo $e->getTraceAsString();
- echo "
";
+ //echo $e->getTraceAsString();
+ //echo "
";
foreach ($this->_class->getFilters() as $filter) {
if (($value = $filter->filterGet($this, $fieldName, $value)) !== null) {
return $value;
@@ -979,7 +980,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
if (isset($this->_data[$fieldName])) {
if ($value instanceof Doctrine_Record) {
$type = $this->_class->getTypeOf($fieldName);
- $id = $value->getIncremented();
+ // FIXME: composite key support
+ $ids = $value->identifier();
+ $id = count($ids) > 0 ? array_pop($ids) : null;
if ($id !== null && $type !== 'object') {
$value = $id;
}
@@ -998,6 +1001,13 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->_data[$fieldName] = $value;
$this->_modified[] = $fieldName;
+
+ /* We can't do this currently because there are tests that change
+ * the primary key of already persisted entities (ugh). */
+ if ($this->isTransient() && $this->_class->isIdentifier($fieldName)) {
+ $this->_id[$fieldName] = $value;
+ }
+
switch ($this->_state) {
case Doctrine_Record::STATE_CLEAN:
$this->_state = Doctrine_Record::STATE_DIRTY;
@@ -1011,8 +1021,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
try {
$this->_coreSetRelated($fieldName, $value);
} catch (Doctrine_Relation_Exception $e) {
- echo $e->getTraceAsString();
- echo "
";
+ //echo $e->getTraceAsString();
+ //echo "
";
foreach ($this->_class->getFilters() as $filter) {
if (($value = $filter->filterSet($this, $fieldName, $value)) !== null) {
return $value;
@@ -1131,7 +1141,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
public function save(Doctrine_Connection $conn = null)
{
// TODO: Forward to EntityManager. There: registerNew() OR registerDirty() on UnitOfWork.
- $this->_mapper->save($this, $conn);
+ $this->_em->save($this, $conn);
}
/**
@@ -1175,7 +1185,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
public function replace(Doctrine_Connection $conn = null)
{
if ($conn === null) {
- $conn = $this->_mapper->getConnection();
+ $conn = $this->_em;
}
return $conn->replace($this->_class, $this->getPrepared(), $this->_id);
@@ -1249,7 +1259,10 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
break;
default:
if ($this->_data[$field] instanceof Doctrine_Record) {
- $this->_data[$field] = $this->_data[$field]->getIncremented();
+ // FIXME: composite key support
+ $ids = $this->_data[$field]->identifier();
+ $id = count($ids) > 0 ? array_pop($ids) : null;
+ $this->_data[$field] = $id;
}
/** TODO:
if ($this->_data[$v] === null) {
@@ -1313,8 +1326,12 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
if ($this->_class->getIdentifierType() == Doctrine::IDENTIFIER_AUTOINC) {
$idFieldNames = (array)$this->_class->getIdentifier();
- $id = $idFieldNames[0];
- $a[$id] = $this->getIncremented();
+ $idFieldName = $idFieldNames[0];
+
+ $ids = $this->identifier();
+ $id = count($ids) > 0 ? array_pop($ids) : null;
+
+ $a[$idFieldName] = $id;
}
if ($deep) {
@@ -1460,17 +1477,41 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
* Checks whether the entity already has a persistent state.
*
* @return boolean TRUE if the object is new, FALSE otherwise.
+ * @deprecated Use isTransient()
*/
public function isNew()
{
return $this->_state == self::STATE_TCLEAN || $this->_state == self::STATE_TDIRTY;
}
+
+ /**
+ * Checks whether the entity already has a persistent state.
+ *
+ * @return boolean TRUE if the object is new, FALSE otherwise.
+ */
+ public function isTransient()
+ {
+ return $this->_state == self::STATE_TCLEAN || $this->_state == self::STATE_TDIRTY;
+ }
+
+ /**
+ * Checks whether the entity has been modified since it was last synchronized
+ * with the database.
+ *
+ * @return boolean TRUE if the object has been modified, FALSE otherwise.
+ */
+ public function isDirty()
+ {
+ return ($this->_state === Doctrine_Record::STATE_DIRTY ||
+ $this->_state === Doctrine_Record::STATE_TDIRTY);
+ }
/**
* Checks whether the entity has been modified since it was last synchronized
* with the database.
*
* @return boolean TRUE if the object has been modified, FALSE otherwise.
+ * @deprecated Use isDirty()
*/
public function isModified()
{
@@ -1496,6 +1537,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
/**
* getIterator
* @return Doctrine_Record_Iterator a Doctrine_Record_Iterator that iterates through the data
+ * @todo Really needed/useful?
*/
public function getIterator()
{
@@ -1513,7 +1555,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
public function delete(Doctrine_Connection $conn = null)
{
// TODO: Forward to EntityManager. There: registerRemoved() on UnitOfWork
- return $this->_mapper->delete($this, $conn);
+ return $this->_em->remove($this, $conn);
}
/**
@@ -1532,7 +1574,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
unset($data[$id]);
}
- $ret = $this->_mapper->create($data);
+ $ret = $this->_em->createEntity($this->_entityName, $data);
$modified = array();
foreach ($data as $key => $val) {
@@ -1581,7 +1623,7 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$this->_data[$fieldName] = $value;
}
} else {
- $idFieldNames = (array)$this->_class->getIdentifier();
+ $idFieldNames = $this->_class->getIdentifier();
$name = $idFieldNames[0];
$this->_id[$name] = $id;
$this->_data[$name] = $id;
@@ -1601,23 +1643,6 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
return $this->_id;
}
- /**
- * returns the value of autoincremented primary key of this object (if any)
- *
- * @return integer
- * @todo Better name? Not sure this is the right place here.
- * @todo Plays against full composite key support..
- */
- final public function getIncremented()
- {
- $id = current($this->_id);
- if ($id === false) {
- return null;
- }
-
- return $id;
- }
-
/**
* hasRefence
* @param string $name
@@ -1964,15 +1989,15 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
{
return $this->_class;
}
-
- /**
- * Returns the mapper of the entity.
- *
- * @return Doctrine_Mapper
- */
- public function getMapper()
+
+ public function getEntityManager()
{
- return $this->_mapper;
+ return $this->_em;
+ }
+
+ public function getRepository()
+ {
+ return $this->_class->getConnection()->getRepository($this->_entityName);
}
/**
@@ -2002,8 +2027,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
public function free($deep = false)
{
if ($this->_state != self::STATE_LOCKED) {
- $this->_mapper->detach($this);
- $this->_mapper->removeRecord($this);
+ $this->_em->detach($this);
+ $this->_em->removeRecord($this);
$this->_data = array();
$this->_id = array();
diff --git a/lib/Doctrine/Relation/Association.php b/lib/Doctrine/Relation/Association.php
index 81a0ac0ee..dfb744891 100644
--- a/lib/Doctrine/Relation/Association.php
+++ b/lib/Doctrine/Relation/Association.php
@@ -93,18 +93,15 @@ class Doctrine_Relation_Association extends Doctrine_Relation
* @return Doctrine_Record|Doctrine_Collection
*/
public function fetchRelatedFor(Doctrine_Record $record)
- {
- $id = $record->getIncremented();
- //var_dump($id);
- //echo "
";
+ {
+ // FIXME: composite key support
+ $ids = $record->identifier();
+ $id = count($ids) > 0 ? array_pop($ids) : null;
+
if (empty($id) || ! $this->_foreignMapper->getClassMetadata()->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));
- //echo $query->getDql() . "
";
- //echo $query->getSql() . "
";
- //echo "
";
$coll = Doctrine_Query::create()->query($this->getRelationDql(1), array($id));
}
$coll->setReference($record, $this);
diff --git a/lib/Doctrine/Relation/Association/Self.php b/lib/Doctrine/Relation/Association/Self.php
index 3da7ed57c..ec11adb38 100644
--- a/lib/Doctrine/Relation/Association/Self.php
+++ b/lib/Doctrine/Relation/Association/Self.php
@@ -18,7 +18,7 @@
* and is licensed under the LGPL. For more information, see
* .
*/
-Doctrine::autoload('Doctrine_Relation_Association');
+
/**
* Doctrine_Relation_Association_Self
*
@@ -75,8 +75,10 @@ class Doctrine_Relation_Association_Self extends Doctrine_Relation_Association
}
public function fetchRelatedFor(Doctrine_Record $record)
- {
- $id = $record->getIncremented();
+ {
+ // FIXME: composite key support
+ $ids = $record->identifier();
+ $id = count($ids) > 0 ? array_pop($ids) : null;
$q = new Doctrine_RawSql();
diff --git a/lib/Doctrine/Relation/Nest.php b/lib/Doctrine/Relation/Nest.php
index 07909c969..1c7c623fd 100644
--- a/lib/Doctrine/Relation/Nest.php
+++ b/lib/Doctrine/Relation/Nest.php
@@ -74,35 +74,11 @@ class Doctrine_Relation_Nest extends Doctrine_Relation_Association
return $dql;
}
- /**
public function fetchRelatedFor(Doctrine_Record $record)
{
- $id = $record->getIncremented();
-
- if (empty($id) || ! $this->definition['table']->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) {
- return new Doctrine_Collection($this->getTable());
- } else {
- $q = new Doctrine_Query();
-
- $c = $this->getTable()->getComponentName();
- $a = substr($c, 0, 1);
- $c2 = $this->getAssociationTable()->getComponentName();
- $a2 = substr($c2, 0, 1);
-
- $q->from($c)
- ->innerJoin($c . '.' . $c2)
-
- $sub = 'SELECT ' . $this->getForeign()
- . ' FROM ' . $c2
- . ' WHERE ' . $this->getLocal()
- . ' = ?';
- }
- }
- */
-
- public function fetchRelatedFor(Doctrine_Record $record)
- {
- $id = $record->getIncremented();
+ // FIXME: composite key support
+ $ids = $record->identifier();
+ $id = count($ids) > 0 ? array_pop($ids) : null;
if (empty($id) || ! $this->_foreignMapper->getClassMetadata()->getAttribute(Doctrine::ATTR_LOAD_REFERENCES)) {
diff --git a/lib/Doctrine/Relation/Parser.php b/lib/Doctrine/Relation/Parser.php
index a60aa1b68..2ff76cb4b 100644
--- a/lib/Doctrine/Relation/Parser.php
+++ b/lib/Doctrine/Relation/Parser.php
@@ -147,12 +147,6 @@ class Doctrine_Relation_Parser
$this->getRelations();
return $this->getRelation($alias, false);
} else {
- /*try {
- throw new Exception();
- } catch (Exception $e) {
- //echo "" . "
";
- ///echo $e->getTraceAsString() . "
";
- }*/
throw new Doctrine_Relation_Exception("Unknown relation '$alias'.");
}
}
diff --git a/lib/Doctrine/Validator.php b/lib/Doctrine/Validator.php
index e59f08e33..6898a1adf 100644
--- a/lib/Doctrine/Validator.php
+++ b/lib/Doctrine/Validator.php
@@ -84,7 +84,8 @@ class Doctrine_Validator
if ($value === Doctrine_Null::$INSTANCE) {
$value = null;
} else if ($value instanceof Doctrine_Record) {
- $value = $value->getIncremented();
+ $ids = $value->identifier();
+ $value = count($ids) > 0 ? array_pop($ids) : null;
}
$dataType = $classMetadata->getTypeOf($fieldName);
diff --git a/tests/Orm/Hydration/BasicHydrationTest.php b/tests/Orm/Hydration/BasicHydrationTest.php
index 1b21158a9..7c92fbf03 100644
--- a/tests/Orm/Hydration/BasicHydrationTest.php
+++ b/tests/Orm/Hydration/BasicHydrationTest.php
@@ -9,11 +9,22 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
parent::setUp();
}
+ /** The data of the hydration mode dataProvider */
+ protected static $hydrationModeProviderData = array(
+ array('hydrationMode' => Doctrine::HYDRATE_RECORD),
+ array('hydrationMode' => Doctrine::HYDRATE_ARRAY)
+ );
+ /** Getter for the hydration mode dataProvider */
+ public static function hydrationModeProvider()
+ {
+ return self::$hydrationModeProviderData;
+ }
+
/**
- * Fakes the DQL query: select u.id, u.name from CmsUser u
+ * Select u.id, u.name from CmsUser u
*
*/
- public function testBasic()
+ public function testBasicHydration()
{
// Faked query components
$queryComponents = array(
@@ -72,4 +83,285 @@ class Orm_Hydration_BasicHydrationTest extends Doctrine_OrmTestCase
$this->assertEquals('jwage', $objectResult[1]->name);
}
+
+ /**
+ * select u.id, u.status, p.phonenumber, upper(u.name) nameUpper from User u
+ * join u.phonenumbers p
+ * =
+ * select u.id, u.status, p.phonenumber, upper(u.name) as u__0 from USERS u
+ * INNER JOIN PHONENUMBERS p ON u.id = p.user_id
+ *
+ * @dataProvider hydrationModeProvider
+ */
+ public function testNewHydrationMixedQueryFetchJoin($hydrationMode)
+ {
+ // Faked query components
+ $queryComponents = array(
+ 'u' => array(
+ 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'),
+ 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'),
+ 'parent' => null,
+ 'relation' => null,
+ 'map' => null,
+ 'agg' => array('0' => 'nameUpper')
+ ),
+ 'p' => array(
+ 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'),
+ 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'),
+ 'parent' => 'u',
+ 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
+ 'map' => null
+ )
+ );
+
+ // Faked table alias map
+ $tableAliasMap = array(
+ 'u' => 'u',
+ 'p' => 'p'
+ );
+
+ // Faked result set
+ $resultSet = array(
+ //row1
+ array(
+ 'u__id' => '1',
+ 'u__status' => 'developer',
+ 'u__0' => 'ROMANB',
+ 'p__phonenumber' => '42',
+ ),
+ array(
+ 'u__id' => '1',
+ 'u__status' => 'developer',
+ 'u__0' => 'ROMANB',
+ 'p__phonenumber' => '43',
+ ),
+ array(
+ 'u__id' => '2',
+ 'u__status' => 'developer',
+ 'u__0' => 'JWAGE',
+ 'p__phonenumber' => '91'
+ )
+ );
+
+ $stmt = new Doctrine_HydratorMockStatement($resultSet);
+ $hydrator = new Doctrine_HydratorNew();
+ $hydrator->setQueryComponents($queryComponents);
+
+ $hydrator->setResultMixed(true);
+
+ $result = $hydrator->hydrateResultSet($stmt, $tableAliasMap, $hydrationMode);
+ //var_dump($result);
+
+ $this->assertEquals(2, count($result));
+ $this->assertTrue(is_array($result));
+ $this->assertTrue(is_array($result[0]));
+ $this->assertTrue(is_array($result[1]));
+
+ $this->assertEquals(3, count($result[0][0]));
+ // first user => 2 phonenumbers
+ $this->assertEquals(2, count($result[0][0]['phonenumbers']));
+ $this->assertEquals('ROMANB', $result[0]['nameUpper']);
+ // second user => 1 phonenumber
+ $this->assertEquals(1, count($result[1][0]['phonenumbers']));
+ $this->assertEquals('JWAGE', $result[1]['nameUpper']);
+
+ $this->assertEquals(42, $result[0][0]['phonenumbers'][0]['phonenumber']);
+ $this->assertEquals(43, $result[0][0]['phonenumbers'][1]['phonenumber']);
+ $this->assertEquals(91, $result[1][0]['phonenumbers'][0]['phonenumber']);
+
+ if ($hydrationMode == Doctrine::HYDRATE_RECORD) {
+ $this->assertTrue($result[0][0] instanceof Doctrine_Record);
+ $this->assertTrue($result[0][0]['phonenumbers'] instanceof Doctrine_Collection);
+ $this->assertTrue($result[0][0]['phonenumbers'][0] instanceof Doctrine_Record);
+ $this->assertTrue($result[0][0]['phonenumbers'][1] instanceof Doctrine_Record);
+ $this->assertTrue($result[1][0] instanceof Doctrine_Record);
+ $this->assertTrue($result[1][0]['phonenumbers'] instanceof Doctrine_Collection);
+ }
+ }
+
+ /**
+ * select u.id, u.status, count(p.phonenumber) numPhones from User u
+ * join u.phonenumbers p group by u.status, u.id
+ * =
+ * select u.id, u.status, count(p.phonenumber) as p__0 from USERS u
+ * INNER JOIN PHONENUMBERS p ON u.id = p.user_id group by u.id, u.status
+ *
+ * @dataProvider hydrationModeProvider
+ */
+ public function testNewHydrationBasicsMixedQueryNormalJoin($hydrationMode)
+ {
+ // Faked query components
+ $queryComponents = array(
+ 'u' => array(
+ 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'),
+ 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'),
+ 'parent' => null,
+ 'relation' => null,
+ 'map' => null
+ ),
+ 'p' => array(
+ 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'),
+ 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'),
+ 'parent' => 'u',
+ 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
+ 'map' => null,
+ 'agg' => array('0' => 'numPhones')
+ )
+ );
+
+ // Faked table alias map
+ $tableAliasMap = array(
+ 'u' => 'u',
+ 'p' => 'p'
+ );
+
+ // Faked result set
+ $resultSet = array(
+ //row1
+ array(
+ 'u__id' => '1',
+ 'u__status' => 'developer',
+ 'p__0' => '2',
+ ),
+ array(
+ 'u__id' => '2',
+ 'u__status' => 'developer',
+ 'p__0' => '1',
+ )
+ );
+
+
+ $stmt = new Doctrine_HydratorMockStatement($resultSet);
+ $hydrator = new Doctrine_HydratorNew();
+ $hydrator->setQueryComponents($queryComponents);
+
+ $hydrator->setResultMixed(true);
+
+ $result = $hydrator->hydrateResultSet($stmt, $tableAliasMap, $hydrationMode);
+ //var_dump($result);
+
+ $this->assertEquals(2, count($result));
+ $this->assertTrue(is_array($result));
+ $this->assertTrue(is_array($result[0]));
+ $this->assertTrue(is_array($result[1]));
+
+ // first user => 2 phonenumbers
+ $this->assertEquals(2, $result[0]['numPhones']);
+ // second user => 1 phonenumber
+ $this->assertEquals(1, $result[1]['numPhones']);
+
+ if ($hydrationMode == Doctrine::HYDRATE_RECORD) {
+ $this->assertTrue($result[0][0] instanceof Doctrine_Record);
+ $this->assertTrue($result[1][0] instanceof Doctrine_Record);
+ }
+ }
+
+ /**
+ * select u.id, u.status, upper(u.name) nameUpper from User u index by u.id
+ * join u.phonenumbers p indexby p.phonenumber
+ * =
+ * select u.id, u.status, upper(u.name) as p__0 from USERS u
+ * INNER JOIN PHONENUMBERS p ON u.id = p.user_id
+ *
+ * @dataProvider hydrationModeProvider
+ */
+ public function testNewHydrationMixedQueryFetchJoinCustomIndex($hydrationMode)
+ {
+ // Faked query components
+ $queryComponents = array(
+ 'u' => array(
+ 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsUser'),
+ 'mapper' => $this->sharedFixture['connection']->getMapper('CmsUser'),
+ 'parent' => null,
+ 'relation' => null,
+ 'agg' => array('0' => 'nameUpper'),
+ 'map' => 'id'
+ ),
+ 'p' => array(
+ 'table' => $this->sharedFixture['connection']->getClassMetadata('CmsPhonenumber'),
+ 'mapper' => $this->sharedFixture['connection']->getMapper('CmsPhonenumber'),
+ 'parent' => 'u',
+ 'relation' => $this->sharedFixture['connection']->getClassMetadata('CmsUser')->getRelation('phonenumbers'),
+ 'map' => 'phonenumber'
+ )
+ );
+
+ // Faked table alias map
+ $tableAliasMap = array(
+ 'u' => 'u',
+ 'p' => 'p'
+ );
+
+ // Faked result set
+ $resultSet = array(
+ //row1
+ array(
+ 'u__id' => '1',
+ 'u__status' => 'developer',
+ 'u__0' => 'ROMANB',
+ 'p__phonenumber' => '42',
+ ),
+ array(
+ 'u__id' => '1',
+ 'u__status' => 'developer',
+ 'u__0' => 'ROMANB',
+ 'p__phonenumber' => '43',
+ ),
+ array(
+ 'u__id' => '2',
+ 'u__status' => 'developer',
+ 'u__0' => 'JWAGE',
+ 'p__phonenumber' => '91'
+ )
+ );
+
+
+ $stmt = new Doctrine_HydratorMockStatement($resultSet);
+ $hydrator = new Doctrine_HydratorNew();
+ $hydrator->setQueryComponents($queryComponents);
+
+ // give the hydrator an artificial hint
+ $hydrator->setResultMixed(true);
+
+ $result = $hydrator->hydrateResultSet($stmt, $tableAliasMap, $hydrationMode);
+ if ($hydrationMode == Doctrine::HYDRATE_ARRAY) {
+ //var_dump($result);
+ }
+
+ $this->assertEquals(2, count($result));
+ $this->assertTrue(is_array($result));
+ $this->assertTrue(is_array($result[0]));
+ $this->assertTrue(is_array($result[1]));
+
+
+ // first user => 2 phonenumbers. notice the custom indexing by user id
+ $this->assertEquals(2, count($result[0]['1']['phonenumbers']));
+ // second user => 1 phonenumber. notice the custom indexing by user id
+ $this->assertEquals(1, count($result[1]['2']['phonenumbers']));
+
+ // test the custom indexing of the phonenumbers
+ $this->assertTrue(isset($result[0]['1']['phonenumbers']['42']));
+ $this->assertTrue(isset($result[0]['1']['phonenumbers']['43']));
+ $this->assertTrue(isset($result[1]['2']['phonenumbers']['91']));
+
+ // test the scalar values
+ $this->assertEquals('ROMANB', $result[0]['nameUpper']);
+ $this->assertEquals('JWAGE', $result[1]['nameUpper']);
+
+ if ($hydrationMode == Doctrine::HYDRATE_RECORD) {
+ $this->assertTrue($result[0]['1'] instanceof Doctrine_Record);
+ $this->assertTrue($result[1]['2'] instanceof Doctrine_Record);
+ $this->assertTrue($result[0]['1']['phonenumbers'] instanceof Doctrine_Collection);
+ $this->assertEquals(2, count($result[0]['1']['phonenumbers']));
+ }
+
+ }
+
+
+
+
+
+
+
+
}
\ No newline at end of file
diff --git a/tests/Orm/UnitOfWorkTestCase.php b/tests/Orm/UnitOfWorkTestCase.php
index a4f9dd985..819f43cf2 100644
--- a/tests/Orm/UnitOfWorkTestCase.php
+++ b/tests/Orm/UnitOfWorkTestCase.php
@@ -18,6 +18,8 @@ class Orm_UnitOfWorkTestCase extends Doctrine_OrmTestCase
public function testRegisterNew()
{
+ $this->_user->username = 'romanb';
+ $this->_user->id = 1;
$this->_unitOfWork->registerNew($this->_user);
$this->assertFalse($this->_unitOfWork->contains($this->_user));
$this->assertTrue($this->_unitOfWork->isRegisteredNew($this->_user));
@@ -35,7 +37,15 @@ class Orm_UnitOfWorkTestCase extends Doctrine_OrmTestCase
$this->assertTrue($this->_unitOfWork->isRegisteredDirty($this->_user));
$this->assertFalse($this->_unitOfWork->isRegisteredNew($this->_user));
$this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user));
-
+ }
+
+ public function testRegisterRemovedOnTransientEntityIsIgnored()
+ {
+ $this->_user->username = 'romanb';
+ $this->_user->id = 1;
+ $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user));
+ $this->_unitOfWork->registerRemoved($this->_user);
+ $this->assertFalse($this->_unitOfWork->isRegisteredRemoved($this->_user));
}
/*public function testSavedEntityHasIdentityAndIsManaged()
diff --git a/tests/models/cms/CmsPhonenumber.php b/tests/models/cms/CmsPhonenumber.php
new file mode 100644
index 000000000..a095a8ba9
--- /dev/null
+++ b/tests/models/cms/CmsPhonenumber.php
@@ -0,0 +1,9 @@
+mapColumn('user_id', 'integer', 4);
+ $class->mapColumn('phonenumber', 'string', 50, array('primary' => true));
+ }
+}
diff --git a/tests/models/cms/CmsUser.php b/tests/models/cms/CmsUser.php
index cfa93db2d..af8f17a2e 100644
--- a/tests/models/cms/CmsUser.php
+++ b/tests/models/cms/CmsUser.php
@@ -6,5 +6,8 @@ class CmsUser extends Doctrine_Record
$class->mapColumn('id', 'integer', 4, array('primary' => true, 'autoincrement' => true));
$class->mapColumn('username', 'string', 255);
$class->mapColumn('name', 'string', 255);
+
+ $class->hasMany('CmsPhonenumber as phonenumbers', array(
+ 'local' => 'id', 'foreign' => 'user_id'));
}
}
diff --git a/tests_old/AccessTestCase.php b/tests_old/AccessTestCase.php
index 1ccb6d730..e31ea50de 100644
--- a/tests_old/AccessTestCase.php
+++ b/tests_old/AccessTestCase.php
@@ -77,7 +77,7 @@ class Doctrine_Access_TestCase extends Doctrine_UnitTestCase
$user->save();
- $user = $this->connection->getMapper('User')->find($user->identifier());
+ $user = $this->connection->getRepository('User')->find($user->identifier());
$this->assertEqual($user->name, 'Jack');
$user['name'] = 'Jack';
@@ -97,7 +97,7 @@ class Doctrine_Access_TestCase extends Doctrine_UnitTestCase
$user->save();
- $user = $this->connection->getMapper('User')->find($user->identifier());
+ $user = $this->connection->getRepository('User')->find($user->identifier());
$this->assertEqual($user->name, 'Jack');
$user->name = 'Jack';
@@ -115,7 +115,7 @@ class Doctrine_Access_TestCase extends Doctrine_UnitTestCase
$user->save();
- $user = $this->connection->getMapper('User')->find($user->identifier());
+ $user = $this->connection->getRepository('User')->find($user->identifier());
$this->assertEqual($user->get('name'), 'Jack');
diff --git a/tests_old/ClassTableInheritanceTestCase.php b/tests_old/ClassTableInheritanceTestCase.php
index 815cd94c3..85f839638 100644
--- a/tests_old/ClassTableInheritanceTestCase.php
+++ b/tests_old/ClassTableInheritanceTestCase.php
@@ -168,7 +168,7 @@ class Doctrine_ClassTableInheritance_TestCase extends Doctrine_UnitTestCase
$profiler = new Doctrine_Connection_Profiler();
$this->conn->addListener($profiler);
- $record = $this->conn->getMapper('CTITest')->find(1);
+ $record = $this->conn->getRepository('CTITest')->find(1);
$record->age = 11;
$record->name = 'Jack';
@@ -193,7 +193,7 @@ class Doctrine_ClassTableInheritance_TestCase extends Doctrine_UnitTestCase
{
$this->conn->clear();
- $record = $this->conn->getMapper('CTITest')->find(1);
+ $record = $this->conn->getRepository('CTITest')->find(1);
$this->assertEqual($record->id, 1);
$this->assertEqual($record->name, 'Jack');
@@ -209,7 +209,7 @@ class Doctrine_ClassTableInheritance_TestCase extends Doctrine_UnitTestCase
$profiler = new Doctrine_Connection_Profiler();
$this->conn->addListener($profiler);
- $record = $this->conn->getMapper('CTITest')->find(1);
+ $record = $this->conn->getRepository('CTITest')->find(1);
$record->delete();
diff --git a/tests_old/CustomPrimaryKeyTestCase.php b/tests_old/CustomPrimaryKeyTestCase.php
index d31c200b3..445232090 100644
--- a/tests_old/CustomPrimaryKeyTestCase.php
+++ b/tests_old/CustomPrimaryKeyTestCase.php
@@ -53,7 +53,7 @@ class Doctrine_CustomPrimaryKey_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($c->identifier(), array('uid' => 1));
$this->connection->clear();
- $c = $this->connection->getMapper('CustomPK')->find(1);
+ $c = $this->connection->getRepository('CustomPK')->find(1);
$this->assertEqual($c->identifier(), array('uid' => 1));
}
diff --git a/tests_old/DataType/BooleanTestCase.php b/tests_old/DataType/BooleanTestCase.php
index 92afbf534..72e92d56a 100644
--- a/tests_old/DataType/BooleanTestCase.php
+++ b/tests_old/DataType/BooleanTestCase.php
@@ -60,7 +60,7 @@ class Doctrine_DataType_Boolean_TestCase extends Doctrine_UnitTestCase {
$this->connection->clear();
- $test = $test->getMapper()->find($test->id);
+ $test = $test->getRepository()->find($test->id);
$this->assertIdentical($test->is_working, true);
}
public function testNormalQuerying() {
diff --git a/tests_old/DataType/EnumTestCase.php b/tests_old/DataType/EnumTestCase.php
index b7c3de088..1a5fe6af2 100644
--- a/tests_old/DataType/EnumTestCase.php
+++ b/tests_old/DataType/EnumTestCase.php
@@ -172,7 +172,7 @@ class Doctrine_DataType_Enum_TestCase extends Doctrine_UnitTestCase
public function testFailingRefresh()
{
- $enum = $this->connection->getMapper('EnumTest')->find(1);
+ $enum = $this->connection->getRepository('EnumTest')->find(1);
$this->conn->exec('DELETE FROM enum_test WHERE id = 1');
diff --git a/tests_old/DoctrineTest/Doctrine_UnitTestCase.php b/tests_old/DoctrineTest/Doctrine_UnitTestCase.php
index 0028f8a64..4299675ff 100644
--- a/tests_old/DoctrineTest/Doctrine_UnitTestCase.php
+++ b/tests_old/DoctrineTest/Doctrine_UnitTestCase.php
@@ -197,7 +197,7 @@ class Doctrine_UnitTestCase extends UnitTestCase
//echo "exporting : " . var_dump($this->tables);
//echo "
";
$this->conn->export->exportClasses($this->tables);
- $this->objTable = $this->connection->getMapper('User');
+ $this->objTable = $this->connection->getRepository('User');
}
public function prepareData()
diff --git a/tests_old/Inheritance/JoinedTestCase.php b/tests_old/Inheritance/JoinedTestCase.php
index e97078ddb..00cfb0d57 100644
--- a/tests_old/Inheritance/JoinedTestCase.php
+++ b/tests_old/Inheritance/JoinedTestCase.php
@@ -152,7 +152,7 @@ class Doctrine_Inheritance_Joined_TestCase extends Doctrine_UnitTestCase
public function testDqlQueryJoinsTransparentlyAcrossParents()
{
$this->_createManager();
- $this->conn->getMapper('CTI_Manager')->clear();
+ $this->conn->clear('CTI_Manager');
$query = $this->conn->createQuery();
$query->parseQuery("SELECT m.* FROM CTI_Manager m");
@@ -167,8 +167,8 @@ class Doctrine_Inheritance_Joined_TestCase extends Doctrine_UnitTestCase
public function testQueryingBaseClassOuterJoinsSubClassesAndReturnsSubclassInstances()
{
$this->_createManager();
- $this->conn->getMapper('CTI_Manager')->clear();
- $this->conn->getMapper('CTI_User')->clear();
+ $this->conn->clear('CTI_Manager');
+ $this->conn->clear('CTI_User');
$query = $this->conn->createQuery();
$query->parseQuery("SELECT u.* FROM CTI_User u");
diff --git a/tests_old/Query/JoinCondition2TestCase.php b/tests_old/Query/JoinCondition2TestCase.php
index d75e3ca3a..6530403a0 100755
--- a/tests_old/Query/JoinCondition2TestCase.php
+++ b/tests_old/Query/JoinCondition2TestCase.php
@@ -41,9 +41,9 @@ class Doctrine_Query_JoinCondition2_TestCase extends Doctrine_UnitTestCase
public function prepareData()
{
- $this->conn->getMapper('User')->clear();
- $this->conn->getMapper('Group')->clear();
- $this->conn->getMapper('Groupuser')->clear();
+ $this->conn->clear('User');
+ $this->conn->clear('Group');
+ $this->conn->clear('Groupuser');
$zYne = new User();
$zYne->name = 'zYne';
diff --git a/tests_old/Query/MultiJoinTestCase.php b/tests_old/Query/MultiJoinTestCase.php
index 3c9fce0fb..00f7d8d84 100644
--- a/tests_old/Query/MultiJoinTestCase.php
+++ b/tests_old/Query/MultiJoinTestCase.php
@@ -43,7 +43,7 @@ class Doctrine_Query_MultiJoin_TestCase extends Doctrine_UnitTestCase
$query = new Doctrine_Query($this->connection);
- $user = $this->connection->getMapper('User')->find(4);
+ $user = $this->connection->getRepository('User')->find(4);
$album = $this->connection->create('Album');
@@ -73,7 +73,7 @@ class Doctrine_Query_MultiJoin_TestCase extends Doctrine_UnitTestCase
$this->assertEqual(count($user->Album[1]->Song), 4);
- $user = $this->connection->getMapper('User')->find(5);
+ $user = $this->connection->getRepository('User')->find(5);
$user->Album[0]->name = 'Clayman';
$user->Album[1]->name = 'Colony';
@@ -122,7 +122,7 @@ class Doctrine_Query_MultiJoin_TestCase extends Doctrine_UnitTestCase
public function testInitializeMoreData()
{
- $user = $this->connection->getMapper('User')->find(4);
+ $user = $this->connection->getRepository('User')->find(4);
$user->Book[0]->name = 'The Prince';
$user->Book[0]->Author[0]->name = 'Niccolo Machiavelli';
$user->Book[0]->Author[1]->name = 'Someone';
@@ -133,7 +133,7 @@ class Doctrine_Query_MultiJoin_TestCase extends Doctrine_UnitTestCase
$user->save();
- $user = $this->connection->getMapper('User')->find(5);
+ $user = $this->connection->getRepository('User')->find(5);
$user->Book[0]->name = 'Zadig';
$user->Book[0]->Author[0]->name = 'Voltaire';
$user->Book[0]->Author[1]->name = 'Someone';
diff --git a/tests_old/Query/ReferenceModelTestCase.php b/tests_old/Query/ReferenceModelTestCase.php
index ccf2bf0de..b4c545918 100644
--- a/tests_old/Query/ReferenceModelTestCase.php
+++ b/tests_old/Query/ReferenceModelTestCase.php
@@ -60,7 +60,7 @@ class Doctrine_Query_ReferenceModel_TestCase extends Doctrine_UnitTestCase {
$this->connection->unitOfWork->saveAll();
$this->connection->clear();
- $category = $category->getMapper()->find($category->id);
+ $category = $category->getRepository()->find($category->id);
$this->assertEqual($category->name, 'Root');
$this->assertEqual($category->Subcategory[0]->name, 'Sub 1');
diff --git a/tests_old/Query/RegistryTestCase.php b/tests_old/Query/RegistryTestCase.php
index 2755df600..a1e85a72f 100644
--- a/tests_old/Query/RegistryTestCase.php
+++ b/tests_old/Query/RegistryTestCase.php
@@ -62,6 +62,6 @@ class Doctrine_Query_Registry_TestCase extends Doctrine_UnitTestCase
$user = new User();
- $user->getMapper()->executeNamedQuery('User.all');
+ $user->getEntityManager()->executeNamedQuery('User.all');
}
}
diff --git a/tests_old/RecordTestCase.php b/tests_old/RecordTestCase.php
index 560aff6c9..666b35070 100644
--- a/tests_old/RecordTestCase.php
+++ b/tests_old/RecordTestCase.php
@@ -89,7 +89,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($account->amount, 2000);
- $user = $user->getMapper()->find($user->id);
+ $user = $user->getRepository()->find($user->id);
$this->assertEqual($user->state(), Doctrine_Record::STATE_CLEAN);
@@ -148,7 +148,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($gzip->gzip, "compressed");
$this->connection->clear();
- $gzip = $gzip->getMapper()->find($gzip->id);
+ $gzip = $gzip->getRepository()->find($gzip->id);
$this->assertEqual($gzip->gzip, "compressed");
$gzip->gzip = "compressed 2";
@@ -209,7 +209,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertTrue(array_key_exists('id', $a));
$this->assertTrue(is_numeric($a['id']));
$this->connection->clear();
- $user = $user->getMapper()->find($user->id);
+ $user = $user->getRepository()->find($user->id);
$a = $user->toArray();
@@ -231,7 +231,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testUpdatingWithNullValue()
{
- $user = $this->connection->getMapper('User')->find(5);
+ $user = $this->connection->getRepository('User')->find(5);
$user->name = null;
$this->assertEqual($user->name, null);
@@ -241,7 +241,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->connection->clear();
- $user = $this->connection->getMapper('User')->find(5);
+ $user = $this->connection->getRepository('User')->find(5);
$this->assertEqual($user->name, null);
@@ -249,7 +249,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testSerialize()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$str = serialize($user);
$user2 = unserialize($str);
@@ -279,7 +279,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($record->entity2, 4);
$this->assertEqual($record->entity1, 3);
$this->assertEqual($record->state(), Doctrine_Record::STATE_TDIRTY);
- $this->assertEqual($record->identifier(), array("entity1" => null, "entity2" => null));
+ $this->assertEqual($record->identifier(), array("entity1" => 3, "entity2" => 4));
$record->save();
$this->assertEqual($record->state(), Doctrine_Record::STATE_CLEAN);
@@ -287,7 +287,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($record->entity1, 3);
$this->assertEqual($record->identifier(), array("entity1" => 3, "entity2" => 4));
- $record = $record->getMapper()->find($record->identifier());
+ $record = $record->getRepository()->find($record->identifier());
$this->assertEqual($record->state(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 4);
$this->assertEqual($record->entity1, 3);
@@ -300,20 +300,21 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->identifier(), array("entity1" => 3, "entity2" => 4));
-
+
$record->save();
$this->assertEqual($record->state(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->identifier(), array("entity1" => 2, "entity2" => 5));
- $record = $record->getMapper()->find($record->identifier());
-
+ $record = $record->getRepository()->find($record->identifier());
+
$this->assertEqual($record->state(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
$this->assertEqual($record->identifier(), array("entity1" => 2, "entity2" => 5));
$record->refresh();
+
$this->assertEqual($record->state(), Doctrine_Record::STATE_CLEAN);
$this->assertEqual($record->entity2, 5);
$this->assertEqual($record->entity1, 2);
@@ -368,7 +369,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->connection->unitOfWork->saveAll();
- $task = $task->getMapper()->find($task->identifier());
+ $task = $task->getRepository()->find($task->identifier());
$this->assertEqual($task->name, "Task 1");
$this->assertEqual($task->ResourceAlias[0]->name, "Resource 1");
@@ -386,7 +387,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($user->updated, null);
$user->save();
$id = $user->identifier();
- $user = $user->getMapper()->find($id);
+ $user = $user->getRepository()->find($id);
$this->assertEqual($user->name, "Jack Daniels");
$this->assertEqual($user->created, null);
$this->assertEqual($user->updated, null);
@@ -439,12 +440,12 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$elements = $this->connection->query("FROM Element");
$this->assertEqual($elements->count(), 5);
- $e = $e->getMapper()->find(1);
+ $e = $e->getRepository()->find(1);
$this->assertEqual($e->name,"parent");
$this->assertEqual($e->Child[0]->name,"child 1");
- $c = $e->getMapper()->find(2);
+ $c = $e->getRepository()->find(2);
$this->assertEqual($c->name, "child 1");
$this->assertEqual($e->Child[0]->parent_id, 1);
@@ -553,7 +554,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testUpdate()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$user->set("name","Jack Daniels",true);
@@ -566,7 +567,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testCopy()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$new = $user->copy();
$this->assertTrue($new instanceof Doctrine_Record);
@@ -583,7 +584,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testCopyAndModify()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$new = $user->copy();
$this->assertTrue($new instanceof Doctrine_Record);
@@ -604,7 +605,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testReferences()
{
- $user = $this->connection->getMapper('User')->find(5);
+ $user = $this->connection->getRepository('User')->find(5);
$this->assertTrue($user->Phonenumber instanceof Doctrine_Collection);
$this->assertEqual($user->Phonenumber->count(), 3);
@@ -615,7 +616,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
$this->assertEqual($user->Phonenumber->count(), 0);
$user->save();
- $user->getMapper()->clear();
+ $user->getEntityManager()->clear('User');
$user = $this->objTable->find(5);
@@ -736,15 +737,11 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testSaveAssociations()
{
- $userMapper = $this->connection->getMapper('User');
+ $userMapper = $this->connection->getRepository('User');
$user = $userMapper->find(5);
- $this->assertTrue($userMapper === $user->getMapper());
- $this->assertTrue($userMapper->getTable() === $user->getMapper()->getTable());
- $this->assertTrue($userMapper->getTable() === $this->conn->getClassMetadata('User'));
- $this->assertTrue($this->conn === $userMapper->getConnection());
- $userTable = $userMapper->getTable();
+ $userTable = $this->connection->getClassMetadata('User');
/*echo get_class($rel1) . "
";
echo get_class($rel2) . "
";
echo get_class($userTable->getRelation('Group'));
@@ -753,7 +750,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
echo "local:" . $rel2->getLocal() . "---foreign:" . $rel2->getForeign() . "
";
echo "........
";*/
- $gf = $this->connection->getMapper("Group");
+ $gf = $this->connection->getRepository("Group");
//echo "start";
$this->assertTrue($user->Group instanceof Doctrine_Collection);
//echo "end";
@@ -865,14 +862,14 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testCount()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$this->assertTrue(is_integer($user->count()));
}
public function testGetReference()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$this->assertTrue($user->Email instanceof Doctrine_Record);
$this->assertTrue($user->Phonenumber instanceof Doctrine_Collection);
@@ -882,13 +879,13 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
}
public function testGetIterator()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$this->assertTrue($user->getIterator() instanceof ArrayIterator);
}
public function testRefreshRelated()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$user->Address[0]->address = "Address #1";
$user->Address[1]->address = "Address #2";
$user->save();
@@ -904,7 +901,7 @@ class Doctrine_Record_TestCase extends Doctrine_UnitTestCase
public function testRefreshDeep()
{
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
$user->Address[0]->address = "Address #1";
$user->Address[1]->address = "Address #2";
$user->save();
diff --git a/tests_old/Relation/NestTestCase.php b/tests_old/Relation/NestTestCase.php
index 6da81c467..263f94c10 100644
--- a/tests_old/Relation/NestTestCase.php
+++ b/tests_old/Relation/NestTestCase.php
@@ -117,7 +117,7 @@ class Doctrine_Relation_Nest_TestCase extends Doctrine_UnitTestCase
$this->connection->clear();
- $e = $e->getMapper()->find($e->id);
+ $e = $e->getRepository()->find($e->id);
$count = count($this->conn);
diff --git a/tests_old/TableTestCase.php b/tests_old/TableTestCase.php
index 9da171a4a..72f043653 100644
--- a/tests_old/TableTestCase.php
+++ b/tests_old/TableTestCase.php
@@ -83,7 +83,7 @@ class Doctrine_Table_TestCase extends Doctrine_UnitTestCase
$this->connection->clear();
- $t = $this->connection->getMapper('FieldNameTest')->find(1);
+ $t = $this->connection->getRepository('FieldNameTest')->find(1);
$this->assertEqual($t->someColumn, 'abc');
$this->assertEqual($t->someEnum, 'php');
diff --git a/tests_old/Ticket/626DTestCase.php b/tests_old/Ticket/626DTestCase.php
index beee47686..a2388c215 100644
--- a/tests_old/Ticket/626DTestCase.php
+++ b/tests_old/Ticket/626DTestCase.php
@@ -37,7 +37,7 @@ class Doctrine_Ticket_626D_TestCase extends Doctrine_UnitTestCase
$student1 = $this->newStudent('T626D_Student1', '07090002', 'First Student');
try {
- $student = $this->conn->getMapper('T626D_Student1')->find('07090002');
+ $student = $this->conn->getRepository('T626D_Student1')->find('07090002');
$this->pass();
} catch (Exception $e) {
$this->fail($e->__toString());
diff --git a/tests_old/ValidatorTestCase.php b/tests_old/ValidatorTestCase.php
index 6ea8c1174..1c4636e03 100644
--- a/tests_old/ValidatorTestCase.php
+++ b/tests_old/ValidatorTestCase.php
@@ -140,7 +140,7 @@ class Doctrine_Validator_TestCase extends Doctrine_UnitTestCase
public function testValidate()
{
$this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
- $user = $this->connection->getMapper('User')->find(4);
+ $user = $this->connection->getRepository('User')->find(4);
$set = array('password' => 'this is an example of too long password',
'loginname' => 'this is an example of too long loginname',
@@ -200,7 +200,7 @@ class Doctrine_Validator_TestCase extends Doctrine_UnitTestCase
public function testSave()
{
$this->manager->setAttribute(Doctrine::ATTR_VALIDATE, Doctrine::VALIDATE_ALL);
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
try {
$user->name = "this is an example of too long name not very good example but an example nevertheless";
$user->save();
@@ -260,7 +260,7 @@ class Doctrine_Validator_TestCase extends Doctrine_UnitTestCase
}
// Tests validateOnUpdate()
- $user = $this->connection->getMapper("User")->find(4);
+ $user = $this->connection->getRepository("User")->find(4);
try {
$user->name = "The Saint"; // Set correct name
$user->password = "Top Secret"; // Set correct password
@@ -337,7 +337,7 @@ class Doctrine_Validator_TestCase extends Doctrine_UnitTestCase
$r->identifier = '1234';
$r->save();
- $r = $this->connection->getMapper('ValidatorTest_Person')->findAll()->getFirst();
+ $r = $this->connection->getRepository('ValidatorTest_Person')->findAll()->getFirst();
$r->identifier = 1234;
try {
$r->save();