Compare commits

...

32 Commits
2.1.1 ... 2.1.2

Author SHA1 Message Date
Benjamin Eberlei
144d0de0ab Release 2.1.2 2011-09-25 18:24:18 +00:00
Benjamin Eberlei
5c6164ce07 Bump Dev Version to 2.1.3-DEV 2011-09-25 18:23:05 +00:00
Benjamin Eberlei
e960ba24eb Release 2.1.2 2011-09-25 18:21:30 +00:00
Benjamin Eberlei
e55b700670 Update dependencies of Common and ORM 2011-09-25 20:20:17 +02:00
Benjamin Eberlei
e4dd5e83e4 Merge branch 'DDC-1381' into 2.1.x 2011-09-25 19:11:00 +02:00
Fabien Pennequin
082c2ded8d Fixed php notice in ClassMetadataFactory 2011-09-25 19:10:32 +02:00
Benjamin Eberlei
7f9cb9567a DDC-1337 - Fix MultiTableDeleteExecutor and MultiTableUpdateExecutor in MySQL transaction case 2011-09-25 19:08:16 +02:00
Benjamin Eberlei
90c50b013d Merge branch 'DDC-1392' into 2.1.x 2011-09-25 18:09:43 +02:00
Benjamin Eberlei
6a05e7f393 DDC-1392 - Fix bug with merging unitialized proxies 2011-09-25 18:09:13 +02:00
Benjamin Eberlei
a8e4d8f52d Merge branch 'DDC-1367' into 2.1.x 2011-09-25 16:41:12 +02:00
Benjamin Eberlei
47314c116c DDC-1367 - Bugfix 2011-09-25 16:40:14 +02:00
Benjamin Eberlei
c2eb6e6104 Merge branch 'DDC-1346' into 2.1.x 2011-09-25 15:11:58 +02:00
Guilherme Blanco
3b6a1e11f3 Added support for ResultVariable referencing in ArithmeticPrimary. Fixes DDC-1346. 2011-09-25 15:11:36 +02:00
Benjamin Eberlei
87650428b2 Merge branch 'DDC-1321' into 2.1.x 2011-09-25 15:07:12 +02:00
Guilherme Blanco
1de27437b5 Fixed bug with orphanRemoval not removing associated Entity on OneToMany and OneToOne relationships. As defined in ClassMatedataInfo, in these situations, when orphanRemoval=true, cascade=remove is implicit. This fixes DDC-1321. 2011-09-25 15:07:00 +02:00
Benjamin Eberlei
cf10ee4d02 Merge branch 'DDC-1356' into 2.1.x 2011-09-04 14:33:00 +02:00
Guilherme Blanco
1faa3a945e Added support to user provide an array of Entities as a DQL parameter. Fixes DDC-1356. 2011-09-04 14:32:45 +02:00
Benjamin Eberlei
22f37d4178 Merge branch 'DDC-1354' into 2.1.x 2011-09-04 14:30:38 +02:00
Guilherme Blanco
6ad21462fe Fixes DDC-1354. 2011-09-04 14:30:16 +02:00
Benjamin Eberlei
e9c29135f7 Merge branch 'DDC-1350' into 2.1.x 2011-08-30 20:41:10 +02:00
Benjamin Eberlei
12af7d24c0 DDC-1350 - Bugfixes in Doctrine\ORM\Tools\Setup 2011-08-30 20:41:02 +02:00
Benjamin Eberlei
4f3282d328 Bump DBAL dependency to 2.1.2 2011-08-29 23:00:27 +02:00
Benjamin Eberlei
60e7efa5b9 Merge branch 'DDC-1225' into 2.1.x 2011-08-29 21:55:51 +02:00
Guilherme Blanco
0a4c1028a1 Fixed issue with duplicated commas if Entity has no fields. 2011-08-29 21:54:41 +02:00
Benjamin Eberlei
2c3757d087 Merge branch 'DDC-1341' into 2.1.x 2011-08-28 21:50:04 +02:00
Benjamin Eberlei
bf892a8ece Namespace shortcut for repository was not merged into 2.1.x yet 2011-08-28 21:49:53 +02:00
Guilherme Blanco
878710d013 Fixed issue with CTI during DQL update that was incorrectly setting parameter types during multi table execution. Fixes DDC-1341. 2011-08-28 21:48:24 +02:00
Benjamin Eberlei
be800a991c Merge branch 'FixPostgresFailures' into 2.1.x 2011-08-28 15:57:44 +02:00
Benjamin Eberlei
e295168c19 DDC-1348 - Fix bug with UnitOfWork::getEntityState() 2011-08-28 15:57:33 +02:00
Benjamin Eberlei
c03d7dd086 Merge branch 'DDC-1306' into 2.1.x 2011-08-27 20:46:09 +02:00
Benjamin Eberlei
70938fa7f9 DDC-1306, DDC-1113 - Fix issues with inheritance and commit order 2011-08-27 20:44:47 +02:00
Benjamin Eberlei
83dbde9cda Bump Dev Version to 2.1.2-DEV 2011-08-26 06:11:43 +00:00
32 changed files with 788 additions and 104 deletions

View File

@@ -162,6 +162,16 @@ abstract class AbstractQuery
{
return $this->_params;
}
/**
* Get all defined parameter types.
*
* @return array The defined query parameter types.
*/
public function getParameterTypes()
{
return $this->_paramTypes;
}
/**
* Gets a query parameter.
@@ -174,6 +184,17 @@ abstract class AbstractQuery
return isset($this->_params[$key]) ? $this->_params[$key] : null;
}
/**
* Gets a query parameter type.
*
* @param mixed $key The key (index or name) of the bound parameter.
* @return mixed The parameter type of the bound parameter.
*/
public function getParameterType($key)
{
return isset($this->_paramTypes[$key]) ? $this->_paramTypes[$key] : null;
}
/**
* Gets the SQL query that corresponds to this query object.
* The returned SQL syntax depends on the connection driver that is used

View File

@@ -340,7 +340,7 @@ class ClassMetadataFactory implements ClassMetadataFactoryInterface
{
// Verify & complete identifier mapping
if ( ! $class->identifier && ! $class->isMappedSuperclass) {
throw MappingException::identifierRequired($className);
throw MappingException::identifierRequired($class->name);
}
// verify inheritance

View File

@@ -774,9 +774,13 @@ class ClassMetadataInfo implements ClassMetadata
// If targetEntity is unqualified, assume it is in the same namespace as
// the sourceEntity.
$mapping['sourceEntity'] = $this->name;
if (isset($mapping['targetEntity']) && strpos($mapping['targetEntity'], '\\') === false
&& strlen($this->namespace) > 0) {
$mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity'];
if (isset($mapping['targetEntity'])) {
if (strlen($this->namespace) > 0 && strpos($mapping['targetEntity'], '\\') === false) {
$mapping['targetEntity'] = $this->namespace . '\\' . $mapping['targetEntity'];
}
$mapping['targetEntity'] = ltrim($mapping['targetEntity'], '\\');
}
// Complete id mapping
@@ -908,9 +912,8 @@ class ClassMetadataInfo implements ClassMetadata
$mapping['targetToSourceKeyColumns'] = array_flip($mapping['sourceToTargetKeyColumns']);
}
//TODO: if orphanRemoval, cascade=remove is implicit!
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ?
(bool) $mapping['orphanRemoval'] : false;
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
if (isset($mapping['id']) && $mapping['id'] === true && !$mapping['isOwningSide']) {
throw MappingException::illegalInverseIdentifierAssocation($this->name, $mapping['fieldName']);
@@ -935,9 +938,8 @@ class ClassMetadataInfo implements ClassMetadata
throw MappingException::oneToManyRequiresMappedBy($mapping['fieldName']);
}
//TODO: if orphanRemoval, cascade=remove is implicit!
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ?
(bool) $mapping['orphanRemoval'] : false;
$mapping['orphanRemoval'] = isset($mapping['orphanRemoval']) ? (bool) $mapping['orphanRemoval'] : false;
$mapping['isCascadeRemove'] = $mapping['orphanRemoval'] ? true : $mapping['isCascadeRemove'];
if (isset($mapping['orderBy'])) {
if ( ! is_array($mapping['orderBy'])) {
@@ -1625,11 +1627,13 @@ class ClassMetadataInfo implements ClassMetadata
public function setDiscriminatorMap(array $map)
{
foreach ($map as $value => $className) {
if (strpos($className, '\\') === false && strlen($this->namespace)) {
if (strlen($this->namespace) > 0 && strpos($className, '\\') === false) {
$className = $this->namespace . '\\' . $className;
}
$className = ltrim($className, '\\');
$this->discriminatorMap[$value] = $className;
if ($this->name == $className) {
$this->discriminatorValue = $value;
} else {

View File

@@ -238,50 +238,84 @@ final class Query extends AbstractQuery
throw QueryException::invalidParameterNumber();
}
$sqlParams = $types = array();
foreach ($this->_params as $key => $value) {
if ( ! isset($paramMappings[$key])) {
throw QueryException::unknownParameter($key);
}
if (isset($this->_paramTypes[$key])) {
foreach ($paramMappings[$key] as $position) {
$types[$position] = $this->_paramTypes[$key];
}
}
if (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value))) {
if ($this->_em->getUnitOfWork()->getEntityState($value) == UnitOfWork::STATE_MANAGED) {
$idValues = $this->_em->getUnitOfWork()->getEntityIdentifier($value);
} else {
$class = $this->_em->getClassMetadata(get_class($value));
$idValues = $class->getIdentifierValues($value);
}
$sqlPositions = $paramMappings[$key];
$cSqlPos = count($sqlPositions);
$cIdValues = count($idValues);
$idValues = array_values($idValues);
for ($i = 0; $i < $cSqlPos; $i++) {
$sqlParams[$sqlPositions[$i]] = $idValues[ ($i % $cIdValues) ];
}
} else {
foreach ($paramMappings[$key] as $position) {
$sqlParams[$position] = $value;
}
}
}
if ($sqlParams) {
ksort($sqlParams);
$sqlParams = array_values($sqlParams);
}
list($sqlParams, $types) = $this->processParameterMappings($paramMappings);
if ($this->_resultSetMapping === null) {
$this->_resultSetMapping = $this->_parserResult->getResultSetMapping();
}
return $executor->execute($this->_em->getConnection(), $sqlParams, $types);
}
/**
* Processes query parameter mappings
*
* @param array $paramMappings
* @return array
*/
private function processParameterMappings($paramMappings)
{
$sqlParams = $types = array();
foreach ($this->_params as $key => $value) {
if ( ! isset($paramMappings[$key])) {
throw QueryException::unknownParameter($key);
}
if (isset($this->_paramTypes[$key])) {
foreach ($paramMappings[$key] as $position) {
$types[$position] = $this->_paramTypes[$key];
}
}
$sqlPositions = $paramMappings[$key];
$value = array_values($this->processParameterValue($value));
$countValue = count($value);
for ($i = 0, $l = count($sqlPositions); $i < $l; $i++) {
$sqlParams[$sqlPositions[$i]] = $value[($i % $countValue)];
}
}
if ($sqlParams) {
ksort($sqlParams);
$sqlParams = array_values($sqlParams);
}
return array($sqlParams, $types);
}
/**
* Process an individual parameter value
*
* @param mixed $value
* @return array
*/
private function processParameterValue($value)
{
if (is_array($value)) {
for ($i = 0, $l = count($value); $i < $l; $i++) {
$paramValue = $this->processParameterValue($value[$i]);
// TODO: What about Entities that have composite primary key?
$value[$i] = is_array($paramValue) ? $paramValue[key($paramValue)] : $paramValue;
}
return array($value);
}
if ( ! (is_object($value) && $this->_em->getMetadataFactory()->hasMetadataFor(get_class($value)))) {
return array($value);
}
if ($this->_em->getUnitOfWork()->getEntityState($value) === UnitOfWork::STATE_MANAGED) {
return array_values($this->_em->getUnitOfWork()->getEntityIdentifier($value));
}
$class = $this->_em->getClassMetadata(get_class($value));
return array_values($class->getIdentifierValues($value));
}
/**
* Defines a cache driver to be used for caching queries.

View File

@@ -98,7 +98,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor
}
$this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' ('
. $platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
$this->_dropTempTableSql = 'DROP TABLE ' . $tempTable;
$this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable);
}
/**

View File

@@ -106,7 +106,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
//FIXME (URGENT): With query cache the parameter is out of date. Move to execute() stage.
if ($newValue instanceof AST\InputParameter) {
$paramKey = $newValue->name;
$this->_sqlParameters[$i][] = $sqlWalker->getQuery()->getParameter($paramKey);
$this->_sqlParameters[$i]['parameters'][] = $sqlWalker->getQuery()->getParameter($paramKey);
$this->_sqlParameters[$i]['types'][] = $sqlWalker->getQuery()->getParameterType($paramKey);
++$this->_numParametersInUpdateClause;
}
@@ -136,7 +137,7 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
$this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSQL() . ' ' . $tempTable . ' ('
. $platform->getColumnDeclarationListSQL($columnDefinitions) . ')';
$this->_dropTempTableSql = 'DROP TABLE ' . $tempTable;
$this->_dropTempTableSql = $platform->getDropTemporaryTableSQL($tempTable);
}
/**
@@ -154,11 +155,23 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor
$conn->executeUpdate($this->_createTempTableSql);
// Insert identifiers. Parameters from the update clause are cut off.
$numUpdated = $conn->executeUpdate($this->_insertSql, array_slice($params, $this->_numParametersInUpdateClause), $types);
$numUpdated = $conn->executeUpdate(
$this->_insertSql,
array_slice($params, $this->_numParametersInUpdateClause),
array_slice($types, $this->_numParametersInUpdateClause)
);
// Execute UPDATE statements
for ($i=0, $count=count($this->_sqlStatements); $i<$count; ++$i) {
$conn->executeUpdate($this->_sqlStatements[$i], isset($this->_sqlParameters[$i]) ? $this->_sqlParameters[$i] : array());
$parameters = array();
$types = array();
if (isset($this->_sqlParameters[$i])) {
$parameters = isset($this->_sqlParameters[$i]['parameters']) ? $this->_sqlParameters[$i]['parameters'] : array();
$types = isset($this->_sqlParameters[$i]['types']) ? $this->_sqlParameters[$i]['types'] : array();
}
$conn->executeUpdate($this->_sqlStatements[$i], $parameters, $types);
}
// Drop temporary table

View File

@@ -2290,7 +2290,7 @@ class Parser
/**
* ArithmeticPrimary ::= SingleValuedPathExpression | Literal | "(" SimpleArithmeticExpression ")"
* | FunctionsReturningNumerics | AggregateExpression | FunctionsReturningStrings
* | FunctionsReturningDatetime | IdentificationVariable
* | FunctionsReturningDatetime | IdentificationVariable | ResultVariable
*/
public function ArithmeticPrimary()
{
@@ -2314,7 +2314,11 @@ class Parser
if ($peek['value'] == '.') {
return $this->SingleValuedPathExpression();
}
if (isset($this->_queryComponents[$this->_lexer->lookahead['value']]['resultVariable'])) {
return $this->ResultVariable();
}
return $this->StateFieldPathExpression();
case Lexer::T_INPUT_PARAMETER:

View File

@@ -526,9 +526,8 @@ class SqlWalker implements TreeWalker
*/
public function walkSelectClause($selectClause)
{
$sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '') . implode(
', ', array_filter(array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions))
);
$sql = 'SELECT ' . (($selectClause->isDistinct) ? 'DISTINCT ' : '');
$sqlSelectExpressions = array_filter(array_map(array($this, 'walkSelectExpression'), $selectClause->selectExpressions));
$addMetaColumns = ! $this->_query->getHint(Query::HINT_FORCE_PARTIAL_LOAD) &&
$this->_query->getHydrationMode() == Query::HYDRATE_OBJECT
@@ -554,7 +553,8 @@ class SqlWalker implements TreeWalker
$tblAlias = $this->getSQLTableAlias($rootClass->table['name'], $dqlAlias);
$discrColumn = $rootClass->discriminatorColumn;
$columnAlias = $this->getSQLColumnAlias($discrColumn['name']);
$sql .= ", $tblAlias." . $discrColumn['name'] . ' AS ' . $columnAlias;
$sqlSelectExpressions[] = $tblAlias . '.' . $discrColumn['name'] . ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->setDiscriminatorColumn($dqlAlias, $columnAlias);
@@ -574,7 +574,9 @@ class SqlWalker implements TreeWalker
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
$columnAlias = $this->getSQLColumnAlias($srcColumn);
$sql .= ", $sqlTableAlias." . $srcColumn . ' AS ' . $columnAlias;
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
}
@@ -589,7 +591,9 @@ class SqlWalker implements TreeWalker
if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
foreach ($assoc['targetToSourceKeyColumns'] as $srcColumn) {
$columnAlias = $this->getSQLColumnAlias($srcColumn);
$sql .= ', ' . $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
$sqlSelectExpressions[] = $sqlTableAlias . '.' . $srcColumn . ' AS ' . $columnAlias;
$columnAlias = $this->_platform->getSQLResultCasing($columnAlias);
$this->_rsm->addMetaResult($dqlAlias, $this->_platform->getSQLResultCasing($columnAlias), $srcColumn, (isset($assoc['id']) && $assoc['id'] === true));
}
@@ -598,6 +602,8 @@ class SqlWalker implements TreeWalker
}
}
}
$sql .= implode(', ', $sqlSelectExpressions);
return $sql;
}
@@ -1911,6 +1917,12 @@ class SqlWalker implements TreeWalker
public function walkArithmeticTerm($term)
{
if (is_string($term)) {
if (isset($this->_queryComponents[$term])) {
$columnName = $this->_queryComponents[$term]['token']['value'];
return $this->_scalarResultAliasMap[$columnName];
}
return $term;
}

View File

@@ -97,7 +97,7 @@ class Setup
require_once $directory . "/Doctrine/Common/ClassLoader.php";
}
$loader = new ClassLoader("Doctrine");
$loader = new ClassLoader("Doctrine", $directory);
$loader->register();
$loader = new ClassLoader("Symfony\Component", $directory . "/Doctrine");
@@ -115,7 +115,7 @@ class Setup
*/
static public function createAnnotationMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
{
$config = self::createConfiguration($isDevMode, $cache, $proxyDir);
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
$config->setMetadataDriverImpl($config->newDefaultAnnotationDriver($paths));
return $config;
}
@@ -131,7 +131,7 @@ class Setup
*/
static public function createXMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
{
$config = self::createConfiguration($isDevMode, $cache, $proxyDir);
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
$config->setMetadataDriverImpl(new XmlDriver($paths));
return $config;
}
@@ -147,7 +147,7 @@ class Setup
*/
static public function createYAMLMetadataConfiguration(array $paths, $isDevMode = false, $proxyDir = null, Cache $cache = null)
{
$config = self::createConfiguration($isDevMode, $cache, $proxyDir);
$config = self::createConfiguration($isDevMode, $proxyDir, $cache);
$config->setMetadataDriverImpl(new YamlDriver($paths));
return $config;
}
@@ -162,6 +162,7 @@ class Setup
*/
static public function createConfiguration($isDevMode = false, $proxyDir = null, Cache $cache = null)
{
$proxyDir = $proxyDir ?: sys_get_temp_dir();
if ($isDevMode === false && $cache === null) {
if (extension_loaded('apc')) {
$cache = new \Doctrine\Common\Cache\ApcCache;
@@ -175,16 +176,16 @@ class Setup
} else {
$cache = new ArrayCache;
}
$cache->setNamespace("dc2_"); // to avoid collisions
} else if ($cache === null) {
$cache = new ArrayCache;
}
$cache->setNamespace("dc2_" . md5($proxyDir) . "_"); // to avoid collisions
$config = new Configuration();
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
$config->setResultCacheImpl($cache);
$config->setProxyDir( $proxyDir ?: sys_get_temp_dir() );
$config->setProxyDir( $proxyDir );
$config->setProxyNamespace('DoctrineProxies');
$config->setAutoGenerateProxyClasses($isDevMode);

View File

@@ -834,6 +834,8 @@ class UnitOfWork implements PropertyChangedListener
// See if there are any new classes in the changeset, that are not in the
// commit order graph yet (dont have a node).
// TODO: Can we know the know the possible $newNodes based on something more efficient? IdentityMap?
$newNodes = array();
foreach ($entityChangeSet as $oid => $entity) {
$className = get_class($entity);
@@ -845,7 +847,7 @@ class UnitOfWork implements PropertyChangedListener
}
// Calculate dependencies for new nodes
foreach ($newNodes as $class) {
while ($class = array_pop($newNodes)) {
foreach ($class->associationMappings as $assoc) {
if ($assoc['isOwningSide'] && $assoc['type'] & ClassMetadata::TO_ONE) {
$targetClass = $this->em->getClassMetadata($assoc['targetEntity']);
@@ -860,6 +862,7 @@ class UnitOfWork implements PropertyChangedListener
$targetSubClass = $this->em->getClassMetadata($subClassName);
if ( ! $calc->hasClass($subClassName)) {
$calc->addClass($targetSubClass);
$newNodes[] = $targetSubClass;
}
$calc->addDependency($targetSubClass, $class);
}
@@ -1102,6 +1105,22 @@ class UnitOfWork implements PropertyChangedListener
}
}
}
} else if (!$class->idGenerator->isPostInsertGenerator()) {
// if we have a pre insert generator we can't be sure that having an id
// really means that the entity exists. We have to verify this through
// the last resort: a db lookup
// Last try before db lookup: check the identity map.
if ($this->tryGetById($id, $class->rootEntityName)) {
return self::STATE_DETACHED;
} else {
// db lookup
if ($this->getEntityPersister(get_class($entity))->exists($entity)) {
return self::STATE_DETACHED;
} else {
return self::STATE_NEW;
}
}
} else {
return self::STATE_DETACHED;
}
@@ -1368,6 +1387,10 @@ class UnitOfWork implements PropertyChangedListener
if ($this->getEntityState($entity, self::STATE_DETACHED) == self::STATE_MANAGED) {
$managedCopy = $entity;
} else {
if ($entity instanceof Proxy && ! $entity->__isInitialized__) {
$entity->__load();
}
// Try to look the entity up in the identity map.
$id = $class->getIdentifierValues($entity);
@@ -1742,7 +1765,7 @@ class UnitOfWork implements PropertyChangedListener
*/
public function lock($entity, $lockMode, $lockVersion = null)
{
if ($this->getEntityState($entity) != self::STATE_MANAGED) {
if ($this->getEntityState($entity, self::STATE_DETACHED) != self::STATE_MANAGED) {
throw new InvalidArgumentException("Entity is not MANAGED.");
}

View File

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

View File

@@ -31,7 +31,7 @@ class CmsUser
*/
public $name;
/**
* @OneToMany(targetEntity="CmsPhonenumber", mappedBy="user", cascade={"persist", "remove", "merge"}, orphanRemoval=true)
* @OneToMany(targetEntity="CmsPhonenumber", mappedBy="user", cascade={"persist", "merge"}, orphanRemoval=true)
*/
public $phonenumbers;
/**

View File

@@ -17,6 +17,11 @@ class CompanyEmployee extends CompanyPerson
* @Column(type="string", length=255)
*/
private $department;
/**
* @Column(type="datetime", nullable=true)
*/
private $startDate;
public function getSalary() {
return $this->salary;
@@ -33,4 +38,12 @@ class CompanyEmployee extends CompanyPerson
public function setDepartment($dep) {
$this->department = $dep;
}
public function getStartDate() {
return $this->startDate;
}
public function setStartDate($date) {
$this->startDate = $date;
}
}

View File

@@ -150,15 +150,15 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$user->username = 'gblanco';
$user->status = 'developer';
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
$this->_em->persist($user);
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($user));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_MANAGED, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_MANAGED");
$this->_em->remove($user);
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
$this->_em->persist($user);
$this->_em->flush();
@@ -166,10 +166,10 @@ class BasicFunctionalTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->remove($user);
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_REMOVED, $this->_em->getUnitOfWork()->getEntityState($user));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_REMOVED, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_REMOVED");
$this->_em->flush();
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user));
$this->assertEquals(\Doctrine\ORM\UnitOfWork::STATE_NEW, $this->_em->getUnitOfWork()->getEntityState($user), "State should be UnitOfWork::STATE_NEW");
$this->assertNull($this->_em->find('Doctrine\Tests\Models\CMS\CmsUser', $id));
}

View File

@@ -291,8 +291,21 @@ class ClassTableInheritanceTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertTrue(count($this->_em->createQuery(
'SELECT count(p.id) FROM Doctrine\Tests\Models\Company\CompanyEmployee p WHERE p.salary = 1')
->getResult()) > 0);
->getResult()) > 0);
}
/**
* @group DDC-1341
*/
public function testBulkUpdateNonScalarParameterDDC1341()
{
$dql = 'UPDATE Doctrine\Tests\Models\Company\CompanyEmployee AS p SET p.startDate = ?0 WHERE p.department = ?1';
$query = $this->_em->createQuery($dql)
->setParameter(0, new \DateTime())
->setParameter(1, 'IT');
$result = $query->execute();
}
/**

View File

@@ -0,0 +1,58 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\CMS\CmsUser,
Doctrine\Tests\Models\CMS\CmsAddress,
Doctrine\Tests\Models\CMS\CmsPhonenumber;
require_once __DIR__ . '/../../TestInit.php';
/**
* Tests a bidirectional one-to-many association mapping with orphan removal.
*/
class OneToManyOrphanRemovalTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testOrphanRemoval()
{
$user = new CmsUser;
$user->status = 'dev';
$user->username = 'romanb';
$user->name = 'Roman B.';
$phone = new CmsPhonenumber;
$phone->phonenumber = '123456';
$user->addPhonenumber($phone);
$this->_em->persist($user);
$this->_em->flush();
$userId = $user->getId();
$this->_em->clear();
$userProxy = $this->_em->getReference('Doctrine\Tests\Models\CMS\CmsUser', $userId);
$this->_em->remove($userProxy);
$this->_em->flush();
$this->_em->clear();
$query = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u');
$result = $query->getResult();
$this->assertEquals(0, count($result), 'CmsUser should be removed by EntityManager');
$query = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p');
$result = $query->getResult();
$this->assertEquals(0, count($result), 'CmsPhonenumber should be removed by orphanRemoval');
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\Tests\Models\CMS\CmsUser,
Doctrine\Tests\Models\CMS\CmsAddress,
Doctrine\Tests\Models\CMS\CmsPhonenumber;
require_once __DIR__ . '/../../TestInit.php';
/**
* Tests a bidirectional one-to-one association mapping with orphan removal.
*/
class OneToOneOrphanRemovalTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testOrphanRemoval()
{
$user = new CmsUser;
$user->status = 'dev';
$user->username = 'romanb';
$user->name = 'Roman B.';
$address = new CmsAddress;
$address->country = 'de';
$address->zip = 1234;
$address->city = 'Berlin';
$user->setAddress($address);
$this->_em->persist($user);
$this->_em->flush();
$userId = $user->getId();
$this->_em->clear();
$userProxy = $this->_em->getReference('Doctrine\Tests\Models\CMS\CmsUser', $userId);
$this->_em->remove($userProxy);
$this->_em->flush();
$this->_em->clear();
$query = $this->_em->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u');
$result = $query->getResult();
$this->assertEquals(0, count($result), 'CmsUser should be removed by EntityManager');
$query = $this->_em->createQuery('SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a');
$result = $query->getResult();
$this->assertEquals(0, count($result), 'CmsAddress should be removed by orphanRemoval');
}
}

View File

@@ -501,4 +501,36 @@ class QueryTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertEquals(0, count($users));
}
public function testQueryWithArrayOfEntitiesAsParameter()
{
$userA = new CmsUser;
$userA->name = 'Benjamin';
$userA->username = 'beberlei';
$userA->status = 'developer';
$this->_em->persist($userA);
$userB = new CmsUser;
$userB->name = 'Roman';
$userB->username = 'romanb';
$userB->status = 'developer';
$this->_em->persist($userB);
$userC = new CmsUser;
$userC->name = 'Jonathan';
$userC->username = 'jwage';
$userC->status = 'developer';
$this->_em->persist($userC);
$this->_em->flush();
$this->_em->clear();
$query = $this->_em->createQuery("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u IN (?0) OR u.username = ?1");
$query->setParameter(0, array($userA, $userC));
$query->setParameter(1, 'beberlei');
$users = $query->execute();
$this->assertEquals(2, count($users));
}
}

View File

@@ -0,0 +1,99 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1113
* @group DDC-1306
*/
class DDC1113Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1113Engine'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1113Vehicle'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1113Car'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1113Bus'),
));
} catch (\Exception $e) {
}
}
public function testIssue()
{
$car = new DDC1113Car();
$car->engine = new DDC1113Engine();
$bus = new DDC1113Bus();
$bus->engine = new DDC1113Engine();
$this->_em->persist($car);
$this->_em->flush();
$this->_em->persist($bus);
$this->_em->flush();
$this->_em->remove($bus);
$this->_em->remove($car);
$this->_em->flush();
}
}
/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorMap({"car" = "DDC1113Car", "bus" = "DDC1113Bus"})
*/
class DDC1113Vehicle
{
/** @Id @GeneratedValue @Column(type="integer") */
public $id;
/**
* @ManyToOne(targetEntity="DDC1113Vehicle")
*/
public $parent;
/** @OneToOne(targetEntity="DDC1113Engine", cascade={"persist", "remove"}) */
public $engine;
}
/**
* @Entity
*/
class DDC1113Car extends DDC1113Vehicle
{
}
/**
* @Entity
*/
class DDC1113Bus extends DDC1113Vehicle
{
}
/**
* @Entity
*/
class DDC1113Engine
{
/** @Id @GeneratedValue @Column(type="integer") */
public $id;
}

View File

@@ -0,0 +1,85 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Tests\Models\CMS\CmsEmployee;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1225
*/
class DDC1225Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1225_TestEntity1'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\\DDC1225_TestEntity2'),
));
} catch(\PDOException $e) {
}
}
public function testIssue()
{
$qb = $this->_em->createQueryBuilder();
$qb->from('Doctrine\Tests\ORM\Functional\Ticket\DDC1225_TestEntity1', 'te1')
->select('te1')
->where('te1.testEntity2 = ?1')
->setParameter(1, 0);
$this->assertEquals(
'SELECT t0_.test_entity2_id AS test_entity2_id0 FROM te1 t0_ WHERE t0_.test_entity2_id = ?',
$qb->getQuery()->getSQL()
);
}
}
/**
* @Entity
* @Table(name="te1")
*/
class DDC1225_TestEntity1
{
/**
* @Id
* @ManyToOne(targetEntity="Doctrine\Tests\ORM\Functional\Ticket\DDC1225_TestEntity2")
* @JoinColumn(name="test_entity2_id", referencedColumnName="id", nullable=false)
*/
private $testEntity2;
/**
* @param DDC1225_TestEntity2 $testEntity2
*/
public function setTestEntity2(DDC1225_TestEntity2 $testEntity2)
{
$this->testEntity2 = $testEntity2;
}
/**
* @return DDC1225_TestEntity2
*/
public function getTestEntity2()
{
return $this->testEntity2;
}
}
/**
* @Entity
* @Table(name="te2")
*/
class DDC1225_TestEntity2
{
/**
* @Id
* @GeneratedValue(strategy="AUTO")
* @Column(type="integer")
*/
private $id;
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Tests\Models\CMS\CmsUser;
use Doctrine\Tests\Models\CMS\CmsGroup;
use Doctrine\Tests\Models\CMS\CmsPhonenumber;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1306
*/
class DDC1306Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testIssue()
{
$phone = new CmsPhonenumber();
$phone->phonenumber = "1234";
// puts user and phone into commit order calculator
$this->_em->persist($phone);
$this->_em->flush();
$address = new \Doctrine\Tests\Models\CMS\CmsAddress();
$address->city = "bonn";
$address->country = "Germany";
$address->street = "somestreet!";
$address->zip = 12345;
$this->_em->persist($address);
$user = new CmsUser();
$user->username = "beberlei";
$user->name = "benjamin";
$user->status = "active";
$user->setAddress($address);
// puts user and address into commit order calculator, but does not calculate user dependencies new
$this->_em->persist($user);
$this->_em->flush();
$this->_em->remove($user->getAddress());
$this->_em->remove($user);
$this->_em->flush();
}
}

View File

@@ -0,0 +1,127 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\ORM\UnitOfWork;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1392
*/
class DDC1392Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
protected function setUp()
{
parent::setUp();
try {
$this->_schemaTool->createSchema(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1392File'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1392Picture'),
));
} catch (\Exception $ignored) {
}
}
public function testFailingCase()
{
$file = new DDC1392File;
$picture = new DDC1392Picture;
$picture->setFile($file);
$em = $this->_em;
$em->persist($picture);
$em->flush();
$em->clear();
$fileId = $file->getFileId();
$pictureId = $picture->getPictureId();
$this->assertTrue($fileId > 0);
$picture = $em->find(__NAMESPACE__ . '\DDC1392Picture', $pictureId);
$this->assertEquals(UnitOfWork::STATE_MANAGED, $em->getUnitOfWork()->getEntityState($picture->getFile()), "Lazy Proxy should be marked MANAGED.");
$file = $picture->getFile();
// With this activated there will be no problem
//$file->__load();
$picture->setFile(null);
$em->clear();
$em->merge($file);
$em->flush();
$q = $this->_em->createQuery("SELECT COUNT(e) FROM " . __NAMESPACE__ . '\DDC1392File e');
$result = $q->getSingleScalarResult();
self::assertEquals(1, $result);
}
}
/**
* @Entity
*/
class DDC1392Picture
{
/**
* @Column(name="picture_id", type="integer")
* @Id @GeneratedValue
*/
private $pictureId;
/**
* @ManyToOne(targetEntity="DDC1392File", cascade={"persist", "remove"})
* @JoinColumn(name="file_id", referencedColumnName="file_id")
*/
private $file;
/**
* Get pictureId
*/
public function getPictureId()
{
return $this->pictureId;
}
/**
* Set file
*/
public function setFile($value = null)
{
$this->file = $value;
}
/**
* Get file
*/
public function getFile()
{
return $this->file;
}
}
/**
* @Entity
*/
class DDC1392File
{
/**
* @Column(name="file_id", type="integer")
* @Id
* @GeneratedValue(strategy="AUTO")
*/
public $fileId;
/**
* Get fileId
*/
public function getFileId()
{
return $this->fileId;
}
}

View File

@@ -182,7 +182,7 @@ abstract class AbstractMappingDriverTest extends \Doctrine\Tests\OrmTestCase
$this->assertTrue(isset($class->associationMappings['phonenumbers']));
$this->assertFalse($class->associationMappings['phonenumbers']['isOwningSide']);
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRemove']);
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeMerge']);

View File

@@ -38,8 +38,8 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
foreach ($queryHints AS $name => $value) {
$query->setHint($name, $value);
}
parent::assertEquals($sqlToBeConfirmed, $query->getSql());
parent::assertEquals($sqlToBeConfirmed, $query->getSQL());
$query->free();
} catch (\Exception $e) {
$this->fail($e->getMessage() ."\n".$e->getTraceAsString());
@@ -410,7 +410,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
{
$this->assertSqlGeneration(
"SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
"SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c0_.discr AS discr4 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id WHERE c0_.discr = 'manager'"
"SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c0_.discr AS discr5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id WHERE c0_.discr = 'manager'"
);
}
@@ -418,7 +418,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
{
$this->assertSqlGeneration(
"SELECT u FROM Doctrine\Tests\Models\Company\CompanyManager u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
"SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c2_.title AS title4, c0_.discr AS discr5 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id WHERE c0_.discr = 'manager'"
"SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id WHERE c0_.discr = 'manager'"
);
}
@@ -555,7 +555,7 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
$this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, array('id' => 101));
$q3->setParameter('param', $person);
$this->assertEquals(
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c1_.car_id AS car_id3, c2_.salary AS salary4, c2_.department AS department5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',
'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c1_.car_id AS car_id3, c2_.salary AS salary4, c2_.department AS department5, c2_.startDate AS startDate6, c0_.discr AS discr7, c0_.spouse_id AS spouse_id8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',
$q3->getSql()
);
}

View File

@@ -220,10 +220,11 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
$this->assertEquals('CASCADE', $class->associationMappings['address']['joinColumns'][0]['onUpdate']);
$this->assertTrue($class->associationMappings['address']['isCascadeRemove']);
$this->assertFalse($class->associationMappings['address']['isCascadePersist']);
$this->assertTrue($class->associationMappings['address']['isCascadePersist']);
$this->assertFalse($class->associationMappings['address']['isCascadeRefresh']);
$this->assertFalse($class->associationMappings['address']['isCascadeMerge']);
$this->assertFalse($class->associationMappings['address']['isCascadeDetach']);
$this->assertTrue($class->associationMappings['address']['orphanRemoval']);
return $class;
}
@@ -240,11 +241,12 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
$this->assertEquals('user', $class->associationMappings['phonenumbers']['mappedBy']);
$this->assertEquals(array('number' => 'ASC'), $class->associationMappings['phonenumbers']['orderBy']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRemove']);
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']);
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeMerge']);
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeMerge']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']);
$this->assertTrue($class->associationMappings['phonenumbers']['orphanRemoval']);
return $class;
}
@@ -301,9 +303,11 @@ abstract class AbstractClassMetadataExporterTest extends \Doctrine\Tests\OrmTest
public function testCascadeIsExported($class)
{
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadePersist']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeMerge']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRemove']);
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeMerge']);
$this->assertTrue($class->associationMappings['phonenumbers']['isCascadeRemove']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeRefresh']);
$this->assertFalse($class->associationMappings['phonenumbers']['isCascadeDetach']);
$this->assertTrue($class->associationMappings['phonenumbers']['orphanRemoval']);
return $class;
}

View File

@@ -23,14 +23,14 @@ class User
public $email;
/**
* @OneToOne(targetEntity="Doctrine\Tests\ORM\Tools\Export\Address", cascade={"remove"}, inversedBy="user")
* @OneToOne(targetEntity="Doctrine\Tests\ORM\Tools\Export\Address", cascade={"remove", "persist"}, inversedBy="user", orphanRemoval=true)
* @JoinColumn(name="address_id", onDelete="CASCADE", onUpdate="CASCADE")
*/
public $address;
/**
*
* @OneToMany(targetEntity="Doctrine\Tests\ORM\Tools\Export\Phonenumber", mappedBy="user", cascade={"persist"})
* @OneToMany(targetEntity="Doctrine\Tests\ORM\Tools\Export\Phonenumber", mappedBy="user", cascade={"persist", "merge"}, orphanRemoval=true)
* @OrderBy({"number"="ASC"})
*/
public $phonenumbers;
@@ -65,4 +65,4 @@ class User
public function doStuffOnPostPersist()
{
}
}
}

View File

@@ -37,7 +37,7 @@ $metadata->mapOneToOne(array(
'inversedBy' => 'user',
'cascade' =>
array(
0 => 'remove',
0 => 'persist',
),
'mappedBy' => NULL,
'joinColumns' =>
@@ -50,7 +50,7 @@ $metadata->mapOneToOne(array(
'onUpdate' => 'CASCADE'
),
),
'orphanRemoval' => false,
'orphanRemoval' => true,
));
$metadata->mapOneToMany(array(
'fieldName' => 'phonenumbers',
@@ -58,9 +58,10 @@ $metadata->mapOneToMany(array(
'cascade' =>
array(
1 => 'persist',
2 => 'merge',
),
'mappedBy' => 'user',
'orphanRemoval' => false,
'orphanRemoval' => true,
'orderBy' =>
array(
'number' => 'ASC',

View File

@@ -20,14 +20,15 @@
<field name="name" column="name" type="string" length="50" nullable="true" unique="true" />
<field name="email" column="user_email" type="string" column-definition="CHAR(32) NOT NULL" />
<one-to-one field="address" target-entity="Doctrine\Tests\ORM\Tools\Export\Address" inversed-by="user">
<cascade><cascade-remove /></cascade>
<one-to-one field="address" target-entity="Doctrine\Tests\ORM\Tools\Export\Address" inversed-by="user" orphan-removal="true">
<cascade><cascade-persist /></cascade>
<join-column name="address_id" referenced-column-name="id" on-delete="CASCADE" on-update="CASCADE"/>
</one-to-one>
<one-to-many field="phonenumbers" target-entity="Doctrine\Tests\ORM\Tools\Export\Phonenumber" mapped-by="user">
<one-to-many field="phonenumbers" target-entity="Doctrine\Tests\ORM\Tools\Export\Phonenumber" mapped-by="user" orphan-removal="true">
<cascade>
<cascade-persist/>
<cascade-merge/>
</cascade>
<order-by>
<order-by-field name="number" direction="ASC" />

View File

@@ -24,15 +24,17 @@ Doctrine\Tests\ORM\Tools\Export\User:
referencedColumnName: id
onDelete: CASCADE
onUpdate: CASCADE
cascade: [ remove ]
cascade: [ remove, persist ]
inversedBy: user
orphanRemoval: true
oneToMany:
phonenumbers:
targetEntity: Doctrine\Tests\ORM\Tools\Export\Phonenumber
mappedBy: user
orderBy:
number: ASC
cascade: [ persist ]
cascade: [ persist, merge ]
orphanRemoval: true
manyToMany:
groups:
targetEntity: Doctrine\Tests\ORM\Tools\Export\Group
@@ -51,4 +53,4 @@ Doctrine\Tests\ORM\Tools\Export\User:
- all
lifecycleCallbacks:
prePersist: [ doStuffOnPrePersist, doOtherStuffOnPrePersistToo ]
postPersist: [ doStuffOnPostPersist ]
postPersist: [ doStuffOnPostPersist ]

View File

@@ -3,6 +3,7 @@
namespace Doctrine\Tests\ORM\Tools;
use Doctrine\ORM\Tools\Setup;
use Doctrine\Common\Cache\ArrayCache;
require_once __DIR__ . '/../../TestInit.php';
@@ -69,6 +70,28 @@ class SetupTest extends \Doctrine\Tests\OrmTestCase
$this->assertInstanceOf('Doctrine\ORM\Configuration', $config);
$this->assertInstanceOf('Doctrine\ORM\Mapping\Driver\YamlDriver', $config->getMetadataDriverImpl());
}
/**
* @group DDC-1350
*/
public function testConfigureProxyDir()
{
$config = Setup::createAnnotationMetadataConfiguration(array(), true, "/foo");
$this->assertEquals('/foo', $config->getProxyDir());
}
/**
* @group DDC-1350
*/
public function testConfigureCache()
{
$cache = new ArrayCache();
$config = Setup::createAnnotationMetadataConfiguration(array(), true, null, $cache);
$this->assertSame($cache, $config->getResultCacheImpl());
$this->assertSame($cache, $config->getMetadataCacheImpl());
$this->assertSame($cache, $config->getQueryCacheImpl());
}
public function tearDown()
{