Compare commits

...

45 Commits
2.2.2 ... 2.0.1

Author SHA1 Message Date
Benjamin Eberlei
5e61b73619 Fix version of 2.0.x branch to 2.0.1-DEV 2011-01-30 17:16:30 +01:00
Benjamin Eberlei
23ac0026a0 Merge remote branch 'origin/2.0.x' into 2.0.x 2011-01-30 17:14:35 +01:00
Benjamin Eberlei
65e85aa471 Update dependencies to Common 2.0.1 and DBAL 2.0.1 2011-01-30 17:14:07 +01:00
Benjamin Eberlei
d5b61ec897 Update build.xml workflow 2011-01-30 17:11:56 +01:00
Benjamin Eberlei
adc2f24c9a Merge branch 'DDC-892' into 2.0.x 2011-01-23 20:54:03 +01:00
Benjamin Eberlei
8423c0c608 DDC-892 - Implement separate chaining approach for result caches to prevent hash colissions. 2011-01-23 20:53:20 +01:00
Benjamin Eberlei
44aa098b37 Merge branch 'GenerationTools' into 2.0.x 2011-01-23 20:27:02 +01:00
Benjamin Eberlei
839ec8f25a Significantly updated the Help of the ConvertMapping and GenerateEntities Commands to help people using and understanding their scope. Added an additional --force flag to ConvertMapping command. 2011-01-23 20:26:56 +01:00
Benjamin Eberlei
0893d2eb00 Merge branch 'DDC-958' into 2.0.x 2011-01-23 17:28:24 +01:00
Benjamin Eberlei
b63babc7b8 DDC-958 - Fire postLoad event when calling refresh(). 2011-01-23 17:28:16 +01:00
Benjamin Eberlei
7350d85a4b Merge branch 'DDC-968' into 2.0.x 2011-01-23 16:48:08 +01:00
Benjamin Eberlei
a6b81d684a DDC-968 - Add AbstractQuery::getHints() method 2011-01-23 16:47:48 +01:00
Benjamin Eberlei
9e864c3662 Merge branch 'DDC-969' into 2.0.x 2011-01-23 16:13:12 +01:00
Benjamin Eberlei
024cc43189 DDC-969 - Use of field instead of column when accessing a table leads to error when both differ. 2011-01-23 16:12:59 +01:00
Benjamin Eberlei
1e79672147 Merge branch 'DDC-978' into 2.0.x 2011-01-23 15:41:02 +01:00
Benjamin Eberlei
3b7448bcf4 DDC-978 - Fix bug where Collection gets cleared (again) when calling flush multiple times and replacing a PersistentCollection with a new one. 2011-01-23 15:40:54 +01:00
Benjamin Eberlei
d5025235f3 Merge branch 'DDC-996' into 2.0.x 2011-01-23 14:24:13 +01:00
Benjamin Eberlei
dbc1a4da4b DDC-996 - Throw more useful exception if fieldName is empty in a mapped field or association. 2011-01-23 14:23:25 +01:00
Benjamin Eberlei
837d3f0f80 Merge branch 'DDc-960' into 2.0.x 2011-01-23 12:58:55 +01:00
Benjamin Eberlei
203fb59115 DDC-960 - Bugfix in how Persisters generate Fetch last version of Entity SQL. 2011-01-23 12:58:27 +01:00
Benjamin Eberlei
ecdc0fad64 Merge branch 'DDC-975' into 2.0.x 2011-01-13 21:45:44 +01:00
Benjamin Eberlei
e1fd2c158b DDC-975 - Fix notice in SchemaTool in combination with XML mapping driver. 2011-01-13 21:45:30 +01:00
Benjamin Eberlei
479dae2a99 Merge branch 'DDC-980' into 2.0.x 2011-01-13 21:18:46 +01:00
Benjamin Eberlei
d94c2a11e8 DDC-980 - Fix Update and Delete statements reference of the root table when doing subselects. 2011-01-13 21:18:23 +01:00
Benjamin Eberlei
d44b9fb05c Merge branch 'DDC-965' into 2.0.x 2011-01-02 10:25:37 +01:00
Benjamin Eberlei
fc16ecc6d7 DDC-965 - Defer ID check after loadMetata event is fired. 2011-01-02 10:25:23 +01:00
Benjamin Eberlei
1c9007fb0e Merge branch 'DDC-966' into 2.0.x 2011-01-02 10:19:06 +01:00
Benjamin Eberlei
79dc69b920 DDC-966 - Fix NOT NULL constraint SingleTableInheritance Generation using SchemaTool. 2011-01-02 10:18:55 +01:00
Benjamin Eberlei
5e22a08ee1 Merge branch 'DDC-949' into 2.0.x 2011-01-02 09:43:21 +01:00
Benjamin Eberlei
3d43049426 DDC-949 - Bugfix for BasicEntityPersister not using $types for select clauses. This fixes the issue for PostgreSQL however it still occurs on Oracle. DBAL change is necessary for this. 2011-01-02 09:43:04 +01:00
Benjamin Eberlei
95464c95fa Merge branch 'DDC-945-2' into 2.0.x 2010-12-31 14:39:49 +01:00
Benjamin Eberlei
392d23e401 DDC-945 - Fix regression, ManyToMany unidirectional owning side assocations should be allowed. 2010-12-31 14:39:38 +01:00
Benjamin Eberlei
19db4f304d Merge branch 'DDC-929' into 2.0.x 2010-12-30 23:18:49 +01:00
Benjamin Eberlei
aeaeff9002 DDC-929 - Fix bug with DatabaseDriver not detecting indexes that are not called primary. 2010-12-30 23:18:36 +01:00
Benjamin Eberlei
9bc236b4fa Merge branch 'DDC-961' into 2.0.x 2010-12-30 22:31:39 +01:00
Benjamin Eberlei
cd6611ad3e DDC-961 - Bugfix with missing first letter in automatic join table names in global namespace entities. 2010-12-30 22:31:24 +01:00
Benjamin Eberlei
41e5fc6b34 Merge branch 'DDC-837' into 2.0.x 2010-12-28 14:58:56 +01:00
Benjamin Eberlei
615a1159a7 DDC-837 - Fix bug with associations of the same name not being possible in inheritance hierachies. 2010-12-28 14:58:30 +01:00
Benjamin Eberlei
1059991865 Merge branch 'DDC-928' into 2.0.x 2010-12-28 12:20:28 +01:00
Benjamin Eberlei
18fc94b395 DDC-928 - Fix undefined variable notice. 2010-12-28 12:20:10 +01:00
Benjamin Eberlei
b288eac530 Merge branch 'DDC-945' into 2.0.x 2010-12-28 12:01:17 +01:00
Benjamin Eberlei
699cd2cf4b DDC-945 - Throw exception in ClassMetadataFactory when mapped superclass has to many associations. 2010-12-28 12:00:42 +01:00
Benjamin Eberlei
c1f10b4673 DDC-617 - Throw error if selecting identification variables without picking at least one root entity alias. 2010-12-28 10:21:25 +01:00
Benjamin Eberlei
6bff8c338f DDC-931 - SchemaTool#dropSchema() should not stop on failure of a single query (as stated in docblocks). 2010-12-22 23:07:27 +01:00
Benjamin Eberlei
1ca924d021 Fix for DDC-944 2010-12-22 00:19:03 +01:00
39 changed files with 985 additions and 221 deletions

View File

@@ -1,6 +1,6 @@
version=2.0.0BETA2
dependencies.common=2.0.0BETA4
dependencies.dbal=2.0.0BETA4
version=2.0.1
dependencies.common=2.0.1
dependencies.dbal=2.0.1
stability=beta
build.dir=build
dist.dir=dist

View File

@@ -184,9 +184,12 @@
</target>
<target name="git-tag">
<exec command="grep '${version}' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<exec command="git tag -a ${version}" passthru="true" />
<exec command="git push origin ${version}" passthru="true" />
<exec command="grep '${version}-DEV' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<exec command="sed 's/${version}-DEV/${version}-DEV/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${project.basedir}/lib/Doctrine/ORM/Version2.php ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git add ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git commit -m 'Release ${version}'" />
<exec command="git tag -m 'Tag ${version}' -a ${version}" passthru="true" />
</target>
<target name="pirum-release">
@@ -201,11 +204,10 @@
<target name="update-dev-version">
<exec command="grep '${version}' ${project.basedir}/lib/Doctrine/ORM/Version.php" checkreturn="true"/>
<propertyprompt propertyName="next_version" defaultValue="${version}" promptText="Enter next version string (without -DEV)" />
<exec command="sed 's/${version}-DEV/${next_version}-DEV/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="sed 's/${version}/${next_version}-DEV/' ${project.basedir}/lib/Doctrine/ORM/Version.php > ${project.basedir}/lib/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${project.basedir}/lib/Doctrine/ORM/Version2.php ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git add ${project.basedir}/lib/Doctrine/ORM/Version.php" passthru="true" />
<exec command="git commit -m 'Bump Dev Version to ${next_version}-DEV'" passthru="true" />
<exec command="git push origin master" passthru="true" />
</target>
<target name="release" depends="git-tag,build-packages,distribute-download,pirum-release,update-dev-version" />

View File

@@ -458,6 +458,16 @@ abstract class AbstractQuery
return isset($this->_hints[$name]) ? $this->_hints[$name] : false;
}
/**
* Return the key value map of query hints that are currently set.
*
* @return array
*/
public function getHints()
{
return $this->_hints;
}
/**
* Executes the query and returns an IterableResult that can be used to incrementally
* iterate over the result.
@@ -496,10 +506,10 @@ abstract class AbstractQuery
// Check result cache
if ($this->_useResultCache && $cacheDriver = $this->getResultCacheDriver()) {
$id = $this->_getResultCacheId();
list($id, $hash) = $this->getResultCacheId();
$cached = $this->_expireResultCache ? false : $cacheDriver->fetch($id);
if ($cached === false) {
if ($cached === false || !isset($cached[$id])) {
// Cache miss.
$stmt = $this->_doExecute();
@@ -512,7 +522,7 @@ abstract class AbstractQuery
return $result;
} else {
// Cache hit.
return $cached;
return $cached[$id];
}
}
@@ -546,12 +556,12 @@ abstract class AbstractQuery
* Will return the configured id if it exists otherwise a hash will be
* automatically generated for you.
*
* @return string $id
* @return array ($id, $hash)
*/
protected function _getResultCacheId()
protected function getResultCacheId()
{
if ($this->_resultCacheId) {
return $this->_resultCacheId;
return array($this->_resultCacheId, $this->_resultCacheId);
} else {
$params = $this->_params;
foreach ($params AS $key => $value) {
@@ -563,13 +573,16 @@ abstract class AbstractQuery
$idValues = $class->getIdentifierValues($value);
}
$params[$key] = $idValues;
} else {
$params[$key] = $value;
}
}
$sql = $this->getSql();
ksort($this->_hints);
return md5(implode(";", (array)$sql) . var_export($params, true) .
var_export($this->_hints, true)."&hydrationMode=".$this->_hydrationMode);
$key = implode(";", (array)$sql) . var_export($params, true) .
var_export($this->_hints, true)."&hydrationMode=".$this->_hydrationMode;
return array($key, md5($key));
}
}

View File

@@ -284,10 +284,6 @@ class ClassMetadataFactory
throw MappingException::reflectionFailure($className, $e);
}
// Verify & complete identifier mapping
if ( ! $class->identifier && ! $class->isMappedSuperclass) {
throw MappingException::identifierRequired($className);
}
if ($parent && ! $parent->isMappedSuperclass) {
if ($parent->isIdGeneratorSequence()) {
$class->setSequenceGeneratorDefinition($parent->sequenceGeneratorDefinition);
@@ -315,6 +311,11 @@ class ClassMetadataFactory
$this->evm->dispatchEvent(Events::loadClassMetadata, $eventArgs);
}
// Verify & complete identifier mapping
if ( ! $class->identifier && ! $class->isMappedSuperclass) {
throw MappingException::identifierRequired($className);
}
// verify inheritance
if (!$parent && !$class->isMappedSuperclass && !$class->isInheritanceTypeNone()) {
if (count($class->discriminatorMap) == 0) {
@@ -382,6 +383,9 @@ class ClassMetadataFactory
{
foreach ($parentClass->associationMappings as $field => $mapping) {
if ($parentClass->isMappedSuperclass) {
if ($mapping['type'] & ClassMetadata::TO_MANY && !$mapping['isOwningSide']) {
throw MappingException::illegalToManyAssocationOnMappedSuperclass($parentClass->name, $field);
}
$mapping['sourceEntity'] = $subClass->name;
}

View File

@@ -643,8 +643,8 @@ class ClassMetadataInfo
protected function _validateAndCompleteFieldMapping(array &$mapping)
{
// Check mandatory fields
if ( ! isset($mapping['fieldName'])) {
throw MappingException::missingFieldName($this->name, $mapping);
if ( ! isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) {
throw MappingException::missingFieldName($this->name);
}
if ( ! isset($mapping['type'])) {
// Default to string
@@ -711,8 +711,8 @@ class ClassMetadataInfo
}
// Mandatory: fieldName, targetEntity
if ( ! isset($mapping['fieldName'])) {
throw MappingException::missingFieldName();
if ( ! isset($mapping['fieldName']) || strlen($mapping['fieldName']) == 0) {
throw MappingException::missingFieldName($this->name);
}
if ( ! isset($mapping['targetEntity'])) {
throw MappingException::missingTargetEntity($mapping['fieldName']);
@@ -836,8 +836,17 @@ class ClassMetadataInfo
{
$mapping = $this->_validateAndCompleteAssociationMapping($mapping);
if ($mapping['isOwningSide']) {
$sourceShortName = strtolower(substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1));
$targetShortName = strtolower(substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1));
if (strpos($mapping['sourceEntity'], '\\') !== false) {
$sourceShortName = strtolower(substr($mapping['sourceEntity'], strrpos($mapping['sourceEntity'], '\\') + 1));
} else {
$sourceShortName = strtolower($mapping['sourceEntity']);
}
if (strpos($mapping['targetEntity'], '\\') !== false) {
$targetShortName = strtolower(substr($mapping['targetEntity'], strrpos($mapping['targetEntity'], '\\') + 1));
} else {
$targetShortName = strtolower($mapping['targetEntity']);
}
// owning side MUST have a join table
if ( ! isset($mapping['joinTable']['name'])) {
$mapping['joinTable']['name'] = $sourceShortName .'_' . $targetShortName;

View File

@@ -22,6 +22,7 @@ namespace Doctrine\ORM\Mapping\Driver;
use Doctrine\Common\Cache\ArrayCache,
Doctrine\Common\Annotations\AnnotationReader,
Doctrine\DBAL\Schema\AbstractSchemaManager,
Doctrine\DBAL\Schema\SchemaException,
Doctrine\ORM\Mapping\ClassMetadataInfo,
Doctrine\ORM\Mapping\MappingException,
Doctrine\Common\Util\Inflector;
@@ -128,6 +129,11 @@ class DatabaseDriver implements Driver
$columns = $this->tables[$tableName]->getColumns();
$indexes = $this->tables[$tableName]->getIndexes();
try {
$primaryKeyColumns = $this->tables[$tableName]->getPrimaryKey()->getColumns();
} catch(SchemaException $e) {
$primaryKeyColumns = array();
}
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$foreignKeys = $this->tables[$tableName]->getForeignKeys();
@@ -144,7 +150,7 @@ class DatabaseDriver implements Driver
$fieldMappings = array();
foreach ($columns as $column) {
$fieldMapping = array();
if (isset($indexes['primary']) && in_array($column->getName(), $indexes['primary']->getColumns())) {
if ($primaryKeyColumns && in_array($column->getName(), $primaryKeyColumns)) {
$fieldMapping['id'] = true;
} else if (in_array($column->getName(), $allForeignKeyColumns)) {
continue;

View File

@@ -48,9 +48,9 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("Id generators can't be used with a composite id.");
}
public static function missingFieldName()
public static function missingFieldName($entity)
{
return new self("The association mapping misses the 'fieldName' attribute.");
return new self("The field or association mapping misses the 'fieldName' attribute in entity '$entity'.");
}
public static function missingTargetEntity($fieldName)
@@ -68,9 +68,9 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("No mapping file found named '$fileName' for class '$entityName'.");
}
public static function mappingNotFound($fieldName)
public static function mappingNotFound($className, $fieldName)
{
return new self("No mapping found for field '$fieldName'.");
return new self("No mapping found for field '$fieldName' on class '$className'.");
}
public static function oneToManyRequiresMappedBy($fieldName)
@@ -227,4 +227,8 @@ class MappingException extends \Doctrine\ORM\ORMException
return new self("Duplicate definition of column '".$columnName."' on entity '".$className."' in a field or discriminator column mapping.");
}
public static function illegalToManyAssocationOnMappedSuperclass($className, $field)
{
return new self("It is illegal to put an inverse side one-to-many or many-to-many association on mapped superclass '".$className."#".$field."'.");
}
}

View File

@@ -33,11 +33,18 @@ use Doctrine\ORM\Mapping\ClassMetadata,
abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
{
/**
* Map from column names to class names that declare the field the column is mapped to.
* Map from column names to class metadata instances that declare the field the column is mapped to.
*
* @var array
*/
private $_declaringClassMap = array();
private $declaringClassMap = array();
/**
* Map from column names to class names that declare the field the association with join column is mapped to.
*
* @var array
*/
private $declaringJoinColumnMap = array();
/**
* {@inheritdoc}
@@ -70,8 +77,8 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
unset($sqlResult[$discrColumnName]);
foreach ($sqlResult as $column => $value) {
$realColumnName = $this->_resultColumnNames[$column];
if (isset($this->_declaringClassMap[$column])) {
$class = $this->_declaringClassMap[$column];
if (isset($this->declaringClassMap[$column])) {
$class = $this->declaringClassMap[$column];
if ($class->name == $entityName || is_subclass_of($entityName, $class->name)) {
$field = $class->fieldNames[$realColumnName];
if (isset($data[$field])) {
@@ -81,6 +88,10 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
->convertToPHPValue($value, $this->_platform);
}
}
} else if (isset($this->declaringJoinColumnMap[$column])) {
if ($this->declaringJoinColumnMap[$column] == $entityName || is_subclass_of($entityName, $this->declaringJoinColumnMap[$column])) {
$data[$realColumnName] = $value;
}
} else {
$data[$realColumnName] = $value;
}
@@ -99,9 +110,21 @@ abstract class AbstractEntityInheritancePersister extends BasicEntityPersister
$columnAlias = $this->_platform->getSQLResultCasing($columnName . $this->_sqlAliasCounter++);
if ( ! isset($this->_resultColumnNames[$columnAlias])) {
$this->_resultColumnNames[$columnAlias] = $columnName;
$this->_declaringClassMap[$columnAlias] = $class;
$this->declaringClassMap[$columnAlias] = $class;
}
return "$sql AS $columnAlias";
}
protected function getSelectJoinColumnSQL($tableAlias, $joinColumnName, $className)
{
$columnAlias = $joinColumnName . $this->_sqlAliasCounter++;
$resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
$this->_resultColumnNames[$resultColumnName] = $joinColumnName;
$this->declaringJoinColumnMap[$resultColumnName] = $className;
}
return $tableAlias . ".$joinColumnName AS $columnAlias";
}
}

View File

@@ -28,7 +28,9 @@ use PDO,
Doctrine\ORM\Query,
Doctrine\ORM\PersistentCollection,
Doctrine\ORM\Mapping\MappingException,
Doctrine\ORM\Mapping\ClassMetadata;
Doctrine\ORM\Mapping\ClassMetadata,
Doctrine\ORM\Events,
Doctrine\ORM\Event\LifecycleEventArgs;
/**
* A BasicEntityPersiter maps an entity to a single table in a relational database.
@@ -223,7 +225,7 @@ class BasicEntityPersister
}
if ($this->_class->isVersioned) {
$this->_assignDefaultVersionValue($this->_class, $entity, $id);
$this->assignDefaultVersionValue($entity, $id);
}
}
@@ -238,22 +240,33 @@ class BasicEntityPersister
* by the preceding INSERT statement and assigns it back in to the
* entities version field.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $class
* @param object $entity
* @param mixed $id
*/
protected function _assignDefaultVersionValue($class, $entity, $id)
protected function assignDefaultVersionValue($entity, $id)
{
$versionField = $this->_class->versionField;
$identifier = $this->_class->getIdentifierColumnNames();
$versionFieldColumnName = $this->_class->getColumnName($versionField);
$value = $this->fetchVersionValue($this->_class, $id);
$this->_class->setFieldValue($entity, $this->_class->versionField, $value);
}
/**
* Fetch the current version value of a versioned entity.
*
* @param Doctrine\ORM\Mapping\ClassMetadata $versionedClass
* @param mixed $id
* @return mixed
*/
protected function fetchVersionValue($versionedClass, $id)
{
$versionField = $versionedClass->versionField;
$identifier = $versionedClass->getIdentifierColumnNames();
$versionFieldColumnName = $versionedClass->getColumnName($versionField);
//FIXME: Order with composite keys might not be correct
$sql = "SELECT " . $versionFieldColumnName . " FROM " . $class->getQuotedTableName($this->_platform)
$sql = "SELECT " . $versionFieldColumnName . " FROM " . $versionedClass->getQuotedTableName($this->_platform)
. " WHERE " . implode(' = ? AND ', $identifier) . " = ?";
$value = $this->_conn->fetchColumn($sql, array_values((array)$id));
$value = Type::getType($class->fieldMappings[$versionField]['type'])->convertToPHPValue($value, $this->_platform);
$this->_class->setFieldValue($entity, $versionField, $value);
return Type::getType($versionedClass->fieldMappings[$versionField]['type'])->convertToPHPValue($value, $this->_platform);
}
/**
@@ -282,7 +295,7 @@ class BasicEntityPersister
if ($this->_class->isVersioned) {
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
$this->_assignDefaultVersionValue($this->_class, $entity, $id);
$this->assignDefaultVersionValue($entity, $id);
}
}
}
@@ -525,7 +538,8 @@ class BasicEntityPersister
public function load(array $criteria, $entity = null, $assoc = null, array $hints = array(), $lockMode = 0)
{
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc, $lockMode);
$stmt = $this->_conn->executeQuery($sql, array_values($criteria));
list($params, $types) = $this->expandParameters($criteria);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
@@ -608,7 +622,8 @@ class BasicEntityPersister
public function refresh(array $id, $entity)
{
$sql = $this->_getSelectEntitiesSQL($id);
$stmt = $this->_conn->executeQuery($sql, array_values($id));
list($params, $types) = $this->expandParameters($id);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
$result = $stmt->fetch(PDO::FETCH_ASSOC);
$stmt->closeCursor();
@@ -682,6 +697,14 @@ class BasicEntityPersister
}
$this->_em->getUnitOfWork()->setOriginalEntityData($entity, $newData);
if (isset($this->_class->lifecycleCallbacks[Events::postLoad])) {
$this->_class->invokeLifecycleCallbacks(Events::postLoad, $entity);
}
$evm = $this->_em->getEventManager();
if ($evm->hasListeners(Events::postLoad)) {
$evm->dispatchEvent(Events::postLoad, new LifecycleEventArgs($entity, $this->_em));
}
}
/**
@@ -694,7 +717,8 @@ class BasicEntityPersister
{
$entities = array();
$sql = $this->_getSelectEntitiesSQL($criteria);
$stmt = $this->_conn->executeQuery($sql, array_values($criteria));
list($params, $types) = $this->expandParameters($criteria);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
@@ -742,7 +766,8 @@ class BasicEntityPersister
}
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc);
$stmt = $this->_conn->executeQuery($sql, array_values($criteria));
list($params, $types) = $this->expandParameters($criteria);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
$coll->hydrateAdd($this->_createEntity($result));
}
@@ -1084,8 +1109,8 @@ class BasicEntityPersister
$sql = 'SELECT 1 '
. $this->_platform->appendLockHint($this->getLockTablesSql(), $lockMode)
. ($conditionSql ? ' WHERE ' . $conditionSql : '') . ' ' . $lockSql;
$params = array_values($criteria);
$this->_conn->executeQuery($sql, $params);
list($params, $types) = $this->expandParameters($criteria);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
}
/**
@@ -1169,14 +1194,35 @@ class BasicEntityPersister
}
$sql = $this->_getSelectEntitiesSQL($criteria, $assoc);
$params = array_values($criteria);
$stmt = $this->_conn->executeQuery($sql, $params);
list($params, $types) = $this->expandParameters($criteria);
$stmt = $this->_conn->executeQuery($sql, $params, $types);
while ($result = $stmt->fetch(PDO::FETCH_ASSOC)) {
$coll->hydrateAdd($this->_createEntity($result));
}
$stmt->closeCursor();
}
/**
* Expand the parameters from the given criteria and use the correct binding types if found.
*
* @param array $criteria
* @return array
*/
private function expandParameters($criteria)
{
$params = $types = array();
foreach ($criteria AS $field => $value) {
$type = null;
if (isset($this->_class->fieldMappings[$field])) {
$type = Type::getType($this->_class->fieldMappings[$field]['type'])->getBindingType();
}
$params[] = $value;
$types[] = $type;
}
return array($params, $types);
}
/**
* Checks whether the given managed entity exists in the database.
*

View File

@@ -107,10 +107,6 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
return;
}
if ($this->_class->isVersioned) {
$versionedClass = $this->_getVersionedClassMetadata();
}
$postInsertIds = array();
$idGen = $this->_class->idGenerator;
$isPostInsertId = $idGen->isPostInsertGenerator();
@@ -176,8 +172,8 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
$stmt->closeCursor();
}
if (isset($versionedClass)) {
$this->_assignDefaultVersionValue($versionedClass, $entity, $id);
if ($this->_class->isVersioned) {
$this->assignDefaultVersionValue($entity, $id);
}
$this->_queuedInserts = array();
@@ -207,7 +203,7 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
$this->_updateTable($entity, $versionedClass->getQuotedTableName($this->_platform), array(), true);
$id = $this->_em->getUnitOfWork()->getEntityIdentifier($entity);
$this->_assignDefaultVersionValue($this->_class, $entity, $id);
$this->assignDefaultVersionValue($entity, $id);
}
}
}
@@ -263,12 +259,10 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
$this->_getSQLTableAlias($assoc2['inherited'])
: $baseTableAlias;
foreach ($assoc2['targetToSourceKeyColumns'] as $srcColumn) {
$columnAlias = $srcColumn . $this->_sqlAliasCounter++;
$columnList .= ", $tableAlias.$srcColumn AS $columnAlias";
$resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
$this->_resultColumnNames[$resultColumnName] = $srcColumn;
}
if ($columnList != '') $columnList .= ', ';
$columnList .= $this->getSelectJoinColumnSQL($tableAlias, $srcColumn,
isset($assoc2['inherited']) ? $assoc2['inherited'] : $this->_class->name
);
}
}
}
@@ -318,12 +312,10 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
if ($assoc2['isOwningSide'] && $assoc2['type'] & ClassMetadata::TO_ONE
&& ! isset($assoc2['inherited'])) {
foreach ($assoc2['targetToSourceKeyColumns'] as $srcColumn) {
$columnAlias = $srcColumn . $this->_sqlAliasCounter++;
$columnList .= ', ' . $tableAlias . ".$srcColumn AS $columnAlias";
$resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
$this->_resultColumnNames[$resultColumnName] = $srcColumn;
}
if ($columnList != '') $columnList .= ', ';
$columnList .= $this->getSelectJoinColumnSQL($tableAlias, $srcColumn,
isset($assoc2['inherited']) ? $assoc2['inherited'] : $subClass->name
);
}
}
}
@@ -423,4 +415,13 @@ class JoinedSubclassPersister extends AbstractEntityInheritancePersister
return $columns;
}
/**
* {@inheritdoc}
*/
protected function assignDefaultVersionValue($entity, $id)
{
$value = $this->fetchVersionValue($this->_getVersionedClassMetadata(), $id);
$this->_class->setFieldValue($entity, $this->_class->versionField, $value);
}
}

View File

@@ -63,12 +63,10 @@ class SingleTablePersister extends AbstractEntityInheritancePersister
foreach ($subClass->associationMappings as $assoc) {
if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE && ! isset($assoc['inherited'])) {
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
$columnAlias = $srcColumn . $this->_sqlAliasCounter++;
$columnList .= ', ' . $tableAlias . ".$srcColumn AS $columnAlias";
$resultColumnName = $this->_platform->getSQLResultCasing($columnAlias);
if ( ! isset($this->_resultColumnNames[$resultColumnName])) {
$this->_resultColumnNames[$resultColumnName] = $srcColumn;
}
if ($columnList != '') $columnList .= ', ';
$columnList .= $this->getSelectJoinColumnSQL($tableAlias, $srcColumn,
isset($assoc['inherited']) ? $assoc['inherited'] : $this->_class->name
);
}
}
}

View File

@@ -277,20 +277,8 @@ class Parser
{
$AST = $this->getAST();
// Fix order of identification variables.
// They have to appear in the select clause in the same order as the
// declarations (from ... x join ... y join ... z ...) appear in the query
// as the hydration process relies on that order for proper operation.
if ( count($this->_identVariableExpressions) > 1) {
foreach ($this->_queryComponents as $dqlAlias => $qComp) {
if (isset($this->_identVariableExpressions[$dqlAlias])) {
$expr = $this->_identVariableExpressions[$dqlAlias];
$key = array_search($expr, $AST->selectClause->selectExpressions);
unset($AST->selectClause->selectExpressions[$key]);
$AST->selectClause->selectExpressions[] = $expr;
}
}
}
$this->fixIdentificationVariableOrder($AST);
$this->assertSelectEntityRootAliasRequirement();
if (($customWalkers = $this->_query->getHint(Query::HINT_CUSTOM_TREE_WALKERS)) !== false) {
$this->_customTreeWalkers = $customWalkers;
@@ -332,6 +320,46 @@ class Parser
return $this->_parserResult;
}
private function assertSelectEntityRootAliasRequirement()
{
if ( count($this->_identVariableExpressions) > 0) {
$foundRootEntity = false;
foreach ($this->_identVariableExpressions AS $dqlAlias => $expr) {
if (isset($this->_queryComponents[$dqlAlias]) && $this->_queryComponents[$dqlAlias]['parent'] === null) {
$foundRootEntity = true;
}
}
if (!$foundRootEntity) {
$this->semanticalError('Cannot select entity through identification variables without choosing at least one root entity alias.');
}
}
}
/**
* Fix order of identification variables.
*
* They have to appear in the select clause in the same order as the
* declarations (from ... x join ... y join ... z ...) appear in the query
* as the hydration process relies on that order for proper operation.
*
* @param AST\SelectStatement|AST\DeleteStatement|AST\UpdateStatement $AST
* @return void
*/
private function fixIdentificationVariableOrder($AST)
{
if ( count($this->_identVariableExpressions) > 1) {
foreach ($this->_queryComponents as $dqlAlias => $qComp) {
if (isset($this->_identVariableExpressions[$dqlAlias])) {
$expr = $this->_identVariableExpressions[$dqlAlias];
$key = array_search($expr, $AST->selectClause->selectExpressions);
unset($AST->selectClause->selectExpressions[$key]);
$AST->selectClause->selectExpressions[] = $expr;
}
}
}
}
/**
* Generates a new syntax error.

View File

@@ -209,9 +209,13 @@ class SqlWalker implements TreeWalker
*
* @param string $tableName
* @param string $alias
* @param string $dqlAlias
* @return string
*/
public function setSqlTableAlias($tableName, $alias)
public function setSqlTableAlias($tableName, $alias, $dqlAlias = '')
{
$tableName .= $dqlAlias;
$this->_tableAliasMap[$tableName] = $alias;
return $alias;
@@ -1213,9 +1217,7 @@ class SqlWalker implements TreeWalker
$class = $this->_em->getClassMetadata($deleteClause->abstractSchemaName);
$sql .= $class->getQuotedTableName($this->_platform);
if ($this->_useSqlTableAliases) {
$sql .= ' ' . $this->getSqlTableAlias($class->getTableName());
}
$this->setSqlTableAlias($class->getTableName(), $class->getTableName(), $deleteClause->aliasIdentificationVariable);
$this->_rootAliases[] = $deleteClause->aliasIdentificationVariable;
@@ -1234,9 +1236,7 @@ class SqlWalker implements TreeWalker
$class = $this->_em->getClassMetadata($updateClause->abstractSchemaName);
$sql .= $class->getQuotedTableName($this->_platform);
if ($this->_useSqlTableAliases) {
$sql .= ' ' . $this->getSqlTableAlias($class->getTableName());
}
$this->setSqlTableAlias($class->getTableName(), $class->getTableName(), $updateClause->aliasIdentificationVariable);
$this->_rootAliases[] = $updateClause->aliasIdentificationVariable;

View File

@@ -63,6 +63,10 @@ class ConvertMappingCommand extends Console\Command\Command
'dest-path', InputArgument::REQUIRED,
'The path to generate your entities classes.'
),
new InputOption(
'force', null, InputOption::VALUE_NONE,
'Force to overwrite existing mapping files.'
),
new InputOption(
'from-database', null, null, 'Whether or not to convert mapping information from existing database.'
),
@@ -73,10 +77,24 @@ class ConvertMappingCommand extends Console\Command\Command
new InputOption(
'num-spaces', null, InputOption::VALUE_OPTIONAL,
'Defines the number of indentation spaces', 4
)
),
))
->setHelp(<<<EOT
Convert mapping information between supported formats.
This is an execute <info>one-time</info> command. It should not be necessary for
you to call this method multiple times, escpecially when using the <comment>--from-database</comment>
flag.
Converting an existing databsae schema into mapping files only solves about 70-80%
of the necessary mapping information. Additionally the detection from an existing
database cannot detect inverse associations, inheritance types,
entities with foreign keys as primary keys and many of the
semantical operations on associations such as cascade.
<comment>Hint:</comment> There is no need to convert YAML or XML mapping files to annotations
every time you make changes. All mapping drivers are first class citizens
in Doctrine 2 and can be used as runtime mapping for the ORM.
EOT
);
}
@@ -121,6 +139,7 @@ EOT
$cme = new ClassMetadataExporter();
$exporter = $cme->getExporter($toType, $destPath);
$exporter->setOverwriteExistingFiles( ($input->getOption('force') !== false) );
if ($toType == 'annotation') {
$entityGenerator = new EntityGenerator();

View File

@@ -85,6 +85,23 @@ class GenerateEntitiesCommand extends Console\Command\Command
))
->setHelp(<<<EOT
Generate entity classes and method stubs from your mapping information.
If you use the <comment>--update-entities</comment> or <comment>--regenerate-entities</comment> flags your exisiting
code gets overwritten. The EntityGenerator will only append new code to your
file and will not delete the old code. However this approach may still be prone
to error and we suggest you use code repositories such as GIT or SVN to make
backups of your code.
It makes sense to generate the entity code if you are using entities as Data
Access Objects only and dont put much additional logic on them. If you are
however putting much more logic on the entities you should refrain from using
the entity-generator and code your entities manually.
<error>Important:</error> Even if you specified Inheritance options in your
XML or YAML Mapping files the generator cannot generate the base and
child classes for you correctly, because it doesn't know which
class is supposed to extend which. You have to adjust the entity
code manually for inheritance to work!
EOT
);
}

View File

@@ -188,7 +188,6 @@ class ConvertDoctrine1Schema
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_AUTO);
} else if (isset($column['sequence'])) {
$metadata->setIdGeneratorType(ClassMetadataInfo::GENERATOR_TYPE_SEQUENCE);
$metadata->setSequenceGeneratorDefinition($definition);
$definition = array(
'sequenceName' => is_array($column['sequence']) ? $column['sequence']['name']:$column['sequence']
);
@@ -198,6 +197,7 @@ class ConvertDoctrine1Schema
if (isset($column['sequence']['value'])) {
$definition['initialValue'] = $column['sequence']['value'];
}
$metadata->setSequenceGeneratorDefinition($definition);
}
return $fieldMapping;
}

View File

@@ -23,6 +23,7 @@
namespace Doctrine\ORM\Tools\Export\Driver;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Tools\Export\ExportException;
/**
* Abstract base class which is to be used for the Exporter drivers
@@ -39,12 +40,18 @@ abstract class AbstractExporter
protected $_metadata = array();
protected $_outputDir;
protected $_extension;
protected $_overwriteExistingFiles = false;
public function __construct($dir = null)
{
$this->_outputDir = $dir;
}
public function setOverwriteExistingFiles($overwrite)
{
$this->_overwriteExistingFiles = $overwrite;
}
/**
* Converts a single ClassMetadata instance to the exported format
* and returns it
@@ -110,6 +117,9 @@ abstract class AbstractExporter
if ( ! is_dir($dir)) {
mkdir($dir, 0777, true);
}
if (file_exists($path) && !$this->_overwriteExistingFiles) {
throw ExportException::attemptOverwriteExistingFile($path);
}
file_put_contents($path, $output);
}
}

View File

@@ -15,4 +15,9 @@ class ExportException extends ORMException
{
return new self("The mapping driver '$type' does not exist");
}
public static function attemptOverwriteExistingFile($file)
{
return new self("Attempting to overwrite an existing file '".$file."'.");
}
}

View File

@@ -179,7 +179,7 @@ class SchemaTool
$this->_gatherColumn($class, $idMapping, $table);
$columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform);
// TODO: This seems rather hackish, can we optimize it?
$table->getColumn($class->identifier[0])->setAutoincrement(false);
$table->getColumn($columnName)->setAutoincrement(false);
$pkColumns[] = $columnName;
@@ -275,6 +275,10 @@ class SchemaTool
$pkColumns = array();
foreach ($class->fieldMappings as $fieldName => $mapping) {
if ($class->isInheritanceTypeSingleTable() && isset($mapping['inherited'])) {
continue;
}
$column = $this->_gatherColumn($class, $mapping, $table);
if ($class->isIdentifier($mapping['fieldName'])) {
@@ -453,7 +457,7 @@ class SchemaTool
if (isset($joinColumn['nullable'])) {
$columnOptions['notnull'] = !$joinColumn['nullable'];
}
if ($fieldMapping['type'] == "string") {
if ($fieldMapping['type'] == "string" && isset($fieldMapping['length'])) {
$columnOptions['length'] = $fieldMapping['length'];
} else if ($fieldMapping['type'] == "decimal") {
$columnOptions['scale'] = $fieldMapping['scale'];
@@ -498,7 +502,11 @@ class SchemaTool
$conn = $this->_em->getConnection();
foreach ($dropSchemaSql as $sql) {
$conn->executeQuery($sql);
try {
$conn->executeQuery($sql);
} catch(\Exception $e) {
}
}
}

View File

@@ -462,6 +462,7 @@ class UnitOfWork implements PropertyChangedListener
// A PersistentCollection was de-referenced, so delete it.
if ( ! in_array($orgValue, $this->collectionDeletions, true)) {
$this->collectionDeletions[] = $orgValue;
$changeSet[$propName] = $orgValue; // Signal changeset, to-many assocs will be ignored.
}
}
} else if ($isChangeTrackingNotify) {

View File

@@ -36,7 +36,7 @@ class Version
/**
* Current Doctrine Version
*/
const VERSION = '2.0.0-DEV';
const VERSION = '2.0.1-DEV';
/**
* Compares a Doctrine version with the current one.

View File

@@ -82,6 +82,27 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue($reference->postLoadCallbackInvoked);
}
/**
* @group DDC-958
*/
public function testPostLoadTriggeredOnRefresh()
{
$entity = new LifecycleCallbackTestEntity;
$entity->value = 'hello';
$this->_em->persist($entity);
$this->_em->flush();
$id = $entity->getId();
$this->_em->clear();
$reference = $this->_em->find('Doctrine\Tests\ORM\Functional\LifecycleCallbackTestEntity', $id);
$this->assertTrue($reference->postLoadCallbackInvoked);
$reference->postLoadCallbackInvoked = false;
$this->_em->refresh($reference);
$this->assertTrue($reference->postLoadCallbackInvoked, "postLoad should be invoked when refresh() is called.");
}
/**
* @group DDC-113
*/

View File

@@ -3,7 +3,8 @@
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\CMS\CmsUser,
Doctrine\Tests\Models\CMS\CmsGroup;
Doctrine\Tests\Models\CMS\CmsGroup,
Doctrine\Common\Collections\ArrayCollection;
require_once __DIR__ . '/../../TestInit.php';
@@ -299,4 +300,46 @@ class ManyToManyBasicAssociationTest extends \Doctrine\Tests\OrmFunctionalTestCa
return $user;
}
/**
* @group DDC-980
*/
public function testUpdateDeleteSizeSubselectQueries()
{
$this->_em->createQuery("DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) = 10")->execute();
$this->_em->createQuery("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.status = 'inactive' WHERE SIZE(u.groups) = 10")->execute();
}
/**
* @group DDC-978
*/
public function testClearAndResetCollection()
{
$user = $this->addCmsUserGblancoWithGroups(2);
$group1 = new CmsGroup;
$group1->name = 'Developers_New1';
$group2 = new CmsGroup;
$group2->name = 'Developers_New2';
$this->_em->persist($group1);
$this->_em->persist($group2);
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->find(get_class($user), $user->id);
$coll = new ArrayCollection(array($group1, $group2));
$user->groups = $coll;
$this->_em->flush();
$this->assertInstanceOf('Doctrine\ORM\PersistentCollection', $user->groups,
"UnitOfWork should have replaced ArrayCollection with PersistentCollection.");
$this->_em->flush();
$this->_em->clear();
$user = $this->_em->find(get_class($user), $user->id);
$this->assertEquals(2, count($user->groups));
$this->assertEquals('Developers_New1', $user->groups[0]->name);
$this->assertEquals('Developers_New2', $user->groups[1]->name);
}
}

View File

@@ -19,6 +19,7 @@ class AllTests
{
$suite = new \Doctrine\Tests\DoctrineTestSuite('Doctrine Orm Functional Tools');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\SchemaTool\CompanySchemaTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\SchemaTool\MySqlSchemaToolTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\SchemaTool\PostgreSqlSchemaToolTest');
$suite->addTestSuite('Doctrine\Tests\ORM\Functional\SchemaTool\DDC214Test');

View File

@@ -0,0 +1,53 @@
<?php
namespace Doctrine\Tests\ORM\Functional\SchemaTool;
use Doctrine\DBAL\Schema\Schema;
require_once __DIR__ . '/../../../TestInit.php';
/**
* Functional tests for the Class Table Inheritance mapping strategy.
*
* @author robo
*/
class CompanySchemaTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('company');
parent::setUp();
}
/**
* @group DDC-966
* @return Schema
*/
public function testGeneratedSchema()
{
$schema = $this->_em->getConnection()->getSchemaManager()->createSchema();
$this->assertTrue($schema->hasTable('company_contracts'));
return $schema;
}
/**
* @group DDC-966
* @depends testGeneratedSchema
*/
public function testSingleTableInheritance(Schema $schema)
{
$table = $schema->getTable('company_contracts');
// Check nullability constraints
$this->assertTrue($table->getColumn('id')->getNotnull());
$this->assertTrue($table->getColumn('completed')->getNotnull());
$this->assertFalse($table->getColumn('salesPerson_id')->getNotnull());
$this->assertTrue($table->getColumn('discr')->getNotnull());
$this->assertFalse($table->getColumn('fixPrice')->getNotnull());
$this->assertFalse($table->getColumn('hoursWorked')->getNotnull());
$this->assertFalse($table->getColumn('pricePerHour')->getNotnull());
$this->assertFalse($table->getColumn('maxPrice')->getNotnull());
}
}

View File

@@ -0,0 +1,198 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
class DDC837Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC837Super'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC837Class1'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC837Class2'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC837Class3'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC837Aggregate'),
));
}
/**
* @group DDC-837
*/
public function testIssue()
{
//$this->_em->getConnection()->getConfiguration()->setSQLLogger(new \Doctrine\DBAL\Logging\EchoSQLLogger);
$c1 = new DDC837Class1();
$c1->title = "Foo";
$c1->description = "Foo";
$aggregate1 = new DDC837Aggregate('test1');
$c1->aggregate = $aggregate1;
$c2 = new DDC837Class2();
$c2->title = "Bar";
$c2->description = "Bar";
$c2->text = "Bar";
$aggregate2 = new DDC837Aggregate('test2');
$c2->aggregate = $aggregate2;
$c3 = new DDC837Class3();
$c3->apples = "Baz";
$c3->bananas = "Baz";
$this->_em->persist($c1);
$this->_em->persist($aggregate1);
$this->_em->persist($c2);
$this->_em->persist($aggregate2);
$this->_em->persist($c3);
$this->_em->flush();
$this->_em->clear();
// Test Class1
$e1 = $this->_em->find('Doctrine\Tests\ORM\Functional\Ticket\DDC837Super', $c1->id);
$this->assertType('Doctrine\Tests\ORM\Functional\Ticket\DDC837Class1', $e1);
$this->assertEquals('Foo', $e1->title);
$this->assertEquals('Foo', $e1->description);
$this->assertType(__NAMESPACE__ . '\DDC837Aggregate', $e1->aggregate);
$this->assertEquals('test1', $e1->aggregate->getSysname());
// Test Class 2
$e2 = $this->_em->find('Doctrine\Tests\ORM\Functional\Ticket\DDC837Super', $c2->id);
$this->assertType('Doctrine\Tests\ORM\Functional\Ticket\DDC837Class2', $e2);
$this->assertEquals('Bar', $e2->title);
$this->assertEquals('Bar', $e2->description);
$this->assertEquals('Bar', $e2->text);
$this->assertType(__NAMESPACE__ . '\DDC837Aggregate', $e2->aggregate);
$this->assertEquals('test2', $e2->aggregate->getSysname());
$all = $this->_em->getRepository(__NAMESPACE__.'\DDC837Super')->findAll();
foreach ($all as $obj) {
if ($obj instanceof DDC837Class1) {
$this->assertEquals('Foo', $obj->title);
$this->assertEquals('Foo', $obj->description);
} else if ($obj instanceof DDC837Class2) {
$this->assertTrue($e2 === $obj);
$this->assertEquals('Bar', $obj->title);
$this->assertEquals('Bar', $obj->description);
$this->assertEquals('Bar', $obj->text);
} else if ($obj instanceof DDC837Class3) {
$this->assertEquals('Baz', $obj->apples);
$this->assertEquals('Baz', $obj->bananas);
} else {
$this->fail('Instance of DDC837Class1, DDC837Class2 or DDC837Class3 expected.');
}
}
}
}
/**
* @Entity
* @Table(name="DDC837Super")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="type", type="string")
* @DiscriminatorMap({"class1" = "DDC837Class1", "class2" = "DDC837Class2", "class3"="DDC837Class3"})
*/
abstract class DDC837Super
{
/**
* @Id @Column(name="id", type="integer")
* @GeneratedValue(strategy="AUTO")
*/
public $id;
}
/**
* @Entity
*/
class DDC837Class1 extends DDC837Super
{
/**
* @Column(name="title", type="string", length="150")
*/
public $title;
/**
* @Column(name="content", type="string", length="500")
*/
public $description;
/**
* @OneToOne(targetEntity="DDC837Aggregate")
*/
public $aggregate;
}
/**
* @Entity
*/
class DDC837Class2 extends DDC837Super
{
/**
* @Column(name="title", type="string", length="150")
*/
public $title;
/**
* @Column(name="content", type="string", length="500")
*/
public $description;
/**
* @Column(name="text", type="text")
*/
public $text;
/**
* @OneToOne(targetEntity="DDC837Aggregate")
*/
public $aggregate;
}
/**
* An extra class to demonstrate why title and description aren't in Super
*
* @Entity
*/
class DDC837Class3 extends DDC837Super
{
/**
* @Column(name="title", type="string", length="150")
*/
public $apples;
/**
* @Column(name="content", type="string", length="500")
*/
public $bananas;
}
/**
* @Entity
*/
class DDC837Aggregate
{
/**
* @Id @Column(name="id", type="integer")
* @GeneratedValue
*/
public $id;
/**
* @Column(name="sysname", type="string")
*/
protected $sysname;
public function __construct($sysname)
{
$this->sysname = $sysname;
}
public function getSysname()
{
return $this->sysname;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Tests\Models\Generic\BooleanModel;
require_once __DIR__ . '/../../../TestInit.php';
class DDC949Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('generic');
parent::setUp();
}
/**
* @group DDC-949
*/
public function testBooleanThroughRepository()
{
$true = new BooleanModel();
$true->booleanField = true;
$false = new BooleanModel();
$false->booleanField = false;
$this->_em->persist($true);
$this->_em->persist($false);
$this->_em->flush();
$this->_em->clear();
$true = $this->_em->getRepository('Doctrine\Tests\Models\Generic\BooleanModel')->findOneBy(array('booleanField' => true));
$false = $this->_em->getRepository('Doctrine\Tests\Models\Generic\BooleanModel')->findOneBy(array('booleanField' => false));
$this->assertType('Doctrine\Tests\Models\Generic\BooleanModel', $true);
$this->assertTrue($true->booleanField, "True Boolean Model should be true.");
$this->assertType('Doctrine\Tests\Models\Generic\BooleanModel', $false);
$this->assertFalse($false->booleanField, "False Boolean Model should be false.");
}
}

View File

@@ -0,0 +1,92 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
require_once __DIR__ . '/../../../TestInit.php';
class DDC960Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC960Root'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC960Child')
));
} catch(\Exception $e) {
}
}
/**
* @group DDC-960
*/
public function testUpdateRootVersion()
{
$child = new DDC960Child('Test');
$this->_em->persist($child);
$this->_em->flush();
$child->setName("Test2");
$this->_em->flush();
$this->assertEquals(2, $child->getVersion());
}
}
/**
* @Entity
* @InheritanceType("JOINED")
* @DiscriminatorMap({
* "root" = "DDC960Root",
* "child" = "DDC960Child"
* })
*/
class DDC960Root
{
/**
* @Id @GeneratedValue @Column(type="integer")
*/
private $id;
/**
* @Column(type="integer") @Version
*/
private $version;
public function getId()
{
return $this->id;
}
public function getVersion()
{
return $this->version;
}
}
/**
* @Entity
*/
class DDC960Child extends DDC960Root
{
/**
* @column(type="string")
* @var string
*/
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function setName($name)
{
$this->name = $name;
}
}

View File

@@ -125,14 +125,30 @@ class AnnotationDriverTest extends AbstractMappingDriverTest
$factory = new \Doctrine\ORM\Mapping\ClassMetadataFactory();
$factory->setEntityManager($em);
$classPage = new ClassMetadata('Doctrine\Tests\Models\DirectoryTree\File');
$classPage = $factory->getMetadataFor('Doctrine\Tests\Models\DirectoryTree\File');
$this->assertEquals('Doctrine\Tests\Models\DirectoryTree\File', $classPage->associationMappings['parentDirectory']['sourceEntity']);
$classDirectory = new ClassMetadata('Doctrine\Tests\Models\DirectoryTree\Directory');
$classDirectory = $factory->getMetadataFor('Doctrine\Tests\Models\DirectoryTree\Directory');
$this->assertEquals('Doctrine\Tests\Models\DirectoryTree\Directory', $classDirectory->associationMappings['parentDirectory']['sourceEntity']);
}
/**
* @group DDC-945
*/
public function testInvalidMappedSuperClassWithManyToManyAssociation()
{
$annotationDriver = $this->_loadDriver();
$em = $this->_getTestEntityManager();
$em->getConfiguration()->setMetadataDriverImpl($annotationDriver);
$factory = new \Doctrine\ORM\Mapping\ClassMetadataFactory();
$factory->setEntityManager($em);
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException',
"It is illegal to put an inverse side one-to-many or many-to-many association on ".
"mapped superclass 'Doctrine\Tests\ORM\Mapping\InvalidMappedSuperClass#users'");
$usingInvalidMsc = $factory->getMetadataFor('Doctrine\Tests\ORM\Mapping\UsingInvalidMappedSuperClass');
}
}
/**
@@ -143,3 +159,25 @@ class ColumnWithoutType
/** @Id @Column */
public $id;
}
/**
* @MappedSuperclass
*/
class InvalidMappedSuperClass
{
/**
* @ManyToMany(targetEntity="Doctrine\Tests\Models\CMS\CmsUser", mappedBy="invalid")
*/
private $users;
}
/**
* @Entity
*/
class UsingInvalidMappedSuperClass extends InvalidMappedSuperClass
{
/**
* @Id @Column(type="integer") @GeneratedValue
*/
private $id;
}

View File

@@ -6,6 +6,7 @@ use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Events;
require_once __DIR__ . '/../../TestInit.php';
require_once __DIR__ . '/../../Models/Global/GlobalNamespaceModel.php';
class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
{
@@ -289,4 +290,37 @@ class ClassMetadataTest extends \Doctrine\Tests\OrmTestCase
$cm->setIdentifier(array('name', 'username'));
$this->assertTrue($cm->isIdentifierComposite);
}
}
/**
* @group DDC-944
*/
public function testMappingNotFound()
{
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException', "No mapping found for field 'foo' on class 'Doctrine\Tests\Models\CMS\CmsUser'.");
$cm->getFieldMapping('foo');
}
/**
* @group DDC-961
*/
public function testJoinTableMappingDefaults()
{
$cm = new ClassMetadata('DoctrineGlobal_Article');
$cm->mapManyToMany(array('fieldName' => 'author', 'targetEntity' => 'Doctrine\Tests\Models\CMS\CmsUser'));
$this->assertEquals('doctrineglobal_article_cmsuser', $cm->associationMappings['author']['joinTable']['name']);
}
/**
* @group DDC-996
*/
public function testEmptyFieldNameThrowsException()
{
$this->setExpectedException('Doctrine\ORM\Mapping\MappingException',
"The field or association mapping misses the 'fieldName' attribute in entity 'Doctrine\Tests\Models\CMS\CmsUser'.");
$cm = new ClassMetadata('Doctrine\Tests\Models\CMS\CmsUser');
$cm->mapField(array('fieldName' => ''));
}
}

View File

@@ -273,4 +273,15 @@ class DeleteSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
'DELETE FROM cms_users WHERE id NOT IN (?, ?)'
);
}
/**
* @group DDC-980
*/
public function testSubselectTableAliasReferencing()
{
$this->assertSqlGeneration(
'DELETE Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) = 10',
'DELETE FROM cms_users WHERE (SELECT COUNT(*) FROM cms_users_groups c0_ WHERE c0_.user_id = cms_users.id) = 10'
);
}
}

View File

@@ -15,7 +15,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->_em = $this->_getTestEntityManager();
}
public function assertValidDql($dql, $debug = false)
public function assertValidDQL($dql, $debug = false)
{
try {
$parserResult = $this->parseDql($dql);
@@ -28,7 +28,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
}
}
public function assertInvalidDql($dql, $debug = false)
public function assertInvalidDQL($dql, $debug = false)
{
try {
$parserResult = $this->parseDql($dql);
@@ -62,311 +62,311 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
public function testEmptyQueryString()
{
$this->assertInvalidDql('');
$this->assertInvalidDQL('');
}
public function testPlainFromClauseWithAlias()
{
$this->assertValidDql('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testSelectSingleComponentWithAsterisk()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testSelectSingleComponentWithMultipleColumns()
{
$this->assertValidDql('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testSelectMultipleComponentsUsingMultipleFrom()
{
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user');
$this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user');
}
public function testSelectMultipleComponentsWithAsterisk()
{
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p');
$this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p');
}
public function testSelectDistinctIsSupported()
{
$this->assertValidDql('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testAggregateFunctionInSelect()
{
$this->assertValidDql('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testDuplicatedAliasInAggregateFunction()
{
$this->assertInvalidDql('SELECT COUNT(u.id) AS num, SUM(u.id) AS num FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertInvalidDQL('SELECT COUNT(u.id) AS num, SUM(u.id) AS num FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testAggregateFunctionWithDistinctInSelect()
{
$this->assertValidDql('SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testFunctionalExpressionsSupportedInWherePart()
{
$this->assertValidDql("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'");
$this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'");
}
public function testArithmeticExpressionsSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000');
}
public function testInExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)');
}
public function testInExpressionWithoutSpacesSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1,2,3)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1,2,3)');
}
public function testNotInExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (1)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (1)');
}
public function testInExpressionWithSingleValuedAssociationPathExpression()
{
$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)");
$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)");
}
public function testInvalidInExpressionWithCollectionValuedAssociationPathExpression()
{
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IN (?1, ?2)");
$this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IN (?1, ?2)");
}
public function testInstanceOfExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee');
}
public function testInstanceOfExpressionWithInputParamSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1');
}
public function testNotInstanceOfExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u NOT INSTANCE OF ?1');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u NOT INSTANCE OF ?1');
}
public function testExistsExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
}
public function testNotExistsExpressionSupportedInWherePart()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE NOT EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234)');
}
public function testAggregateFunctionInHavingClause()
{
$this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING COUNT(p.phonenumber) > 2');
$this->assertValidDql("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING MAX(u.name) = 'romanb'");
$this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING COUNT(p.phonenumber) > 2');
$this->assertValidDQL("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p HAVING MAX(u.name) = 'romanb'");
}
public function testLeftJoin()
{
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p');
$this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p');
}
public function testJoin()
{
$this->assertValidDql('SELECT u,p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p');
$this->assertValidDQL('SELECT u,p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p');
}
public function testInnerJoin()
{
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p');
$this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p');
}
public function testMultipleLeftJoin()
{
$this->assertValidDql('SELECT u, a, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a LEFT JOIN u.phonenumbers p');
$this->assertValidDQL('SELECT u, a, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a LEFT JOIN u.phonenumbers p');
}
public function testMultipleInnerJoin()
{
$this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a INNER JOIN u.phonenumbers p');
$this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a INNER JOIN u.phonenumbers p');
}
public function testMixingOfJoins()
{
$this->assertValidDql('SELECT u.name, a.topic, p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a LEFT JOIN u.phonenumbers p');
$this->assertValidDQL('SELECT u.name, a.topic, p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a LEFT JOIN u.phonenumbers p');
}
public function testOrderBySingleColumn()
{
$this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name');
$this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name');
}
public function testOrderBySingleColumnAscending()
{
$this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name ASC');
$this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name ASC');
}
public function testOrderBySingleColumnDescending()
{
$this->assertValidDql('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name DESC');
$this->assertValidDQL('SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.name DESC');
}
public function testOrderByMultipleColumns()
{
$this->assertValidDql('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username DESC, u.name DESC');
$this->assertValidDQL('SELECT u.name, u.username FROM Doctrine\Tests\Models\CMS\CmsUser u ORDER BY u.username DESC, u.name DESC');
}
public function testSubselectInInExpression()
{
$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = 'zYne')");
$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id NOT IN (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = 'zYne')");
}
public function testSubselectInSelectPart()
{
$this->assertValidDql("SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
$this->assertValidDQL("SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
}
public function testArithmeticExpressionInSelectPart()
{
$this->assertValidDql("SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u");
$this->assertValidDQL("SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u");
}
public function testArithmeticExpressionInSubselectPart()
{
$this->assertValidDql("SELECT (SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
$this->assertValidDQL("SELECT (SELECT SUM(u.id) / COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
}
public function testArithmeticExpressionWithParenthesisInSubselectPart()
{
$this->assertValidDql("SELECT (SELECT (SUM(u.id) / COUNT(u.id)) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
$this->assertValidDQL("SELECT (SELECT (SUM(u.id) / COUNT(u.id)) FROM Doctrine\Tests\Models\CMS\CmsUser u2) value FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
}
public function testDuplicateAliasInSubselectPart()
{
$this->assertInvalidDql("SELECT (SELECT SUM(u.id) / COUNT(u.id) AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u2) foo FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
$this->assertInvalidDQL("SELECT (SELECT SUM(u.id) / COUNT(u.id) AS foo FROM Doctrine\Tests\Models\CMS\CmsUser u2) foo FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'");
}
public function testPositionalInputParameter()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1');
}
public function testNamedInputParameter()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = :id');
}
public function testJoinConditionOverrideNotSupported()
{
$this->assertInvalidDql("SELECT u.name, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p ON p.phonenumber = '123 123'");
$this->assertInvalidDQL("SELECT u.name, p FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.phonenumbers p ON p.phonenumber = '123 123'");
}
public function testIndexByClauseWithOneComponent()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id');
}
public function testIndexBySupportsJoins()
{
$this->assertValidDql('SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a INDEX BY a.id'); // INDEX BY is now referring to articles
$this->assertValidDQL('SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a INDEX BY a.id'); // INDEX BY is now referring to articles
}
public function testIndexBySupportsJoins2()
{
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id LEFT JOIN u.phonenumbers p INDEX BY p.phonenumber');
$this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INDEX BY u.id LEFT JOIN u.phonenumbers p INDEX BY p.phonenumber');
}
public function testBetweenExpressionSupported()
{
$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name BETWEEN 'jepso' AND 'zYne'");
$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name BETWEEN 'jepso' AND 'zYne'");
}
public function testNotBetweenExpressionSupported()
{
$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT BETWEEN 'jepso' AND 'zYne'");
$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT BETWEEN 'jepso' AND 'zYne'");
}
public function testLikeExpression()
{
$this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z%'");
$this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z%'");
}
public function testNotLikeExpression()
{
$this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT LIKE 'z%'");
$this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name NOT LIKE 'z%'");
}
public function testLikeExpressionWithCustomEscapeCharacter()
{
$this->assertValidDql("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'");
$this->assertValidDQL("SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE 'z|%' ESCAPE '|'");
}
public function testFieldComparisonWithoutAlias()
{
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE id = 1");
$this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE id = 1");
}
public function testDuplicatedAliasDeclaration()
{
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles u WHERE u.id = 1");
$this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles u WHERE u.id = 1");
}
public function testImplicitJoinInWhereOnSingleValuedAssociationPathExpression()
{
// This should be allowed because avatar is a single-value association.
// SQL: SELECT ... FROM forum_user fu INNER JOIN forum_avatar fa ON fu.avatar_id = fa.id WHERE fa.id = ?
$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a WHERE a.id = ?1");
$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a WHERE a.id = ?1");
}
public function testImplicitJoinInWhereOnCollectionValuedPathExpression()
{
// This should be forbidden, because articles is a collection
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a WHERE a.title = ?");
$this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a WHERE a.title = ?");
}
public function testInvalidSyntaxIsRejected()
{
$this->assertInvalidDql("FOOBAR CmsUser");
$this->assertInvalidDql("DELETE FROM Doctrine\Tests\Models\CMS\CmsUser.articles");
$this->assertInvalidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles.comments");
$this->assertInvalidDQL("FOOBAR CmsUser");
$this->assertInvalidDQL("DELETE FROM Doctrine\Tests\Models\CMS\CmsUser.articles");
$this->assertInvalidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles.comments");
// Currently UNDEFINED OFFSET error
$this->assertInvalidDql("SELECT c FROM CmsUser.articles.comments c");
$this->assertInvalidDQL("SELECT c FROM CmsUser.articles.comments c");
}
public function testUpdateWorksWithOneField()
{
$this->assertValidDql("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone'");
$this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone'");
}
public function testUpdateWorksWithMultipleFields()
{
$this->assertValidDql("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone', u.username = 'some'");
$this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone', u.username = 'some'");
}
public function testUpdateSupportsConditions()
{
$this->assertValidDql("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone' WHERE u.id = 5");
$this->assertValidDQL("UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.name = 'someone' WHERE u.id = 5");
}
public function testDeleteAll()
{
$this->assertValidDql('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testDeleteWithCondition()
{
$this->assertValidDql('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = 3');
$this->assertValidDQL('DELETE FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = 3');
}
/**
@@ -375,94 +375,94 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
*/
public function testImplicitJoinWithCartesianProductAndConditionInWhere()
{
$this->assertValidDql("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.name = a.topic");
$this->assertValidDQL("SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.name = a.topic");
}
public function testAllExpressionWithCorrelatedSubquery()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ALL (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ALL (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
}
public function testCustomJoinsAndWithKeywordSupported()
{
$this->assertValidDql('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p WITH p.phonenumber = 123 WHERE u.id = 1');
$this->assertValidDQL('SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.phonenumbers p WITH p.phonenumber = 123 WHERE u.id = 1');
}
public function testAnyExpressionWithCorrelatedSubquery()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ANY (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > ANY (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
}
public function testSomeExpressionWithCorrelatedSubquery()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > SOME (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id > SOME (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = u.name)');
}
public function testArithmeticExpressionWithoutParenthesisInWhereClause()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) + 1 > 10');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) + 1 > 10');
}
public function testMemberOfExpression()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
//$this->assertValidDql("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE 'Joe' MEMBER OF u.nicknames");
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
//$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE 'Joe' MEMBER OF u.nicknames");
}
public function testSizeFunction()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1');
}
public function testEmptyCollectionComparisonExpression()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY');
}
public function testSingleValuedAssociationFieldInWhere()
{
$this->assertValidDql('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1');
$this->assertValidDql('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1');
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1');
$this->assertValidDQL('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1');
}
public function testBooleanLiteralInWhere()
{
$this->assertValidDql('SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true');
$this->assertValidDQL('SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true');
}
public function testSubqueryInSelectExpression()
{
$this->assertValidDql('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testUsageOfQComponentOutsideSubquery()
{
$this->assertInvalidDql('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u WHERE p.user = ?1');
$this->assertInvalidDQL('select u, (select max(p.phonenumber) from Doctrine\Tests\Models\CMS\CmsPhonenumber p) maxId from Doctrine\Tests\Models\CMS\CmsUser u WHERE p.user = ?1');
}
public function testUnknownAbstractSchemaName()
{
$this->assertInvalidDql('SELECT u FROM UnknownClassName u');
$this->assertInvalidDQL('SELECT u FROM UnknownClassName u');
}
public function testCorrectPartialObjectLoad()
{
$this->assertValidDql('SELECT PARTIAL u.{id,name} FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT PARTIAL u.{id,name} FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testIncorrectPartialObjectLoadBecauseOfMissingIdentifier()
{
$this->assertInvalidDql('SELECT PARTIAL u.{name} FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertInvalidDQL('SELECT PARTIAL u.{name} FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testScalarExpressionInSelect()
{
$this->assertValidDql('SELECT u, 42 + u.id AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT u, 42 + u.id AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
public function testInputParameterInSelect()
{
$this->assertValidDql('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
$this->assertValidDQL('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
/**
@@ -470,7 +470,7 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
*/
public function testDQLKeywordInJoinIsAllowed()
{
$this->assertValidDql('SELECT u FROM ' . __NAMESPACE__ . '\DQLKeywordsModelUser u JOIN u.group g');
$this->assertValidDQL('SELECT u FROM ' . __NAMESPACE__ . '\DQLKeywordsModelUser u JOIN u.group g');
}
/**
@@ -478,15 +478,23 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
*/
public function testDQLKeywordInConditionIsAllowed()
{
$this->assertValidDql('SELECT g FROM ' . __NAMESPACE__ . '\DQLKeywordsModelGroup g WHERE g.from=0');
$this->assertValidDQL('SELECT g FROM ' . __NAMESPACE__ . '\DQLKeywordsModelGroup g WHERE g.from=0');
}
/* The exception is currently thrown in the SQLWalker, not earlier.
public function testInverseSideSingleValuedAssociationPathNotAllowed()
{
$this->assertInvalidDql('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1');
$this->assertInvalidDQL('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address = ?1');
}
*/
/**
* @group DDC-617
*/
public function testSelectOnlyNonRootEntityAlias()
{
$this->assertInvalidDQL('SELECT g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g');
}
}
/** @Entity */

View File

@@ -6,43 +6,43 @@ use Doctrine\ORM\Query\ParserResult;
class ParserResultTest extends \PHPUnit_Framework_TestCase
{
public $result;
public $parserResult;
public function setUp()
{
$this->result = new ParserResult();
$this->parserResult = new ParserResult();
}
public function testGetRsm()
{
$this->assertType(
'Doctrine\ORM\Query\ResultSetMapping',
$this->result->getResultSetMapping()
$this->parserResult->getResultSetMapping()
);
}
public function testSetGetSqlExecutor()
{
$this->assertNull($this->result->getSqlExecutor());
$this->assertNull($this->parserResult->getSqlExecutor());
$executor = $this->getMock('Doctrine\ORM\Query\Exec\AbstractSqlExecutor', array('execute'));
$this->result->setSqlExecutor($executor);
$this->assertSame($executor, $this->result->getSqlExecutor());
$this->parserResult->setSqlExecutor($executor);
$this->assertSame($executor, $this->parserResult->getSqlExecutor());
}
public function testGetSqlParameterPosition()
{
$this->result->addParameterMapping(1, 1);
$this->result->addParameterMapping(1, 2);
$this->assertEquals(array(1, 2), $this->result->getSqlParameterPositions(1));
$this->parserResult->addParameterMapping(1, 1);
$this->parserResult->addParameterMapping(1, 2);
$this->assertEquals(array(1, 2), $this->parserResult->getSqlParameterPositions(1));
}
public function testGetParameterMappings()
{
$this->assertType('array', $this->result->getParameterMappings());
$this->assertType('array', $this->parserResult->getParameterMappings());
$this->result->addParameterMapping(1, 1);
$this->result->addParameterMapping(1, 2);
$this->assertEquals(array(1 => array(1, 2)), $this->result->getParameterMappings());
$this->parserResult->addParameterMapping(1, 1);
$this->parserResult->addParameterMapping(1, 2);
$this->assertEquals(array(1 => array(1, 2)), $this->parserResult->getParameterMappings());
}
}

View File

@@ -86,4 +86,17 @@ class QueryTest extends \Doctrine\Tests\OrmTestCase
$this->assertSame($q2, $q);
}
/**
* @group DDC-968
*/
public function testHints()
{
$q = $this->_em->createQuery("select a from Doctrine\Tests\Models\CMS\CmsArticle a");
$q->setHint('foo', 'bar')->setHint('bar', 'baz');
$this->assertEquals('bar', $q->getHint('foo'));
$this->assertEquals('baz', $q->getHint('bar'));
$this->assertEquals(array('foo' => 'bar', 'bar' => 'baz'), $q->getHints());
}
}

View File

@@ -325,7 +325,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
public function testSupportsMultipleJoins()
{
$this->assertSqlGeneration(
'SELECT u.id, a.id, p, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c',
'SELECT u.id, a.id, p.phonenumber, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c',
'SELECT c0_.id AS id0, c1_.id AS id1, c2_.phonenumber AS phonenumber2, c3_.id AS id3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id INNER JOIN cms_phonenumbers c2_ ON c0_.id = c2_.user_id INNER JOIN cms_comments c3_ ON c1_.id = c3_.article_id'
);
}

View File

@@ -175,4 +175,15 @@ class UpdateSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
"UPDATE cms_comments SET article_id = NULL WHERE article_id = ?"
);
}
/**
* @group DDC-980
*/
public function testSubselectTableAliasReferencing()
{
$this->assertSqlGeneration(
"UPDATE Doctrine\Tests\Models\CMS\CmsUser u SET u.status = 'inactive' WHERE SIZE(u.groups) = 10",
"UPDATE cms_users SET status = 'inactive' WHERE (SELECT COUNT(*) FROM cms_users_groups c0_ WHERE c0_.user_id = cms_users.id) = 10"
);
}
}

View File

@@ -69,6 +69,7 @@ class ConvertDoctrine1SchemaTest extends \Doctrine\Tests\OrmTestCase
$converter = new ConvertDoctrine1Schema(__DIR__ . '/doctrine1schema');
$exporter = $cme->getExporter('yml', __DIR__ . '/convert');
$exporter->setOverwriteExistingFiles(true);
$exporter->setMetadata($converter->getMetadata());
$exporter->export();
@@ -80,8 +81,8 @@ class ConvertDoctrine1SchemaTest extends \Doctrine\Tests\OrmTestCase
$cmf = new DisconnectedClassMetadataFactory();
$cmf->setEntityManager($em);
$metadata = $cmf->getAllMetadata();
$profileClass = $metadata[0];
$userClass = $metadata[1];
$profileClass = $cmf->getMetadataFor('Profile');
$userClass = $cmf->getMetadataFor('User');
$this->assertEquals(2, count($metadata));
$this->assertEquals('Profile', $profileClass->name);
@@ -96,9 +97,12 @@ class ConvertDoctrine1SchemaTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals('User', $profileClass->associationMappings['User']['targetEntity']);
$this->assertEquals('username', $userClass->table['uniqueConstraints']['username']['columns'][0]);
}
unlink(__DIR__ . '/convert/User.dcm.yml');
unlink(__DIR__ . '/convert/Profile.dcm.yml');
rmdir(__DIR__ . '/convert');
public function tearDown()
{
@unlink(__DIR__ . '/convert/User.dcm.yml');
@unlink(__DIR__ . '/convert/Profile.dcm.yml');
@rmdir(__DIR__ . '/convert');
}
}