1
0
mirror of synced 2025-03-21 07:23:55 +03:00

[DDC-1601] Fix bugs in SchemaValidator, using all modelsets as testdata for a large test

This commit is contained in:
Benjamin Eberlei 2012-01-15 11:27:28 +01:00
parent adec530c13
commit 6ffe4d3dda
7 changed files with 99 additions and 42 deletions

View File

@ -95,8 +95,8 @@ class SchemaValidator
}
foreach ($class->associationMappings AS $fieldName => $assoc) {
if (!$cmf->hasMetadataFor($assoc['targetEntity'])) {
$ce[] = "The target entity '" . $assoc['targetEntity'] . "' specified on " . $class->name . '#' . $fieldName . ' is unknown.';
if (!class_exists($assoc['targetEntity']) || $cmf->isTransient($assoc['targetEntity'])) {
$ce[] = "The target entity '" . $assoc['targetEntity'] . "' specified on " . $class->name . '#' . $fieldName . ' is unknown or not an entity.';
return $ce;
}
@ -119,7 +119,7 @@ class SchemaValidator
$ce[] = "The field " . $class->name . "#" . $fieldName . " is on the inverse side of a ".
"bi-directional relationship, but the specified mappedBy association on the target-entity ".
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " does not contain the required ".
"'inversedBy' attribute.";
"'inversedBy=".$fieldName."' attribute.";
} else if ($targetMetadata->associationMappings[$assoc['mappedBy']]['inversedBy'] != $fieldName) {
$ce[] = "The mappings " . $class->name . "#" . $fieldName . " and " .
$assoc['targetEntity'] . "#" . $assoc['mappedBy'] . " are ".
@ -162,30 +162,21 @@ class SchemaValidator
if ($assoc['isOwningSide']) {
if ($assoc['type'] == ClassMetadataInfo::MANY_TO_MANY) {
$identifierColumns = $class->getIdentifierColumnNames();
foreach ($assoc['joinTable']['joinColumns'] AS $joinColumn) {
if (!isset($class->fieldNames[$joinColumn['referencedColumnName']])) {
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' does not " .
"have a corresponding field with this column name on the class '" . $class->name . "'.";
break;
}
$fieldName = $class->fieldNames[$joinColumn['referencedColumnName']];
if (!in_array($fieldName, $class->identifier)) {
if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) {
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
"has to be a primary key column.";
"has to be a primary key column on the target entity class '".$class->name."'.";
break;
}
}
foreach ($assoc['joinTable']['inverseJoinColumns'] AS $inverseJoinColumn) {
if (!isset($targetMetadata->fieldNames[$inverseJoinColumn['referencedColumnName']])) {
$ce[] = "The inverse referenced column name '" . $inverseJoinColumn['referencedColumnName'] . "' does not " .
"have a corresponding field with this column name on the class '" . $targetMetadata->name . "'.";
break;
}
$fieldName = $targetMetadata->fieldNames[$inverseJoinColumn['referencedColumnName']];
if (!in_array($fieldName, $targetMetadata->identifier)) {
$ce[] = "The referenced column name '" . $inverseJoinColumn['referencedColumnName'] . "' " .
"has to be a primary key column.";
$identifierColumns = $targetMetadata->getIdentifierColumnNames();
foreach ($assoc['joinTable']['inverseJoinColumns'] AS $inverseJoinColumn) {
if (!in_array($inverseJoinColumn['referencedColumnName'], $identifierColumns)) {
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
"has to be a primary key column on the target entity class '".$targetMetadata->name."'.";
break;
}
}
@ -204,29 +195,23 @@ class SchemaValidator
}
} else if ($assoc['type'] & ClassMetadataInfo::TO_ONE) {
$identifierColumns = $targetMetadata->getIdentifierColumnNames();
foreach ($assoc['joinColumns'] AS $joinColumn) {
if (!isset($targetMetadata->fieldNames[$joinColumn['referencedColumnName']])) {
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' does not " .
"have a corresponding field with this column name on the class '" . $targetMetadata->name . "'.";
break;
}
$fieldName = $targetMetadata->fieldNames[$joinColumn['referencedColumnName']];
if (!in_array($fieldName, $targetMetadata->identifier)) {
if (!in_array($joinColumn['referencedColumnName'], $identifierColumns)) {
$ce[] = "The referenced column name '" . $joinColumn['referencedColumnName'] . "' " .
"has to be a primary key column.";
"has to be a primary key column on the target entity class '".$targetMetadata->name."'.";
}
}
if (count($class->getIdentifierColumnNames()) != count($assoc['joinColumns'])) {
if (count($identifierColumns) != count($assoc['joinColumns'])) {
$ids = array();
foreach ($assoc['joinColumns'] AS $joinColumn) {
$ids[] = $joinColumn['name'];
}
$ce[] = "The join columns of the association '" . $assoc['fieldName'] . "' " .
"have to match to ALL identifier columns of the source entity '". $class->name . "', " .
"however '" . implode(", ", array_diff($class->getIdentifierColumnNames(), $ids)) .
"have to match to ALL identifier columns of the target entity '". $class->name . "', " .
"however '" . implode(", ", array_diff($targetMetadata->getIdentifierColumnNames(), $ids)) .
"' are missing.";
}
}
@ -260,6 +245,28 @@ class SchemaValidator
return $ce;
}
/**
* @param string $columnName
* @param ClassMetadataInfo $class
* @return bool
*/
private function columnExistsOnEntity($columnName, $class)
{
if (isset($class->fieldNames[$columnName])) {
return true;
}
foreach ($class->associationMappings as $assoc) {
if ($assoc['isOwningSide']) {
foreach ($assoc['joinColumns'] as $columnMapping) {
if ($columnMapping['name'] == $columnName) {
return true;
}
}
}
}
return false;
}
/**
* Check if the Database Schema is in sync with the current metadata state.
*

View File

@ -28,7 +28,7 @@ class CompanyPerson
*/
private $name;
/**
* @OneToOne(targetEntity="CompanyPerson", mappedBy="spouse")
* @OneToOne(targetEntity="CompanyPerson")
* @JoinColumn(name="spouse_id", referencedColumnName="id")
*/
private $spouse;

View File

@ -16,7 +16,7 @@ class DDC117Reference
/**
* @Id
* @ManyToOne(targetEntity="DDC117Article", inversedBy="references")
* @ManyToOne(targetEntity="DDC117Article")
* @JoinColumn(name="target_id", referencedColumnName="article_id")
*/
private $target;
@ -61,4 +61,4 @@ class DDC117Reference
{
return $this->description;
}
}
}

View File

@ -9,7 +9,7 @@ class DDC117Translation
{
/**
* @Id
* @ManyToOne(targetEntity="DDC117Article")
* @ManyToOne(targetEntity="DDC117Article", inversedBy="translations")
* @JoinColumn(name="article_id", referencedColumnName="article_id")
*/
private $article;
@ -62,4 +62,4 @@ class DDC117Translation
{
return $this->reviewedByEditors;
}
}
}

View File

@ -17,7 +17,7 @@ class LegacyUserReference
/**
* @Id
* @ManyToOne(targetEntity="LegacyUser", inversedBy="_references")
* @ManyToOne(targetEntity="LegacyUser")
* @JoinColumn(name="iUserIdTarget", referencedColumnName="iUserId")
*/
private $_target;

View File

@ -26,7 +26,7 @@ class NavPointOfInterest
private $name;
/**
* @ManyToOne(targetEntity="NavCountry")
* @ManyToOne(targetEntity="NavCountry", inversedBy="pois")
*/
private $country;
@ -53,4 +53,4 @@ class NavPointOfInterest
public function getCountry() {
return $this->country;
}
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace Doctrine\Tests\ORM\Functional;
use Doctrine\ORM\Tools\SchemaValidator;
/**
* Test the validity of all modelsets
*
* @group DDC-1601
*/
class SchemaValidatorTest extends \Doctrine\Tests\OrmFunctionalTestCase
{
static public function dataValidateModelSets()
{
$modelSets = array();
foreach (self::$_modelSets as $modelSet => $classes) {
if ($modelSet == "customtype") {
continue;
}
$modelSets[] = array($modelSet);
}
return $modelSets;
}
/**
* @dataProvider dataValidateModelSets
*/
public function testValidateModelSets($modelSet)
{
$validator = new SchemaValidator($this->_em);
$classes = array();
foreach (self::$_modelSets[$modelSet] as $className) {
$classes[] = $this->_em->getClassMetadata($className);
}
foreach ($classes as $class) {
$ce = $validator->validateClass($class);
foreach ($ce as $key => $error) {
if (strpos($error, "must be private or protected. Public fields may break lazy-loading.") !== false) {
unset($ce[$key]);
}
}
$this->assertEquals(0, count($ce), "Invalid Modelset: " . $modelSet . " class " . $class->name . ": ". implode("\n", $ce));
}
}
}