Compare commits

...

34 Commits
2.0.4 ... 2.0.5

Author SHA1 Message Date
Benjamin Eberlei
35a318148c Release 2.0.5 2011-05-14 13:36:31 +00:00
Benjamin Eberlei
c63115efa9 Bump DBAL dependency to 2.0.5 2011-05-14 15:32:31 +02:00
Benjamin Eberlei
7cba650aff DDC-1136 - trailing character for backup files. 2011-05-14 11:58:27 +02:00
Benjamin Eberlei
d9475cbfd0 Merge remote-tracking branch 'origin/2.0.x' into 2.0.x 2011-05-14 08:49:01 +02:00
Benjamin Eberlei
ee1708b04a Merge branch 'DDC-1151' into 2.0.x 2011-05-14 08:48:32 +02:00
Benjamin Eberlei
a8057dfe26 DDC-1151 - Slight modification necessary for 2.0.x 2011-05-14 08:46:51 +02:00
Benjamin Eberlei
60e7b8eff4 DDC-1151 - Fix missing table quotes when adding foreign keys in SchemaTool 2011-05-14 08:45:50 +02:00
Guilherme Blanco
28291f0fa7 Merge pull request #56 from stof/DDC-1146
DDC 1146
2011-05-11 15:47:20 -07:00
Christophe Coevoet
eecd9afc09 [DDC-1146] Updated the Symfony2 vendors 2011-05-12 00:28:36 +02:00
Benjamin Eberlei
8f9f85da39 Merge branch 'DDC-1129' into 2.0.x 2011-05-01 11:46:16 +02:00
Benjamin Eberlei
5d7063b2e1 [DDC-1129] Fix bug in version changeset computation aswell as inline ClassMetadata::isCollectionValuedAssociation to increase performance by 2-5% 2011-05-01 11:46:00 +02:00
Benjamin Eberlei
cc26080a00 Merge branch 'DDC-1091' into 2.0.x 2011-05-01 11:02:21 +02:00
Benjamin Eberlei
2b900e2c26 [DDC-1091] Fix bug with custom string functions in StringPrimary 2011-05-01 11:02:08 +02:00
Benjamin Eberlei
aedda4a21d Merge branch 'DDC-1102' into 2.0.x 2011-05-01 10:02:12 +02:00
Benjamin Eberlei
de6f0e4594 DDC-1102 - Typo in EntityGenerator 2011-05-01 10:02:03 +02:00
Benjamin Eberlei
d1191c3f74 Merge pull request #39 from francisbesset/parent_object_not_found.
[2.0.x] Fixed an undefined index by a HydrationException
2011-04-30 15:08:10 -07:00
Guilherme Blanco
bd117fc9eb Merge pull request #49 from fabpot/namespace-parsing-fix.
[DDC-1134] Entity generator: Namespace parsing fix
2011-04-30 12:49:36 -07:00
Benjamin Eberlei
ac04ce4114 Merge branch 'DBAL-115' into 2.0.x 2011-04-30 17:19:31 +02:00
Benjamin Eberlei
8d39f2a36d [DBAL-115] REALLY fix issues with SchemaTool::getDropSchemaSQL(). 2011-04-30 17:19:15 +02:00
Benjamin Eberlei
e86cbd65fa [DBAL-115] Bugfix in SchemaTool not quoting table names when dropping schema. 2011-04-30 17:17:34 +02:00
Benjamin Eberlei
410dd69c5b Merge branch 'DDC-1133' into 2.0.x 2011-04-30 14:24:29 +02:00
Benjamin Eberlei
222a90fc8a DDC-1133 - Ducktype AnnotationReader in AnnotationDriver 2011-04-30 14:24:20 +02:00
Benjamin Eberlei
c8e2ee05d1 Merge branch 'DDC-1109' into 2.0.x 2011-04-30 12:51:30 +02:00
Benjamin Eberlei
7c9c7369fb [DDC-1109] ltrim discriminator map for convenience. 2011-04-30 12:51:10 +02:00
Benjamin Eberlei
8ec9ee82f9 Merge branch '2.0.x' of github.com:doctrine/doctrine2 into 2.0.x 2011-04-30 12:28:29 +02:00
Benjamin Eberlei
33c896c31f Merge branch 'DDC-1108' into 2.0.x 2011-04-30 12:28:14 +02:00
Benjamin Eberlei
9ee3cc98ae [DDC-1108] Fix bug with single char named input parameters in DQL lexer. 2011-04-30 12:27:55 +02:00
Benjamin Eberlei
12bde174c5 Merge branch 'DDC-1132' into 2.0.x 2011-04-30 11:23:30 +02:00
Benjamin Eberlei
7634d45a29 [DDC-1132] Fix many to many table detection. 2011-04-30 11:20:25 +02:00
Benjamin Eberlei
b2873ab236 [DDC-1132] Fix many to many table detection. 2011-04-30 11:20:25 +02:00
Fabien Potencier
2978cad198 Fix namespace/class parsing in the entity generator 2011-04-30 10:42:38 +02:00
Benjamin Eberlei
c49467b7fa build.xml: Cleanup .git directory in Symfony Components 2011-04-07 15:11:52 -04:00
Benjamin Eberlei
095b8fa930 Bump Dev Version to 2.0.5-DEV 2011-04-07 15:04:05 -04:00
Francis Besset
85474a0c7a Fixed an undefined index by a HydrationException 2011-03-21 20:33:32 +01:00
20 changed files with 337 additions and 129 deletions

View File

@@ -100,6 +100,9 @@
</copy>
<exec command="sed 's/${version}-DEV/${version}/' ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php > ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php" passthru="true" />
<exec command="mv ${build.dir}/doctrine-orm/Doctrine/ORM/Version2.php ${build.dir}/doctrine-orm/Doctrine/ORM/Version.php" passthru="true" />
<delete dir="${build.dir}/doctrine-orm/Doctrine/Symfony/Component/Yaml/.git" includeemptydirs="true"/>
<delete dir="${build.dir}/doctrine-orm/Doctrine/Symfony/Component/Console/.git" includeemptydirs="true"/>
</target>
<target name="build" depends="test, build-orm"/>
@@ -266,4 +269,4 @@
<exec command="sudo pirum add ${project.pirum_dir} ${project.basedir}/dist/DoctrineSymfonyYaml-${version}.tgz" dir="." passthru="true" />
<exec command="sudo pirum build ${project.pirum_dir}" passthru="true" />
</target>
</project>
</project>

View File

@@ -39,9 +39,9 @@ class ObjectHydrator extends AbstractHydrator
* This local cache is maintained between hydration runs and not cleared.
*/
private $_ce = array();
/* The following parts are reinitialized on every hydration run. */
private $_identifierMap;
private $_resultPointers;
private $_idTemplate;
@@ -50,7 +50,7 @@ class ObjectHydrator extends AbstractHydrator
private $_initializedCollections = array();
private $_existingCollections = array();
//private $_createdEntities;
/** @override */
protected function _prepare()
@@ -59,7 +59,7 @@ class ObjectHydrator extends AbstractHydrator
$this->_resultPointers =
$this->_idTemplate = array();
$this->_resultCounter = 0;
foreach ($this->_rsm->aliasMap as $dqlAlias => $className) {
$this->_identifierMap[$dqlAlias] = array();
$this->_idTemplate[$dqlAlias] = '';
@@ -68,10 +68,14 @@ class ObjectHydrator extends AbstractHydrator
if ( ! isset($this->_ce[$className])) {
$this->_ce[$className] = $class;
}
// Remember which associations are "fetch joined", so that we know where to inject
// collection stubs or proxies and where not.
if (isset($this->_rsm->relationMap[$dqlAlias])) {
if ( ! isset($this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]])) {
throw HydrationException::parentObjectOfRelationNotFound($dqlAlias, $this->_rsm->parentAliasMap[$dqlAlias]);
}
$sourceClassName = $this->_rsm->aliasMap[$this->_rsm->parentAliasMap[$dqlAlias]];
$sourceClass = $this->_getClassMetadata($sourceClassName);
$assoc = $sourceClass->associationMappings[$this->_rsm->relationMap[$dqlAlias]];
@@ -176,7 +180,7 @@ class ObjectHydrator extends AbstractHydrator
return $value;
}
/**
* Gets an entity instance.
*
@@ -186,7 +190,7 @@ class ObjectHydrator extends AbstractHydrator
*/
private function _getEntity(array $data, $dqlAlias)
{
$className = $this->_rsm->aliasMap[$dqlAlias];
$className = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->discriminatorColumns[$dqlAlias])) {
$discrColumn = $this->_rsm->metaMappings[$this->_rsm->discriminatorColumns[$dqlAlias]];
$className = $this->_ce[$className]->discriminatorMap[$data[$discrColumn]];
@@ -194,7 +198,7 @@ class ObjectHydrator extends AbstractHydrator
}
return $this->_uow->createEntity($className, $data, $this->_hints);
}
private function _getEntityFromIdentityMap($className, array $data)
{
$class = $this->_ce[$className];
@@ -208,7 +212,7 @@ class ObjectHydrator extends AbstractHydrator
return $this->_uow->tryGetByIdHash($data[$class->identifier[0]], $class->rootEntityName);
}
}
/**
* Gets a ClassMetadata instance from the local cache.
* If the instance is not yet in the local cache, it is loaded into the
@@ -266,7 +270,7 @@ class ObjectHydrator extends AbstractHydrator
// Hydrate the data chunks
foreach ($rowData as $dqlAlias => $data) {
$entityName = $this->_rsm->aliasMap[$dqlAlias];
if (isset($this->_rsm->parentAliasMap[$dqlAlias])) {
// It's a joined result
@@ -277,7 +281,7 @@ class ObjectHydrator extends AbstractHydrator
// Get a reference to the parent object to which the joined element belongs.
if ($this->_rsm->isMixed && isset($this->_rootAliases[$parentAlias])) {
$first = reset($this->_resultPointers);
$first = reset($this->_resultPointers);
$parentObject = $this->_resultPointers[$parentAlias][key($first)];
} else if (isset($this->_resultPointers[$parentAlias])) {
$parentObject = $this->_resultPointers[$parentAlias];
@@ -302,11 +306,11 @@ class ObjectHydrator extends AbstractHydrator
} else if ( ! isset($this->_existingCollections[$collKey])) {
$reflFieldValue = $this->_initRelatedCollection($parentObject, $parentClass, $relationField);
}
$indexExists = isset($this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]]);
$index = $indexExists ? $this->_identifierMap[$path][$id[$parentAlias]][$id[$dqlAlias]] : false;
$indexIsValid = $index !== false ? isset($reflFieldValue[$index]) : false;
if ( ! $indexExists || ! $indexIsValid) {
if (isset($this->_existingCollections[$collKey])) {
// Collection exists, only look for the element in the identity map.

View File

@@ -1479,6 +1479,7 @@ class ClassMetadataInfo
if (strpos($className, '\\') === false && strlen($this->namespace)) {
$className = $this->namespace . '\\' . $className;
}
$className = ltrim($className, '\\');
$this->discriminatorMap[$value] = $className;
if ($this->name == $className) {
$this->discriminatorValue = $value;

View File

@@ -67,10 +67,10 @@ class AnnotationDriver implements Driver
* Initializes a new AnnotationDriver that uses the given AnnotationReader for reading
* docblock annotations.
*
* @param $reader The AnnotationReader to use.
* @param AnnotationReader $reader The AnnotationReader to use, duck-typed.
* @param string|array $paths One or multiple paths where mapping classes can be found.
*/
public function __construct(AnnotationReader $reader, $paths = null)
public function __construct($reader, $paths = null)
{
$this->_reader = $reader;
if ($paths) {

View File

@@ -67,6 +67,26 @@ class DatabaseDriver implements Driver
$this->_sm = $schemaManager;
}
/**
* Set tables manually instead of relying on the reverse engeneering capabilities of SchemaManager.
*
* @param array $entityTables
* @param array $manyToManyTables
* @return void
*/
public function setTables($entityTables, $manyToManyTables)
{
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($entityTables AS $table) {
$className = Inflector::classify(strtolower($table->getName()));
$this->classToTableNames[$className] = $table->getName();
$this->tables[$table->getName()] = $table;
}
foreach ($manyToManyTables AS $table) {
$this->manyToManyTables[$table->getName()] = $table;
}
}
private function reverseEngineerMappingFromDatabase()
{
if ($this->tables !== null) {
@@ -77,7 +97,7 @@ class DatabaseDriver implements Driver
$tables[$tableName] = $this->_sm->listTableDetails($tableName);
}
$this->tables = array();
$this->tables = $this->manyToManyTables = $this->classToTableNames = array();
foreach ($tables AS $tableName => $table) {
/* @var $table Table */
if ($this->_sm->getDatabasePlatform()->supportsForeignKeyConstraints()) {
@@ -95,11 +115,7 @@ class DatabaseDriver implements Driver
sort($pkColumns);
sort($allForeignKeyColumns);
if ($pkColumns == $allForeignKeyColumns) {
if (count($table->getForeignKeys()) > 2) {
throw new \InvalidArgumentException("ManyToMany table '" . $tableName . "' with more or less than two foreign keys are not supported by the Database Reverese Engineering Driver.");
}
if ($pkColumns == $allForeignKeyColumns && count($foreignKeys) == 2) {
$this->manyToManyTables[$tableName] = $table;
} else {
// lower-casing is necessary because of Oracle Uppercase Tablenames,
@@ -191,8 +207,10 @@ class DatabaseDriver implements Driver
foreach ($this->manyToManyTables AS $manyTable) {
foreach ($manyTable->getForeignKeys() AS $foreignKey) {
// foreign key maps to the table of the current entity, many to many association probably exists
if (strtolower($tableName) == strtolower($foreignKey->getForeignTableName())) {
$myFk = $foreignKey;
$otherFk = null;
foreach ($manyTable->getForeignKeys() AS $foreignKey) {
if ($foreignKey != $myFk) {
$otherFk = $foreignKey;
@@ -200,6 +218,12 @@ class DatabaseDriver implements Driver
}
}
if (!$otherFk) {
// the definition of this many to many table does not contain
// enough foreign key information to continue reverse engeneering.
continue;
}
$localColumn = current($myFk->getColumns());
$associationMapping = array();
$associationMapping['fieldName'] = Inflector::camelize(str_replace('_id', '', strtolower(current($otherFk->getColumns()))));

View File

@@ -126,7 +126,7 @@ class Lexer extends \Doctrine\Common\Lexer
'[a-z_\\\][a-z0-9_\:\\\]*[a-z0-9_]{1}',
'(?:[0-9]+(?:[\.][0-9]+)*)(?:e[+-]?[0-9]+)?',
"'(?:[^']|'')*'",
'\?[1-9][0-9]*|:[a-z][a-z0-9_]+'
'\?[1-9][0-9]*|:[a-z]{1}[a-z0-9_]{0,}'
);
}

View File

@@ -2301,7 +2301,8 @@ class Parser
if ($peek['value'] == '.') {
return $this->StateFieldPathExpression();
} else if ($peek['value'] == '(') {
return $this->FunctionsReturningStrings();
// do NOT directly go to FunctionsReturningString() because it doesnt check for custom functions.
return $this->FunctionDeclaration();
} else {
$this->syntaxError("'.' or '('");
}

View File

@@ -179,11 +179,11 @@ public function <methodName>()
$this->_isNew = !file_exists($path) || (file_exists($path) && $this->_regenerateEntityIfExists);
if ( ! $this->_isNew) {
$this->_parseTokensInEntityFile($path);
$this->_parseTokensInEntityFile(file_get_contents($path));
}
if ($this->_backupExisting && file_exists($path)) {
$backupPath = dirname($path) . DIRECTORY_SEPARATOR . "~" . basename($path);
$backupPath = dirname($path) . DIRECTORY_SEPARATOR . basename($path) . "~";
if (!copy($path, $backupPath)) {
throw new \RuntimeException("Attempt to backup overwritten entitiy file but copy operation failed.");
}
@@ -400,24 +400,42 @@ public function <methodName>()
/**
* @todo this won't work if there is a namespace in brackets and a class outside of it.
* @param string $path
* @param string $src
*/
private function _parseTokensInEntityFile($path)
private function _parseTokensInEntityFile($src)
{
$tokens = token_get_all(file_get_contents($path));
$tokens = token_get_all($src);
$lastSeenNamespace = "";
$lastSeenClass = false;
$inNamespace = false;
$inClass = false;
for ($i = 0; $i < count($tokens); $i++) {
$token = $tokens[$i];
if ($token[0] == T_NAMESPACE) {
$lastSeenNamespace = $tokens[$i+2][1] . "\\";
} else if ($token[0] == T_NS_SEPARATOR) {
$lastSeenNamespace .= $tokens[$i+1][1] . "\\";
} else if ($token[0] == T_CLASS) {
$lastSeenClass = $lastSeenNamespace . $tokens[$i+2][1];
if (in_array($token[0], array(T_WHITESPACE, T_COMMENT, T_DOC_COMMENT))) {
continue;
}
if ($inNamespace) {
if ($token[0] == T_NS_SEPARATOR || $token[0] == T_STRING) {
$lastSeenNamespace .= $token[1];
} else if (is_string($token) && in_array($token, array(';', '{'))) {
$inNamespace = false;
}
}
if ($inClass) {
$inClass = false;
$lastSeenClass = $lastSeenNamespace . '\\' . $token[1];
$this->_staticReflection[$lastSeenClass]['properties'] = array();
$this->_staticReflection[$lastSeenClass]['methods'] = array();
}
if ($token[0] == T_NAMESPACE) {
$lastSeenNamespace = "";
$inNamespace = true;
} else if ($token[0] == T_CLASS) {
$inClass = true;
} else if ($token[0] == T_FUNCTION) {
if ($tokens[$i+2][0] == T_STRING) {
$this->_staticReflection[$lastSeenClass]['methods'][] = $tokens[$i+2][1];
@@ -502,7 +520,7 @@ public function <methodName>()
}
if ($metadata->isMappedSuperclass) {
$lines[] = ' * @' . $this->_annotationsPrefix . 'MappedSupperClass';
$lines[] = ' * @' . $this->_annotationsPrefix . 'MappedSuperClass';
} else {
$lines[] = ' * @' . $this->_annotationsPrefix . 'Entity';
}

View File

@@ -185,7 +185,7 @@ class SchemaTool
// Add a FK constraint on the ID column
$table->addUnnamedForeignKeyConstraint(
$this->_em->getClassMetadata($class->rootEntityName)->getTableName(),
$this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform),
array($columnName), array($columnName), array('onDelete' => 'CASCADE')
);
}
@@ -424,6 +424,7 @@ class SchemaTool
$localColumns = array();
$foreignColumns = array();
$fkOptions = array();
$foreignTableName = $class->getQuotedTableName($this->_platform);
foreach ($joinColumns as $joinColumn) {
$columnName = $joinColumn['name'];
@@ -483,7 +484,7 @@ class SchemaTool
}
$theJoinTable->addUnnamedForeignKeyConstraint(
$class->getTableName(), $localColumns, $foreignColumns, $fkOptions
$foreignTableName, $localColumns, $foreignColumns, $fkOptions
);
}
@@ -542,58 +543,35 @@ class SchemaTool
}
/**
*
* Get SQL to drop the tables defined by the passed classes.
*
* @param array $classes
* @return array
*/
public function getDropSchemaSQL(array $classes)
{
$visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform);
$schema = $this->getSchemaFromMetadata($classes);
$sm = $this->_em->getConnection()->getSchemaManager();
$sql = array();
$orderedTables = array();
foreach ($classes AS $class) {
if ($class->isIdGeneratorSequence() && !$class->isMappedSuperclass && $class->name == $class->rootEntityName && $this->_platform->supportsSequences()) {
$sql[] = $this->_platform->getDropSequenceSQL($class->sequenceGeneratorDefinition['sequenceName']);
$fullSchema = $sm->createSchema();
foreach ($fullSchema->getTables() AS $table) {
if (!$schema->hasTable($table->getName())) {
foreach ($table->getForeignKeys() AS $foreignKey) {
/* @var $foreignKey \Doctrine\DBAL\Schema\ForeignKeyConstraint */
if ($schema->hasTable($foreignKey->getForeignTableName())) {
$visitor->acceptForeignKey($table, $foreignKey);
}
}
} else {
$visitor->acceptTable($table);
foreach ($table->getForeignKeys() AS $foreignKey) {
$visitor->acceptForeignKey($table, $foreignKey);
}
}
}
$commitOrder = $this->_getCommitOrder($classes);
$associationTables = $this->_getAssociationTables($commitOrder);
// Drop association tables first
foreach ($associationTables as $associationTable) {
if (!in_array($associationTable, $orderedTables)) {
$orderedTables[] = $associationTable;
}
}
// Drop tables in reverse commit order
for ($i = count($commitOrder) - 1; $i >= 0; --$i) {
$class = $commitOrder[$i];
if (($class->isInheritanceTypeSingleTable() && $class->name != $class->rootEntityName)
|| $class->isMappedSuperclass) {
continue;
}
if (!in_array($class->getTableName(), $orderedTables)) {
$orderedTables[] = $class->getTableName();
}
}
$dropTablesSql = array();
foreach ($orderedTables AS $tableName) {
/* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */
$foreignKeys = $sm->listTableForeignKeys($tableName);
foreach ($foreignKeys AS $foreignKey) {
$sql[] = $this->_platform->getDropForeignKeySQL($foreignKey, $tableName);
}
$dropTablesSql[] = $this->_platform->getDropTableSQL($tableName);
}
return array_merge($sql, $dropTablesSql);
return $visitor->getQueries();
}
/**
@@ -636,44 +614,4 @@ class SchemaTool
return $schemaDiff->toSql($this->_platform);
}
}
private function _getCommitOrder(array $classes)
{
$calc = new CommitOrderCalculator;
// Calculate dependencies
foreach ($classes as $class) {
$calc->addClass($class);
foreach ($class->associationMappings as $assoc) {
if ($assoc['isOwningSide']) {
$targetClass = $this->_em->getClassMetadata($assoc['targetEntity']);
if ( ! $calc->hasClass($targetClass->name)) {
$calc->addClass($targetClass);
}
// add dependency ($targetClass before $class)
$calc->addDependency($targetClass, $class);
}
}
}
return $calc->getCommitOrder();
}
private function _getAssociationTables(array $classes)
{
$associationTables = array();
foreach ($classes as $class) {
foreach ($class->associationMappings as $assoc) {
if ($assoc['isOwningSide'] && $assoc['type'] == ClassMetadata::MANY_TO_MANY) {
$associationTables[] = $assoc['joinTable']['name'];
}
}
}
return $associationTables;
}
}

View File

@@ -399,8 +399,11 @@ class UnitOfWork implements PropertyChangedListener
$actualData = array();
foreach ($class->reflFields as $name => $refProp) {
$value = $refProp->getValue($entity);
if ($class->isCollectionValuedAssociation($name) && $value !== null
if (isset($class->associationMappings[$name])
&& ($class->associationMappings[$name]['type'] & ClassMetadata::TO_MANY)
&& $value !== null
&& ! ($value instanceof PersistentCollection)) {
// If $value is not a Collection then use an ArrayCollection.
if ( ! $value instanceof Collection) {
$value = new ArrayCollection($value);
@@ -419,7 +422,7 @@ class UnitOfWork implements PropertyChangedListener
$coll->setDirty( ! $coll->isEmpty());
$class->reflFields[$name]->setValue($entity, $coll);
$actualData[$name] = $coll;
} else if ( ! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity()) {
} else if ( (! $class->isIdentifier($name) || ! $class->isIdGeneratorIdentity()) && ($name !== $class->versionField) ) {
$actualData[$name] = $value;
}
}

View File

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

View File

@@ -104,9 +104,42 @@ class DatabaseDriverTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertArrayHasKey('user', $metadatas['CmsGroups']->associationMappings);
}
public function testIgnoreManyToManyTableWithoutFurtherForeignKeyDetails()
{
$tableB = new \Doctrine\DBAL\Schema\Table("dbdriver_bar");
$tableB->addColumn('id', 'integer');
$tableB->setPrimaryKey(array('id'));
$tableA = new \Doctrine\DBAL\Schema\Table("dbdriver_baz");
$tableA->addColumn('id', 'integer');
$tableA->setPrimaryKey(array('id'));
$tableMany = new \Doctrine\DBAL\Schema\Table("dbdriver_bar_baz");
$tableMany->addColumn('bar_id', 'integer');
$tableMany->addColumn('baz_id', 'integer');
$tableMany->addForeignKeyConstraint('dbdriver_bar', array('bar_id'), array('id'));
$metadatas = $this->convertToClassMetadata(array($tableA, $tableB), array($tableMany));
$this->assertEquals(0, count($metadatas['DbdriverBaz']->associationMappings), "no association mappings should be detected.");
}
protected function convertToClassMetadata(array $entityTables, array $manyTables = array())
{
$driver = new \Doctrine\ORM\Mapping\Driver\DatabaseDriver($this->_sm);
$driver->setTables($entityTables, $manyTables);
$metadatas = array();
foreach ($driver->getAllClassNames() AS $className) {
$class = new ClassMetadataInfo($className);
$driver->loadMetadataForClass($className, $class);
$metadatas[$className] = $class;
}
return $metadatas;
}
/**
*
* @param string $className
* @return ClassMetadata
*/

View File

@@ -50,4 +50,19 @@ class CompanySchemaTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->assertFalse($table->getColumn('pricePerHour')->getNotnull());
$this->assertFalse($table->getColumn('maxPrice')->getNotnull());
}
/**
* @group DBAL-115
*/
public function testDropPartSchemaWithForeignKeys()
{
if (!$this->_em->getConnection()->getDatabasePlatform()->supportsForeignKeyConstraints()) {
$this->markTestSkipped("Foreign Key test");
}
$sql = $this->_schemaTool->getDropSchemaSQL(array(
$this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyManager'),
));
$this->assertEquals(3, count($sql));
}
}

View File

@@ -0,0 +1,46 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
use Doctrine\Common\Collections\ArrayCollection;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1129
*/
class DDC1129Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function setUp()
{
$this->useModelSet('cms');
parent::setUp();
}
public function testVersionFieldIgnoredInChangesetComputation()
{
$article = new \Doctrine\Tests\Models\CMS\CmsArticle();
$article->text = "I don't know.";
$article->topic = "Who is John Galt?";
$this->_em->persist($article);
$this->_em->flush();
$this->assertEquals(1, $article->version);
$class = $this->_em->getClassMetadata('Doctrine\Tests\Models\CMS\CmsArticle');
$uow = $this->_em->getUnitOfWork();
$uow->computeChangeSet($class, $article);
$changeSet = $uow->getEntityChangeSet($article);
$this->assertEquals(0, count($changeSet), "No changesets should be computed.");
$article->text = "This is John Galt speaking.";
$this->_em->flush();
$this->assertEquals(2, $article->version);
$uow->computeChangeSet($class, $article);
$changeSet = $uow->getEntityChangeSet($article);
$this->assertEquals(0, count($changeSet), "No changesets should be computed.");
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Doctrine\Tests\ORM\Functional\Ticket;
require_once __DIR__ . '/../../../TestInit.php';
/**
* @group DDC-1151
*/
class DDC1151Test extends \Doctrine\Tests\OrmFunctionalTestCase
{
public function testQuoteForeignKey()
{
if ($this->_em->getConnection()->getDatabasePlatform()->getName() != 'postgresql') {
$this->markTestSkipped("This test is useful for all databases, but designed only for postgresql.");
}
$sql = $this->_schemaTool->getCreateSchemaSql(array(
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1151User'),
$this->_em->getClassMetadata(__NAMESPACE__ . '\DDC1151Group'),
));
$this->assertEquals("CREATE TABLE \"User\" (id INT NOT NULL, PRIMARY KEY(id))", $sql[0]);
$this->assertEquals("CREATE TABLE ddc1151user_ddc1151group (ddc1151user_id INT NOT NULL, ddc1151group_id INT NOT NULL, PRIMARY KEY(ddc1151user_id, ddc1151group_id))", $sql[1]);
$this->assertEquals("CREATE INDEX IDX_88A3259AC5AD08A ON ddc1151user_ddc1151group (ddc1151user_id)", $sql[2]);
$this->assertEquals("CREATE INDEX IDX_88A32597357E0B1 ON ddc1151user_ddc1151group (ddc1151group_id)", $sql[3]);
$this->assertEquals("CREATE TABLE \"Group\" (id INT NOT NULL, PRIMARY KEY(id))", $sql[4]);
$this->assertEquals("CREATE SEQUENCE User_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[5]);
$this->assertEquals("CREATE SEQUENCE Group_id_seq INCREMENT BY 1 MINVALUE 1 START 1", $sql[6]);
$this->assertEquals("ALTER TABLE ddc1151user_ddc1151group ADD FOREIGN KEY (ddc1151user_id) REFERENCES \"User\"(id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[7]);
$this->assertEquals("ALTER TABLE ddc1151user_ddc1151group ADD FOREIGN KEY (ddc1151group_id) REFERENCES \"Group\"(id) ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE", $sql[8]);
}
}
/**
* @Entity
* @Table(name="`User`")
*/
class DDC1151User
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
/** @ManyToMany(targetEntity="DDC1151Group") */
public $groups;
}
/**
* @Entity
* @Table(name="`Group`")
*/
class DDC1151Group
{
/** @Id @Column(type="integer") @GeneratedValue */
public $id;
}

View File

@@ -482,6 +482,16 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertValidDQL('SELECT u, u.id + ?1 AS someNumber FROM Doctrine\Tests\Models\CMS\CmsUser u');
}
/**
* @group DDC-1091
*/
public function testCustomFunctionsReturningStringInStringPrimary()
{
$this->_em->getConfiguration()->addCustomStringFunction('CC', 'Doctrine\ORM\Query\AST\Functions\ConcatFunction');
$this->assertValidDQL("SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CC('%', u.name) LIKE '%foo%'", true);
}
/**
* @group DDC-505
*/
@@ -513,6 +523,14 @@ class LanguageRecognitionTest extends \Doctrine\Tests\OrmTestCase
$this->assertInvalidDQL('SELECT g FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.groups g');
}
/**
* @group DDC-1108
*/
public function testInputParameterSingleChar()
{
$this->assertValidDQL('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = :q');
}
/**
* @group DDC-1053
*/

View File

@@ -122,7 +122,7 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$this->_generator->writeEntityClass($metadata, $this->_tmpDir);
$this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/~EntityGeneratorBook.php");
$this->assertFileExists($this->_tmpDir . "/" . $this->_namespace . "/EntityGeneratorBook.php~");
$book = $this->newInstance($metadata);
$reflClass = new \ReflectionClass($metadata->name);
@@ -200,6 +200,54 @@ class EntityGeneratorTest extends \Doctrine\Tests\OrmTestCase
$this->assertEquals($cm->idGenerator, $metadata->idGenerator);
$this->assertEquals($cm->customRepositoryClassName, $metadata->customRepositoryClassName);
}
/**
* @dataProvider getParseTokensInEntityFileData
*/
public function testParseTokensInEntityFile($php, $classes)
{
$r = new \ReflectionObject($this->_generator);
$m = $r->getMethod('_parseTokensInEntityFile');
$m->setAccessible(true);
$p = $r->getProperty('_staticReflection');
$p->setAccessible(true);
$ret = $m->invoke($this->_generator, $php);
$this->assertEquals($classes, array_keys($p->getValue($this->_generator)));
}
public function getParseTokensInEntityFileData()
{
return array(
array(
'<?php namespace Foo\Bar; class Baz {}',
array('Foo\Bar\Baz'),
),
array(
'<?php namespace Foo\Bar; use Foo; class Baz {}',
array('Foo\Bar\Baz'),
),
array(
'<?php namespace /*Comment*/ Foo\Bar; /** Foo */class /* Comment */ Baz {}',
array('Foo\Bar\Baz'),
),
array(
'
<?php namespace
/*Comment*/
Foo\Bar
;
/** Foo */
class
/* Comment */
Baz {}
',
array('Foo\Bar\Baz'),
),
);
}
}
class EntityGeneratorAuthor {}