[DDC-1601] Fix bugs in SchemaValidator, using all modelsets as testdata for a large test
This commit is contained in:
parent
adec530c13
commit
6ffe4d3dda
@ -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.
|
||||
*
|
||||
|
@ -28,7 +28,7 @@ class CompanyPerson
|
||||
*/
|
||||
private $name;
|
||||
/**
|
||||
* @OneToOne(targetEntity="CompanyPerson", mappedBy="spouse")
|
||||
* @OneToOne(targetEntity="CompanyPerson")
|
||||
* @JoinColumn(name="spouse_id", referencedColumnName="id")
|
||||
*/
|
||||
private $spouse;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ class LegacyUserReference
|
||||
|
||||
/**
|
||||
* @Id
|
||||
* @ManyToOne(targetEntity="LegacyUser", inversedBy="_references")
|
||||
* @ManyToOne(targetEntity="LegacyUser")
|
||||
* @JoinColumn(name="iUserIdTarget", referencedColumnName="iUserId")
|
||||
*/
|
||||
private $_target;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
50
tests/Doctrine/Tests/ORM/Functional/SchemaValidatorTest.php
Normal file
50
tests/Doctrine/Tests/ORM/Functional/SchemaValidatorTest.php
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user