mirror of
https://github.com/doctrine/orm.git
synced 2026-03-24 06:52:09 +01:00
Compare commits
45 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e61b73619 | ||
|
|
23ac0026a0 | ||
|
|
65e85aa471 | ||
|
|
d5b61ec897 | ||
|
|
adc2f24c9a | ||
|
|
8423c0c608 | ||
|
|
44aa098b37 | ||
|
|
839ec8f25a | ||
|
|
0893d2eb00 | ||
|
|
b63babc7b8 | ||
|
|
7350d85a4b | ||
|
|
a6b81d684a | ||
|
|
9e864c3662 | ||
|
|
024cc43189 | ||
|
|
1e79672147 | ||
|
|
3b7448bcf4 | ||
|
|
d5025235f3 | ||
|
|
dbc1a4da4b | ||
|
|
837d3f0f80 | ||
|
|
203fb59115 | ||
|
|
ecdc0fad64 | ||
|
|
e1fd2c158b | ||
|
|
479dae2a99 | ||
|
|
d94c2a11e8 | ||
|
|
d44b9fb05c | ||
|
|
fc16ecc6d7 | ||
|
|
1c9007fb0e | ||
|
|
79dc69b920 | ||
|
|
5e22a08ee1 | ||
|
|
3d43049426 | ||
|
|
95464c95fa | ||
|
|
392d23e401 | ||
|
|
19db4f304d | ||
|
|
aeaeff9002 | ||
|
|
9bc236b4fa | ||
|
|
cd6611ad3e | ||
|
|
41e5fc6b34 | ||
|
|
615a1159a7 | ||
|
|
1059991865 | ||
|
|
18fc94b395 | ||
|
|
b288eac530 | ||
|
|
699cd2cf4b | ||
|
|
c1f10b4673 | ||
|
|
6bff8c338f | ||
|
|
1ca924d021 |
@@ -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
|
||||
|
||||
12
build.xml
12
build.xml
@@ -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" />
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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."'.");
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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."'.");
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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.
|
||||
|
||||
2
lib/vendor/doctrine-common
vendored
2
lib/vendor/doctrine-common
vendored
Submodule lib/vendor/doctrine-common updated: 9eb66b7cf9...9d414673bb
2
lib/vendor/doctrine-dbal
vendored
2
lib/vendor/doctrine-dbal
vendored
Submodule lib/vendor/doctrine-dbal updated: e97fbbf755...ae084d9c69
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
198
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php
Normal file
198
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC837Test.php
Normal 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;
|
||||
}
|
||||
}
|
||||
43
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC949Test.php
Normal file
43
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC949Test.php
Normal 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.");
|
||||
}
|
||||
}
|
||||
92
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC960Test.php
Normal file
92
tests/Doctrine/Tests/ORM/Functional/Ticket/DDC960Test.php
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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' => ''));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user