diff --git a/lib/Doctrine/ORM/Id/TableGenerator.php b/lib/Doctrine/ORM/Id/TableGenerator.php index fecc58386..a472a6de3 100644 --- a/lib/Doctrine/ORM/Id/TableGenerator.php +++ b/lib/Doctrine/ORM/Id/TableGenerator.php @@ -12,8 +12,48 @@ use Doctrine\ORM\EntityManager; */ class TableGenerator extends AbstractIdGenerator { + private $_tableName; + private $_sequenceName; + private $_allocationSize; + private $_nextValue; + private $_maxValue; + + public function __construct($tableName, $sequenceName = 'default', $allocationSize = 10) + { + $this->_tableName = $tableName; + $this->_sequenceName = $sequenceName; + $this->_allocationSize = $allocationSize; + } + public function generate(EntityManager $em, $entity) { - throw new \BadMethodCallException(__CLASS__."::".__FUNCTION__." not implemented."); + if ($this->_maxValue === null || $this->_nextValue == $this->_maxValue) { + // Allocate new values + $conn = $em->getConnection(); + if ($conn->getTransactionNestingLevel() == 0) { + + // use select for update + $sql = $conn->getDatabasePlatform()->getTableHiLoCurrentValSql($this->_tableName, $this->_sequenceName); + $currentLevel = $conn->fetchColumn($sql); + if ($currentLevel != null) { + $this->_nextValue = $currentLevel; + $this->_maxValue = $this->_nextValue + $this->_allocationSize; + + $updateSql = $conn->getDatabasePlatform()->getTableHiLoUpdateNextValSql( + $this->_tableName, $this->_sequenceName, $this->_allocationSize + ); + + if ($conn->executeUpdate($updateSql, array(1 => $currentLevel, 2 => $currentLevel+1)) !== 1) { + // no affected rows, concurrency issue, throw exception + } + } else { + // no current level returned, TableGenerator seems to be broken, throw exception + } + } else { + // only table locks help here, implement this or throw exception? + // or do we want to work with table locks exclusively? + } + } + return $this->_nextValue++; } } \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 7f47b6d27..89dc54935 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -609,6 +609,10 @@ class ClassMetadataInfo } $this->columnNames[$mapping['fieldName']] = $mapping['columnName']; + if (isset($this->fieldNames[$mapping['columnName']]) || ($this->discriminatorColumn != null && $this->discriminatorColumn['name'] == $mapping['columnName'])) { + throw MappingException::duplicateColumnName($this->name, $mapping['columnName']); + } + $this->fieldNames[$mapping['columnName']] = $mapping['fieldName']; // Complete id mapping @@ -1033,7 +1037,7 @@ class ClassMetadataInfo public function mapField(array $mapping) { $this->_validateAndCompleteFieldMapping($mapping); - if (isset($this->fieldMappings[$mapping['fieldName']])) { + if (isset($this->fieldMappings[$mapping['fieldName']]) || isset($this->associationMappings[$mapping['fieldName']])) { throw MappingException::duplicateFieldMapping($this->name, $mapping['fieldName']); } $this->fieldMappings[$mapping['fieldName']] = $mapping; @@ -1145,7 +1149,7 @@ class ClassMetadataInfo protected function _storeAssociationMapping(AssociationMapping $assocMapping) { $sourceFieldName = $assocMapping->sourceFieldName; - if (isset($this->associationMappings[$sourceFieldName])) { + if (isset($this->fieldMappings[$sourceFieldName]) || isset($this->associationMappings[$sourceFieldName])) { throw MappingException::duplicateFieldMapping($this->name, $sourceFieldName); } $this->associationMappings[$sourceFieldName] = $assocMapping; @@ -1232,6 +1236,10 @@ class ClassMetadataInfo public function setDiscriminatorColumn($columnDef) { if ($columnDef !== null) { + if (isset($this->fieldNames[$columnDef['name']])) { + throw MappingException::duplicateColumnName($this->name, $columnDef['name']); + } + if ( ! isset($columnDef['name'])) { throw MappingException::nameIsMandatoryForDiscriminatorColumns($this->name, $columnDef); } diff --git a/lib/Doctrine/ORM/Mapping/MappingException.php b/lib/Doctrine/ORM/Mapping/MappingException.php index 175021b4a..ae0907728 100644 --- a/lib/Doctrine/ORM/Mapping/MappingException.php +++ b/lib/Doctrine/ORM/Mapping/MappingException.php @@ -185,4 +185,14 @@ class MappingException extends \Doctrine\ORM\ORMException "does not exist." ); } + + /** + * @param string $className + * @param string $columnName + * @return self + */ + public static function duplicateColumnName($className, $columnName) + { + return new self("Duplicate definition of column '".$columnName."' on entity '".$className."' in a field or discriminator column mapping."); + } } \ No newline at end of file