diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php.orig b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php.orig deleted file mode 100644 index 58632c4c1..000000000 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php.orig +++ /dev/null @@ -1,1814 +0,0 @@ -. - */ - -namespace Doctrine\DBAL\Platforms; - -use Doctrine\DBAL\DBALException, - Doctrine\DBAL\Connection, - Doctrine\DBAL\Types, - Doctrine\DBAL\Schema\Table, - Doctrine\DBAL\Schema\Index, - Doctrine\DBAL\Schema\ForeignKeyConstraint, - Doctrine\DBAL\Schema\TableDiff; - -/** - * Base class for all DatabasePlatforms. The DatabasePlatforms are the central - * point of abstraction of platform-specific behaviors, features and SQL dialects. - * They are a passive source of information. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision: 3938 $ - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Lukas Smith (PEAR MDB2 library) - */ -abstract class AbstractPlatform -{ - /** - * @var int - */ - const CREATE_INDEXES = 1; - - /** - * @var int - */ - const CREATE_FOREIGNKEYS = 2; - - /** - * Constructor. - */ - public function __construct() {} - - /** - * Gets the character used for identifier quoting. - * - * @return string - */ - public function getIdentifierQuoteCharacter() - { - return '"'; - } - - /** - * Gets the string portion that starts an SQL comment. - * - * @return string - */ - public function getSqlCommentStartString() - { - return "--"; - } - - /** - * Gets the string portion that ends an SQL comment. - * - * @return string - */ - public function getSqlCommentEndString() - { - return "\n"; - } - - /** - * Gets the maximum length of a varchar field. - * - * @return integer - */ - public function getVarcharMaxLength() - { - return 255; - } - - /** - * Gets all SQL wildcard characters of the platform. - * - * @return array - */ - public function getWildcards() - { - return array('%', '_'); - } - - /** - * Returns the regular expression operator. - * - * @return string - */ - public function getRegexpExpression() - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Returns the average value of a column - * - * @param string $column the column to use - * @return string generated sql including an AVG aggregate function - */ - public function getAvgExpression($column) - { - return 'AVG(' . $column . ')'; - } - - /** - * Returns the number of rows (without a NULL value) of a column - * - * If a '*' is used instead of a column the number of selected rows - * is returned. - * - * @param string|integer $column the column to use - * @return string generated sql including a COUNT aggregate function - */ - public function getCountExpression($column) - { - return 'COUNT(' . $column . ')'; - } - - /** - * Returns the highest value of a column - * - * @param string $column the column to use - * @return string generated sql including a MAX aggregate function - */ - public function getMaxExpression($column) - { - return 'MAX(' . $column . ')'; - } - - /** - * Returns the lowest value of a column - * - * @param string $column the column to use - * @return string - */ - public function getMinExpression($column) - { - return 'MIN(' . $column . ')'; - } - - /** - * Returns the total sum of a column - * - * @param string $column the column to use - * @return string - */ - public function getSumExpression($column) - { - return 'SUM(' . $column . ')'; - } - - // scalar functions - - /** - * Returns the md5 sum of a field. - * - * Note: Not SQL92, but common functionality - * - * @return string - */ - public function getMd5Expression($column) - { - return 'MD5(' . $column . ')'; - } - - /** - * Returns the length of a text field. - * - * @param string $expression1 - * @param string $expression2 - * @return string - */ - public function getLengthExpression($column) - { - return 'LENGTH(' . $column . ')'; - } - - /** - * Rounds a numeric field to the number of decimals specified. - * - * @param string $expression1 - * @param string $expression2 - * @return string - */ - public function getRoundExpression($column, $decimals = 0) - { - return 'ROUND(' . $column . ', ' . $decimals . ')'; - } - - /** - * Returns the remainder of the division operation - * $expression1 / $expression2. - * - * @param string $expression1 - * @param string $expression2 - * @return string - */ - public function getModExpression($expression1, $expression2) - { - return 'MOD(' . $expression1 . ', ' . $expression2 . ')'; - } - - /** - * trim - * returns the string $str with leading and proceeding space characters removed - * - * @param string $str literal string or column name - * @return string - */ - public function getTrimExpression($str) - { - return 'TRIM(' . $str . ')'; - } - - /** - * rtrim - * returns the string $str with proceeding space characters removed - * - * @param string $str literal string or column name - * @return string - */ - public function getRtrimExpression($str) - { - return 'RTRIM(' . $str . ')'; - } - - /** - * ltrim - * returns the string $str with leading space characters removed - * - * @param string $str literal string or column name - * @return string - */ - public function getLtrimExpression($str) - { - return 'LTRIM(' . $str . ')'; - } - - /** - * upper - * Returns the string $str with all characters changed to - * uppercase according to the current character set mapping. - * - * @param string $str literal string or column name - * @return string - */ - public function getUpperExpression($str) - { - return 'UPPER(' . $str . ')'; - } - - /** - * lower - * Returns the string $str with all characters changed to - * lowercase according to the current character set mapping. - * - * @param string $str literal string or column name - * @return string - */ - public function getLowerExpression($str) - { - return 'LOWER(' . $str . ')'; - } - - /** - * locate - * returns the position of the first occurrence of substring $substr in string $str - * - * @param string $substr literal string to find - * @param string $str literal string - * @return integer - */ - public function getLocateExpression($str, $substr) - { - return 'LOCATE(' . $str . ', ' . $substr . ')'; - } - - /** - * Returns the current system date. - * - * @return string - */ - public function getNowExpression() - { - return 'NOW()'; - } - - /** - * return string to call a function to get a substring inside an SQL statement - * - * Note: Not SQL92, but common functionality. - * - * SQLite only supports the 2 parameter variant of this function - * - * @param string $value an sql string literal or column name/alias - * @param integer $position where to start the substring portion - * @param integer $length the substring portion length - * @return string SQL substring function with given parameters - */ - public function getSubstringExpression($value, $from, $len = null) - { - if ($len === null) - return 'SUBSTRING(' . $value . ' FROM ' . $from . ')'; - else { - return 'SUBSTRING(' . $value . ' FROM ' . $from . ' FOR ' . $len . ')'; - } - } - - /** - * Returns a series of strings concatinated - * - * concat() accepts an arbitrary number of parameters. Each parameter - * must contain an expression - * - * @param string $arg1, $arg2 ... $argN strings that will be concatinated. - * @return string - */ - public function getConcatExpression() - { - return join(' || ' , func_get_args()); - } - - /** - * Returns the SQL for a logical not. - * - * Example: - * - * $q = new Doctrine_Query(); - * $e = $q->expr; - * $q->select('*')->from('table') - * ->where($e->eq('id', $e->not('null')); - * - * - * @return string a logical expression - */ - public function getNotExpression($expression) - { - return 'NOT(' . $expression . ')'; - } - - /** - * Returns the SQL to check if a value is one in a set of - * given values. - * - * in() accepts an arbitrary number of parameters. The first parameter - * must always specify the value that should be matched against. Successive - * must contain a logical expression or an array with logical expressions. - * These expressions will be matched against the first parameter. - * - * @param string $column the value that should be matched against - * @param string|array(string) values that will be matched against $column - * @return string logical expression - */ - public function getInExpression($column, $values) - { - if ( ! is_array($values)) { - $values = array($values); - } - $values = $this->getIdentifiers($values); - - if (count($values) == 0) { - throw \InvalidArgumentException('Values must not be empty.'); - } - return $column . ' IN (' . implode(', ', $values) . ')'; - } - - /** - * Returns SQL that checks if a expression is null. - * - * @param string $expression the expression that should be compared to null - * @return string logical expression - */ - public function getIsNullExpression($expression) - { - return $expression . ' IS NULL'; - } - - /** - * Returns SQL that checks if a expression is not null. - * - * @param string $expression the expression that should be compared to null - * @return string logical expression - */ - public function getIsNotNullExpression($expression) - { - return $expression . ' IS NOT NULL'; - } - - /** - * Returns SQL that checks if an expression evaluates to a value between - * two values. - * - * The parameter $expression is checked if it is between $value1 and $value2. - * - * Note: There is a slight difference in the way BETWEEN works on some databases. - * http://www.w3schools.com/sql/sql_between.asp. If you want complete database - * independence you should avoid using between(). - * - * @param string $expression the value to compare to - * @param string $value1 the lower value to compare with - * @param string $value2 the higher value to compare with - * @return string logical expression - */ - public function getBetweenExpression($expression, $value1, $value2) - { - return $expression . ' BETWEEN ' .$value1 . ' AND ' . $value2; - } - - public function getAcosExpression($value) - { - return 'ACOS(' . $value . ')'; - } - - public function getSinExpression($value) - { - return 'SIN(' . $value . ')'; - } - - public function getPiExpression() - { - return 'PI()'; - } - - public function getCosExpression($value) - { - return 'COS(' . $value . ')'; - } - - public function getForUpdateSql() - { - return 'FOR UPDATE'; - } - - public function getDropDatabaseSql($database) - { - return 'DROP DATABASE ' . $database; - } - - /** - * Drop a Table - * - * @param Table|string $table - * @return string - */ - public function getDropTableSql($table) - { - if ($table instanceof \Doctrine\DBAL\Schema\Table) { - $table = $table->getName(); - } - - return 'DROP TABLE ' . $table; - } - - /** - * Drop index from a table - * - * @param Index|string $name - * @param string|Table $table - * @return string - */ - public function getDropIndexSql($index, $table=null) - { - if($index instanceof \Doctrine\DBAL\Schema\Index) { - $index = $index->getName(); - } else if(!is_string($index)) { - throw new \InvalidArgumentException('AbstractPlatform::getDropIndexSql() expects $index parameter to be string or \Doctrine\DBAL\Schema\Index.'); - } - - return 'DROP INDEX ' . $index; - } - - /** - * Get drop constraint sql - * - * @param \Doctrine\DBAL\Schema\Constraint $constraint - * @param string|Table $table - * @return string - */ - public function getDropConstraintSql($constraint, $table) - { - if ($constraint instanceof \Doctrine\DBAL\Schema\Constraint) { - $constraint = $constraint->getName(); - } - - if ($table instanceof \Doctrine\DBAL\Schema\Table) { - $table = $table->getName(); - } - - return 'ALTER TABLE ' . $table . ' DROP CONSTRAINT ' . $constraint; - } - - /** - * @param ForeignKeyConstraint|string $foreignKey - * @param Table|string $table - * @return string - */ - public function getDropForeignKeySql($foreignKey, $table) - { - if ($foreignKey instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) { - $foreignKey = $foreignKey->getName(); - } - - if ($table instanceof \Doctrine\DBAL\Schema\Table) { - $table = $table->getName(); - } - - return 'ALTER TABLE ' . $table . ' DROP FOREIGN KEY ' . $foreignKey; - } - - /** - * Gets the SQL statement(s) to create a table with the specified name, columns and constraints - * on this platform. - * - * @param string $table The name of the table. - * @param int $createFlags - * @return array The sequence of SQL statements. - */ - public function getCreateTableSql(Table $table, $createFlags=self::CREATE_INDEXES) - { - if (!is_int($createFlags)) { - throw new \InvalidArgumentException("Second argument of AbstractPlatform::getCreateTableSql() has to be integer."); - } - - $tableName = $table->getName(); - $options = $table->getOptions(); - $options['uniqueConstraints'] = array(); - $options['indexes'] = array(); - $options['primary'] = array(); - - if (($createFlags&self::CREATE_INDEXES) > 0) { - foreach ($table->getIndexes() AS $index) { - /* @var $index Index */ - if ($index->isPrimary()) { - $options['primary'] = $index->getColumns(); - } else { - $options['indexes'][$index->getName()] = $index; - } - } - } - - $columns = array(); - foreach ($table->getColumns() AS $column) { - /* @var \Doctrine\DBAL\Schema\Column $column */ - $columnData = array(); - $columnData['name'] = $column->getName(); - $columnData['type'] = $column->getType(); - $columnData['length'] = $column->getLength(); - $columnData['notnull'] = $column->getNotNull(); - $columnData['unique'] = ($column->hasPlatformOption("unique"))?$column->getPlatformOption('unique'):false; - $columnData['version'] = ($column->hasPlatformOption("version"))?$column->getPlatformOption('version'):false; - if(strtolower($columnData['type']) == "string" && $columnData['length'] === null) { - $columnData['length'] = 255; - } - $columnData['precision'] = $column->getPrecision(); - $columnData['scale'] = $column->getScale(); - $columnData['default'] = $column->getDefault(); - // TODO: Fixed? Unsigned? - - if(in_array($column->getName(), $options['primary'])) { - $columnData['primary'] = true; - - if($table->isIdGeneratorIdentity()) { - $columnData['autoincrement'] = true; - } - } - - $columns[$columnData['name']] = $columnData; - } - - if (($createFlags&self::CREATE_FOREIGNKEYS) > 0) { - $options['foreignKeys'] = array(); - foreach ($table->getForeignKeys() AS $fkConstraint) { - $options['foreignKeys'][] = $fkConstraint; - } - } - - return $this->_getCreateTableSql($tableName, $columns, $options); - } - - /** - * @param string $tableName - * @param array $columns - * @param array $options - * @return array - */ - protected function _getCreateTableSql($tableName, array $columns, array $options = array()) - { - $columnListSql = $this->getColumnDeclarationListSql($columns); - - if (isset($options['uniqueConstraints']) && ! empty($options['uniqueConstraints'])) { - foreach ($options['uniqueConstraints'] as $name => $definition) { - $columnListSql .= ', ' . $this->getUniqueConstraintDeclarationSql($name, $definition); - } - } - - if (isset($options['primary']) && ! empty($options['primary'])) { - $columnListSql .= ', PRIMARY KEY(' . implode(', ', array_unique(array_values($options['primary']))) . ')'; - } - - if (isset($options['indexes']) && ! empty($options['indexes'])) { - foreach($options['indexes'] as $index => $definition) { - $columnListSql .= ', ' . $this->getIndexDeclarationSql($index, $definition); - } - } - - $query = 'CREATE TABLE ' . $tableName . ' (' . $columnListSql; - - $check = $this->getCheckDeclarationSql($columns); - if ( ! empty($check)) { - $query .= ', ' . $check; - } - $query .= ')'; - - $sql[] = $query; - - if (isset($options['foreignKeys'])) { - foreach ((array) $options['foreignKeys'] AS $definition) { - $sql[] = $this->getCreateForeignKeySql($definition, $tableName); - } - } - - return $sql; - } - - public function getCreateTemporaryTableSnippetSql() - { - return "CREATE TEMPORARY TABLE"; - } - - /** - * Gets the SQL to create a sequence on this platform. - * - * @param \Doctrine\DBAL\Schema\Sequence $sequence - * @throws DoctrineException - */ - public function getCreateSequenceSql(\Doctrine\DBAL\Schema\Sequence $sequence) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Gets the SQL to create a constraint on a table on this platform. - * - * @param Constraint $constraint - * @param string|Table $table - * @return string - */ - public function getCreateConstraintSql(\Doctrine\DBAL\Schema\Constraint $constraint, $table) - { - if ($table instanceof \Doctrine\DBAL\Schema\Table) { - $table = $table->getName(); - } - - $query = 'ALTER TABLE ' . $table . ' ADD CONSTRAINT ' . $constraint->getName(); - - $columns = array(); - foreach ($constraint->getColumns() as $column) { - $columns[] = $column; - } - $columnList = '('. implode(', ', $columns) . ')'; - - $referencesClause = ''; - if ($constraint instanceof \Doctrine\DBAL\Schema\Index) { - if($constraint->isPrimary()) { - $query .= ' PRIMARY KEY'; - } elseif ($constraint->isUnique()) { - $query .= ' UNIQUE'; - } else { - throw new \InvalidArgumentException( - 'Can only create primary or unique constraints, no common indexes with getCreateConstraintSql().' - ); - } - } else if ($constraint instanceof \Doctrine\DBAL\Schema\ForeignKeyConstraint) { - $query .= ' FOREIGN KEY'; - - $foreignColumns = array(); - foreach ($constraint->getForeignColumns() AS $column) { - $foreignColumns[] = $column; - } - - $referencesClause = ' REFERENCES '.$constraint->getForeignTableName(). ' ('.implode(', ', $foreignColumns).')'; - } - $query .= ' '.$columnList.$referencesClause; - - return $query; - } - - /** - * Gets the SQL to create an index on a table on this platform. - * - * @param Index $index - * @param string|Table $table name of the table on which the index is to be created - * @return string - */ - public function getCreateIndexSql(Index $index, $table) - { - if ($table instanceof Table) { - $table = $table->getName(); - } - $name = $index->getName(); - $columns = $index->getColumns(); - - if (count($columns) == 0) { - throw new \InvalidArgumentException("Incomplete definition. 'columns' required."); - } - - $type = ''; - if ($index->isUnique()) { - $type = 'UNIQUE '; - } - - $query = 'CREATE ' . $type . 'INDEX ' . $name . ' ON ' . $table; - - $query .= ' (' . $this->getIndexFieldDeclarationListSql($columns) . ')'; - - return $query; - } - - /** - * Quotes a string so that it can be safely used as a table or column name, - * even if it is a reserved word of the platform. - * - * NOTE: Just because you CAN use quoted identifiers doesn't mean - * you SHOULD use them. In general, they end up causing way more - * problems than they solve. - * - * @param string $str identifier name to be quoted - * @return string quoted identifier string - */ - public function quoteIdentifier($str) - { - $c = $this->getIdentifierQuoteCharacter(); - - return $c . $str . $c; - } - - /** - * Create a new foreign key - * - * @param ForeignKeyConstraint $foreignKey ForeignKey instance - * @param string|Table $table name of the table on which the foreign key is to be created - * @return string - */ - public function getCreateForeignKeySql(ForeignKeyConstraint $foreignKey, $table) - { - if ($table instanceof \Doctrine\DBAL\Schema\Table) { - $table = $table->getName(); - } - - $query = 'ALTER TABLE ' . $table . ' ADD ' . $this->getForeignKeyDeclarationSql($foreignKey); - - return $query; - } - - /** - * Gets the sql statements for altering an existing table. - * - * The method returns an array of sql statements, since some platforms need several statements. - * - * @param TableDiff $diff - * @return array - */ - public function getAlterTableSql(TableDiff $diff) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Common code for alter table statement generation that updates the changed Index and Foreign Key definitions. - * - * @param TableDiff $diff - * @return array - */ - protected function _getAlterTableIndexForeignKeySql(TableDiff $diff) - { - if ($diff->newName !== false) { - $tableName = $diff->newName; - } else { - $tableName = $diff->name; - } - - $sql = array(); - if ($this->supportsForeignKeyConstraints()) { - foreach ($diff->addedForeignKeys AS $foreignKey) { - $sql[] = $this->getCreateForeignKeySql($foreignKey, $tableName); - } - foreach ($diff->removedForeignKeys AS $foreignKey) { - $sql[] = $this->getDropForeignKeySql($foreignKey, $tableName); - } - foreach ($diff->changedForeignKeys AS $foreignKey) { - $sql[] = $this->getDropForeignKeySql($foreignKey, $tableName); - $sql[] = $this->getCreateForeignKeySql($foreignKey, $tableName); - } - } - - foreach ($diff->addedIndexes AS $index) { - $sql[] = $this->getCreateIndexSql($index, $tableName); - } - foreach ($diff->removedIndexes AS $index) { - $sql[] = $this->getDropIndexSql($index, $tableName); - } - foreach ($diff->changedIndexes AS $index) { - $sql[] = $this->getDropIndexSql($index, $tableName); - $sql[] = $this->getCreateIndexSql($index, $tableName); - } - - return $sql; - } - - /** - * Get declaration of a number of fields in bulk - * - * @param array $fields a multidimensional associative array. - * The first dimension determines the field name, while the second - * dimension is keyed with the name of the properties - * of the field being declared as array indexes. Currently, the types - * of supported field properties are as follows: - * - * length - * Integer value that determines the maximum length of the text - * field. If this argument is missing the field should be - * declared to have the longest length allowed by the DBMS. - * - * default - * Text value to be used as default for this field. - * - * notnull - * Boolean flag that indicates whether this field is constrained - * to not be set to null. - * charset - * Text value with the default CHARACTER SET for this field. - * collation - * Text value with the default COLLATION for this field. - * unique - * unique constraint - * - * @return string - */ - public function getColumnDeclarationListSql(array $fields) - { - $queryFields = array(); - foreach ($fields as $fieldName => $field) { - $query = $this->getColumnDeclarationSql($fieldName, $field); - $queryFields[] = $query; - } - return implode(', ', $queryFields); - } - - /** - * Obtain DBMS specific SQL code portion needed to declare a generic type - * field to be used in statements like CREATE TABLE. - * - * @param string $name name the field to be declared. - * @param array $field associative array with the name of the properties - * of the field being declared as array indexes. Currently, the types - * of supported field properties are as follows: - * - * length - * Integer value that determines the maximum length of the text - * field. If this argument is missing the field should be - * declared to have the longest length allowed by the DBMS. - * - * default - * Text value to be used as default for this field. - * - * notnull - * Boolean flag that indicates whether this field is constrained - * to not be set to null. - * charset - * Text value with the default CHARACTER SET for this field. - * collation - * Text value with the default COLLATION for this field. - * unique - * unique constraint - * check - * column check constraint - * - * @return string DBMS specific SQL code portion that should be used to declare the column. - */ - public function getColumnDeclarationSql($name, array $field) - { - $default = $this->getDefaultValueDeclarationSql($field); - - $charset = (isset($field['charset']) && $field['charset']) ? - ' ' . $this->getColumnCharsetDeclarationSql($field['charset']) : ''; - - $collation = (isset($field['collation']) && $field['collation']) ? - ' ' . $this->getColumnCollationDeclarationSql($field['collation']) : ''; - - $notnull = (isset($field['notnull']) && $field['notnull']) ? ' NOT NULL' : ''; - - $unique = (isset($field['unique']) && $field['unique']) ? - ' ' . $this->getUniqueFieldDeclarationSql() : ''; - - $check = (isset($field['check']) && $field['check']) ? - ' ' . $field['check'] : ''; - - $typeDecl = $field['type']->getSqlDeclaration($field, $this); - - return $name . ' ' . $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; - } - - /** - * Gets the SQL snippet that declares a floating point column of arbitrary precision. - * - * @param array $columnDef - * @return string - */ - public function getDecimalTypeDeclarationSql(array $columnDef) - { - $columnDef['precision'] = ( ! isset($columnDef['precision']) || empty($columnDef['precision'])) - ? 10 : $columnDef['precision']; - $columnDef['scale'] = ( ! isset($columnDef['scale']) || empty($columnDef['scale'])) - ? 0 : $columnDef['scale']; - - return 'NUMERIC(' . $columnDef['precision'] . ', ' . $columnDef['scale'] . ')'; - } - - /** - * Gets the SQL snippet that declares a boolean column. - * - * @param array $columnDef - * @return string - */ - abstract public function getBooleanTypeDeclarationSql(array $columnDef); - - /** - * Gets the SQL snippet that declares a 4 byte integer column. - * - * @param array $columnDef - * @return string - */ - abstract public function getIntegerTypeDeclarationSql(array $columnDef); - - /** - * Gets the SQL snippet that declares an 8 byte integer column. - * - * @param array $columnDef - * @return string - */ - abstract public function getBigIntTypeDeclarationSql(array $columnDef); - - /** - * Gets the SQL snippet that declares a 2 byte integer column. - * - * @param array $columnDef - * @return string - */ - abstract public function getSmallIntTypeDeclarationSql(array $columnDef); - - /** - * Gets the SQL snippet that declares common properties of an integer column. - * - * @param array $columnDef - * @return string - */ - abstract protected function _getCommonIntegerTypeDeclarationSql(array $columnDef); - - /** - * Obtain DBMS specific SQL code portion needed to set a default value - * declaration to be used in statements like CREATE TABLE. - * - * @param array $field field definition array - * @return string DBMS specific SQL code portion needed to set a default value - */ - public function getDefaultValueDeclarationSql($field) - { - $default = empty($field['notnull']) ? ' DEFAULT NULL' : ''; - - if (isset($field['default'])) { - $default = " DEFAULT '".$field['default']."'"; - if (isset($field['type'])) { - if (in_array((string)$field['type'], array("Integer", "BigInteger", "SmallInteger"))) { - $default = " DEFAULT ".$field['default']; - } else if ((string)$field['type'] == 'DateTime' && $field['default'] == $this->getCurrentTimestampSql()) { - $default = " DEFAULT ".$this->getCurrentTimestampSql(); - } - } - } - return $default; - } - - /** - * Obtain DBMS specific SQL code portion needed to set a CHECK constraint - * declaration to be used in statements like CREATE TABLE. - * - * @param array $definition check definition - * @return string DBMS specific SQL code portion needed to set a CHECK constraint - */ - public function getCheckDeclarationSql(array $definition) - { - $constraints = array(); - foreach ($definition as $field => $def) { - if (is_string($def)) { - $constraints[] = 'CHECK (' . $def . ')'; - } else { - if (isset($def['min'])) { - $constraints[] = 'CHECK (' . $field . ' >= ' . $def['min'] . ')'; - } - - if (isset($def['max'])) { - $constraints[] = 'CHECK (' . $field . ' <= ' . $def['max'] . ')'; - } - } - } - - return implode(', ', $constraints); - } - - /** - * Obtain DBMS specific SQL code portion needed to set a unique - * constraint declaration to be used in statements like CREATE TABLE. - * - * @param string $name name of the unique constraint - * @param Index $index index definition - * @return string DBMS specific SQL code portion needed - * to set a constraint - */ - public function getUniqueConstraintDeclarationSql($name, Index $index) - { - if (count($index->getColumns()) == 0) { - throw \InvalidArgumentException("Incomplete definition. 'columns' required."); - } - - return 'CONSTRAINT' . $name . ' UNIQUE (' - . $this->getIndexFieldDeclarationListSql($index->getColumns()) - . ')'; - } - - /** - * Obtain DBMS specific SQL code portion needed to set an index - * declaration to be used in statements like CREATE TABLE. - * - * @param string $name name of the index - * @param Index $index index definition - * @return string DBMS specific SQL code portion needed to set an index - */ - public function getIndexDeclarationSql($name, Index $index) - { - $type = ''; - - if($index->isUnique()) { - $type = 'UNIQUE '; - } - - if (count($index->getColumns()) == 0) { - throw \InvalidArgumentException("Incomplete definition. 'columns' required."); - } - - return $type . 'INDEX ' . $name . ' (' - . $this->getIndexFieldDeclarationListSql($index->getColumns()) - . ')'; - } - - /** - * getIndexFieldDeclarationList - * Obtain DBMS specific SQL code portion needed to set an index - * declaration to be used in statements like CREATE TABLE. - * - * @return string - */ - public function getIndexFieldDeclarationListSql(array $fields) - { - $ret = array(); - foreach ($fields as $field => $definition) { - if (is_array($definition)) { - $ret[] = $field; - } else { - $ret[] = $definition; - } - } - return implode(', ', $ret); - } - - /** - * A method to return the required SQL string that fits between CREATE ... TABLE - * to create the table as a temporary table. - * - * Should be overridden in driver classes to return the correct string for the - * specific database type. - * - * The default is to return the string "TEMPORARY" - this will result in a - * SQL error for any database that does not support temporary tables, or that - * requires a different SQL command from "CREATE TEMPORARY TABLE". - * - * @return string The string required to be placed between "CREATE" and "TABLE" - * to generate a temporary table, if possible. - */ - public function getTemporaryTableSql() - { - return 'TEMPORARY'; - } - - /** - * Get sql query to show a list of database - * - * @return unknown - */ - public function getShowDatabasesSql() - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * getForeignKeyDeclaration - * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint - * of a field declaration to be used in statements like CREATE TABLE. - * - * @param array $definition an associative array with the following structure: - * name optional constraint name - * - * local the local field(s) - * - * foreign the foreign reference field(s) - * - * foreignTable the name of the foreign table - * - * onDelete referential delete action - * - * onUpdate referential update action - * - * deferred deferred constraint checking - * - * The onDelete and onUpdate keys accept the following values: - * - * CASCADE: Delete or update the row from the parent table and automatically delete or - * update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported. - * Between two tables, you should not define several ON UPDATE CASCADE clauses that act on the same column - * in the parent table or in the child table. - * - * SET NULL: Delete or update the row from the parent table and set the foreign key column or columns in the - * child table to NULL. This is valid only if the foreign key columns do not have the NOT NULL qualifier - * specified. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported. - * - * NO ACTION: In standard SQL, NO ACTION means no action in the sense that an attempt to delete or update a primary - * key value is not allowed to proceed if there is a related foreign key value in the referenced table. - * - * RESTRICT: Rejects the delete or update operation for the parent table. NO ACTION and RESTRICT are the same as - * omitting the ON DELETE or ON UPDATE clause. - * - * SET DEFAULT - * - * @return string DBMS specific SQL code portion needed to set the FOREIGN KEY constraint - * of a field declaration. - */ - public function getForeignKeyDeclarationSql(ForeignKeyConstraint $foreignKey) - { - $sql = $this->getForeignKeyBaseDeclarationSql($foreignKey); - $sql .= $this->getAdvancedForeignKeyOptionsSql($foreignKey); - - return $sql; - } - - /** - * Return the FOREIGN KEY query section dealing with non-standard options - * as MATCH, INITIALLY DEFERRED, ON UPDATE, ... - * - * @param ForeignKeyConstraint $foreignKey foreign key definition - * @return string - */ - public function getAdvancedForeignKeyOptionsSql(ForeignKeyConstraint $foreignKey) - { - $query = ''; - if ($this->supportsForeignKeyOnUpdate() && $foreignKey->hasOption('onUpdate')) { - $query .= ' ON UPDATE ' . $this->getForeignKeyReferentialActionSql($foreignKey->getOption('onUpdate')); - } - if ($foreignKey->hasOption('onDelete')) { - $query .= ' ON DELETE ' . $this->getForeignKeyReferentialActionSql($foreignKey->getOption('onDelete')); - } - return $query; - } - - /** - * returns given referential action in uppercase if valid, otherwise throws - * an exception - * - * @throws Doctrine_Exception_Exception if unknown referential action given - * @param string $action foreign key referential action - * @param string foreign key referential action in uppercase - */ - public function getForeignKeyReferentialActionSql($action) - { - $upper = strtoupper($action); - switch ($upper) { - case 'CASCADE': - case 'SET NULL': - case 'NO ACTION': - case 'RESTRICT': - case 'SET DEFAULT': - return $upper; - break; - default: - throw \InvalidArgumentException('Invalid foreign key action: ' . $upper); - } - } - - /** - * Obtain DBMS specific SQL code portion needed to set the FOREIGN KEY constraint - * of a field declaration to be used in statements like CREATE TABLE. - * - * @param ForeignKeyConstraint $foreignKey - * @return string - */ - public function getForeignKeyBaseDeclarationSql(ForeignKeyConstraint $foreignKey) - { - $sql = ''; - if (strlen($foreignKey->getName())) { - $sql .= 'CONSTRAINT ' . $foreignKey->getName() . ' '; - } - $sql .= 'FOREIGN KEY ('; - - if (count($foreignKey->getLocalColumns()) == 0) { - throw new \InvalidArgumentException("Incomplete definition. 'local' required."); - } - if (count($foreignKey->getForeignColumns()) == 0) { - throw new \InvalidArgumentException("Incomplete definition. 'foreign' required."); - } - if (strlen($foreignKey->getForeignTableName()) == 0) { - throw new \InvalidArgumentException("Incomplete definition. 'foreignTable' required."); - } - - $sql .= implode(', ', $foreignKey->getLocalColumns()) - . ') REFERENCES ' - . $foreignKey->getForeignTableName() . '(' - . implode(', ', $foreignKey->getForeignColumns()) . ')'; - - return $sql; - } - - /** - * Obtain DBMS specific SQL code portion needed to set the UNIQUE constraint - * of a field declaration to be used in statements like CREATE TABLE. - * - * @return string DBMS specific SQL code portion needed to set the UNIQUE constraint - * of a field declaration. - */ - public function getUniqueFieldDeclarationSql() - { - return 'UNIQUE'; - } - - /** - * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET - * of a field declaration to be used in statements like CREATE TABLE. - * - * @param string $charset name of the charset - * @return string DBMS specific SQL code portion needed to set the CHARACTER SET - * of a field declaration. - */ - public function getColumnCharsetDeclarationSql($charset) - { - return ''; - } - - /** - * Obtain DBMS specific SQL code portion needed to set the COLLATION - * of a field declaration to be used in statements like CREATE TABLE. - * - * @param string $collation name of the collation - * @return string DBMS specific SQL code portion needed to set the COLLATION - * of a field declaration. - */ - public function getColumnCollationDeclarationSql($collation) - { - return ''; - } - - /** - * build a pattern matching string - * - * EXPERIMENTAL - * - * WARNING: this function is experimental and may change signature at - * any time until labelled as non-experimental - * - * @access public - * - * @param array $pattern even keys are strings, odd are patterns (% and _) - * @param string $operator optional pattern operator (LIKE, ILIKE and maybe others in the future) - * @param string $field optional field name that is being matched against - * (might be required when emulating ILIKE) - * - * @return string SQL pattern - */ - public function getMatchPatternExpression($pattern, $operator = null, $field = null) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Whether the platform prefers sequences for ID generation. - * Subclasses should override this method to return TRUE if they prefer sequences. - * - * @return boolean - */ - public function prefersSequences() - { - return false; - } - - /** - * Whether the platform prefers identity columns (eg. autoincrement) for ID generation. - * Subclasses should override this method to return TRUE if they prefer identity columns. - * - * @return boolean - */ - public function prefersIdentityColumns() - { - return false; - } - - /** - * Some platforms need the boolean values to be converted. - * - * The default conversion in this implementation converts to integers (false => 0, true => 1). - * - * @param mixed $item - */ - public function convertBooleans($item) - { - if (is_array($item)) { - foreach ($item as $k => $value) { - if (is_bool($value)) { - $item[$k] = (int) $value; - } - } - } else if (is_bool($item)) { - $item = (int) $item; - } - return $item; - } - - /** - * Gets the SQL statement specific for the platform to set the charset. - * - * This function is MySQL specific and required by - * {@see \Doctrine\DBAL\Connection::setCharset($charset)} - * - * @param string $charset - * @return string - */ - public function getSetCharsetSql($charset) - { - return "SET NAMES '".$charset."'"; - } - - /** - * Gets the SQL specific for the platform to get the current date. - * - * @return string - */ - public function getCurrentDateSql() - { - return 'CURRENT_DATE'; - } - - /** - * Gets the SQL specific for the platform to get the current time. - * - * @return string - */ - public function getCurrentTimeSql() - { - return 'CURRENT_TIME'; - } - - /** - * Gets the SQL specific for the platform to get the current timestamp - * - * @return string - */ - public function getCurrentTimestampSql() - { - return 'CURRENT_TIMESTAMP'; - } - - /** - * Get sql for transaction isolation level Connection constant - * - * @param integer $level - */ - protected function _getTransactionIsolationLevelSql($level) - { - switch ($level) { - case Connection::TRANSACTION_READ_UNCOMMITTED: - return 'READ UNCOMMITTED'; - case Connection::TRANSACTION_READ_COMMITTED: - return 'READ COMMITTED'; - case Connection::TRANSACTION_REPEATABLE_READ: - return 'REPEATABLE READ'; - case Connection::TRANSACTION_SERIALIZABLE: - return 'SERIALIZABLE'; - default: - throw new \InvalidArgumentException('Invalid isolation level:' . $level); - } - } - - public function getListDatabasesSql() - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListFunctionsSql() - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListTriggersSql($table = null) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListSequencesSql($database) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListTableConstraintsSql($table) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListTableColumnsSql($table) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListTablesSql() - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListUsersSql() - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListViewsSql() - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListTableIndexesSql($table) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getListTableForeignKeysSql($table) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getCreateViewSql($name, $sql) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getDropViewSql($name) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getDropSequenceSql($sequence) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getSequenceNextValSql($sequenceName) - { - throw DBALException::notSupported(__METHOD__); - } - - public function getCreateDatabaseSql($database) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Get sql to set the transaction isolation level - * - * @param integer $level - */ - public function getSetTransactionIsolationSql($level) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Obtain DBMS specific SQL code portion needed to set the CHARACTER SET - * of a field declaration to be used in statements like CREATE TABLE. - * - * @param string $charset name of the charset - * @return string DBMS specific SQL code portion needed to set the CHARACTER SET - * of a field declaration. - */ - public function getCharsetFieldDeclaration($charset) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Obtain DBMS specific SQL to be used to create datetime fields in - * statements like CREATE TABLE - * - * @param array $fieldDeclaration - * @return string - */ - public function getDateTimeTypeDeclarationSql(array $fieldDeclaration) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Obtain DBMS specific SQL to be used to create date fields in statements - * like CREATE TABLE. - * - * @param array $fieldDeclaration - * @return string - */ - public function getDateTypeDeclarationSql(array $fieldDeclaration) - { - throw DBALException::notSupported(__METHOD__); - } - - /** - * Obtain DBMS specific SQL to be used to create time fields in statements - * like CREATE TABLE. - * - * @param array $fieldDeclaration - * @return string - */ - public function getTimeTypeDeclarationSql(array $fieldDeclaration) - { - throw DoctrineException::getTimeTypeDeclarationNotSupported($this); - } - - /** - * Gets the default transaction isolation level of the platform. - * - * @return integer The default isolation level. - * @see Doctrine\DBAL\Connection\TRANSACTION_* constants. - */ - public function getDefaultTransactionIsolationLevel() - { - return Connection::TRANSACTION_READ_COMMITTED; - } - - /* supports*() metods */ - - /** - * Whether the platform supports sequences. - * - * @return boolean - */ - public function supportsSequences() - { - return false; - } - - /** - * Whether the platform supports identity columns. - * Identity columns are columns that recieve an auto-generated value from the - * database on insert of a row. - * - * @return boolean - */ - public function supportsIdentityColumns() - { - return false; - } - - /** - * Whether the platform supports indexes. - * - * @return boolean - */ - public function supportsIndexes() - { - return true; - } - - public function supportsAlterTable() - { - return true; - } - - /** - * Whether the platform supports transactions. - * - * @return boolean - */ - public function supportsTransactions() - { - return true; - } - - /** - * Whether the platform supports savepoints. - * - * @return boolean - */ - public function supportsSavepoints() - { - return true; - } - - /** - * Whether the platform supports primary key constraints. - * - * @return boolean - */ - public function supportsPrimaryConstraints() - { - return true; - } - - /** - * Does the platform supports foreign key constraints? - * - * @return boolean - */ - public function supportsForeignKeyConstraints() - { - return true; - } - - /** - * Does this platform supports onUpdate in foreign key constraints? - * - * @return bool - */ - public function supportsForeignKeyOnUpdate() - { - return ($this->supportsForeignKeyConstraints() && true); - } - - /** - * Whether the platform supports database schemas. - * - * @return boolean - */ - public function supportsSchemas() - { - return false; - } - - /** - * @return bool - */ - public function createsExplicitIndexForForeignKeys() - { - return false; - } - - /** - * Whether the platform supports getting the affected rows of a recent - * update/delete type query. - * - * @return boolean - */ - public function supportsGettingAffectedRows() - { - return true; - } - - public function getIdentityColumnNullInsertSql() - { - return ""; - } - - /** - * Gets the format string, as accepted by the date() function, that describes - * the format of a stored datetime value of this platform. - * - * @return string The format string. - * - * @todo We need to get the specific format for each dbms and override this - * function for each platform - */ - public function getDateTimeFormatString() - { - return 'Y-m-d H:i:s'; - } - - /** - * Gets the format string, as accepted by the date() function, that describes - * the format of a stored date value of this platform. - * - * @return string The format string. - */ - public function getDateFormatString() - { - return 'Y-m-d'; - } - - /** - * Gets the format string, as accepted by the date() function, that describes - * the format of a stored time value of this platform. - * - * @return string The format string. - */ - public function getTimeFormatString() - { - return 'H:i:s'; - } - - public function modifyLimitQuery($query, $limit, $offset = null) - { - if ( ! is_null($limit)) { - $query .= ' LIMIT ' . $limit; - } - - if ( ! is_null($offset)) { - $query .= ' OFFSET ' . $offset; - } - - return $query; - } - - /** - * Gets the SQL snippet used to declare a VARCHAR column type. - * - * @param array $field - */ - abstract public function getVarcharTypeDeclarationSql(array $field); - - /** - * Gets the SQL snippet used to declare a CLOB column type. - * - * @param array $field - */ - abstract public function getClobTypeDeclarationSql(array $field); - - /** - * Gets the name of the platform. - * - * @return string - */ - abstract public function getName(); - - /** - * Gets the character casing of a column in an SQL result set of this platform. - * - * @param string $column The column name for which to get the correct character casing. - * @return string The column name in the character casing used in SQL result sets. - */ - public function getSqlResultCasing($column) - { - return $column; - } - - /** - * Makes any fixes to a name of a schema element (table, sequence, ...) that are required - * by restrictions of the platform, like a maximum length. - * - * @param string $schemaName - * @return string - */ - public function fixSchemaElementName($schemaElementName) - { - return $schemaElementName; - } - - /** - * Maximum length of any given databse identifier, like tables or column names. - * - * @return int - */ - public function getMaxIdentifierLength() - { - return 63; - } - - /** - * Get the insert sql for an empty insert statement - * - * @param string $tableName - * @param string $identifierColumnName - * @return string $sql - */ - public function getEmptyIdentityInsertSql($tableName, $identifierColumnName) - { - return 'INSERT INTO ' . $tableName . ' (' . $identifierColumnName . ') VALUES (null)'; - } -} diff --git a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php.orig b/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php.orig deleted file mode 100644 index 249ffa2f0..000000000 --- a/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php.orig +++ /dev/null @@ -1,374 +0,0 @@ -. - */ - -namespace Doctrine\ORM\Mapping\Driver; - -use Doctrine\Common\DoctrineException, - Doctrine\Common\Cache\ArrayCache, - Doctrine\Common\Annotations\AnnotationReader, - Doctrine\ORM\Mapping\ClassMetadataInfo, - Doctrine\ORM\Mapping\MappingException; - -require __DIR__ . '/DoctrineAnnotations.php'; - -/** - * The AnnotationDriver reads the mapping metadata from docblock annotations. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision$ - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - */ -class AnnotationDriver implements Driver -{ - /** The AnnotationReader. */ - private $_reader; - private $_classDirectory; - - /** - * Initializes a new AnnotationDriver that uses the given AnnotationReader for reading - * docblock annotations. - * - * @param AnnotationReader $reader The AnnotationReader to use. - */ - public function __construct(AnnotationReader $reader, $classDirectory = null) - { - $this->_reader = $reader; - $this->_classDirectory = $classDirectory; - } - - public function setClassDirectory($classDirectory) - { - $this->_classDirectory = $classDirectory; - } - - /** - * {@inheritdoc} - */ - public function loadMetadataForClass($className, ClassMetadataInfo $metadata) - { - $class = $metadata->getReflectionClass(); - - $classAnnotations = $this->_reader->getClassAnnotations($class); - - // Evaluate Entity annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\Entity'])) { - $entityAnnot = $classAnnotations['Doctrine\ORM\Mapping\Entity']; - $metadata->setCustomRepositoryClass($entityAnnot->repositoryClass); - } else if (isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass'])) { - $metadata->isMappedSuperclass = true; - } else { - throw DoctrineException::classIsNotAValidEntityOrMappedSuperClass($className); - } - - // Evaluate DoctrineTable annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\Table'])) { - $tableAnnot = $classAnnotations['Doctrine\ORM\Mapping\Table']; - $primaryTable = array( - 'name' => $tableAnnot->name, - 'schema' => $tableAnnot->schema - ); - - if ($tableAnnot->indexes !== null) { - foreach ($tableAnnot->indexes as $indexAnnot) { - $primaryTable['indexes'][$indexAnnot->name] = array( - 'columns' => $indexAnnot->columns - ); - } - } - - if ($tableAnnot->uniqueConstraints !== null) { - foreach ($tableAnnot->uniqueConstraints as $uniqueConstraint) { - $primaryTable['uniqueConstraints'][$uniqueConstraint->name] = array( - 'columns' => $uniqueConstraint->columns - ); - } - } - - $metadata->setPrimaryTable($primaryTable); - } - - // Evaluate InheritanceType annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\InheritanceType'])) { - $inheritanceTypeAnnot = $classAnnotations['Doctrine\ORM\Mapping\InheritanceType']; - $metadata->setInheritanceType(constant('\Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . $inheritanceTypeAnnot->value)); - } - - // Evaluate DiscriminatorColumn annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn'])) { - $discrColumnAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorColumn']; - $metadata->setDiscriminatorColumn(array( - 'name' => $discrColumnAnnot->name, - 'type' => $discrColumnAnnot->type, - 'length' => $discrColumnAnnot->length - )); - } - - // Evaluate DiscriminatorMap annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap'])) { - $discrMapAnnot = $classAnnotations['Doctrine\ORM\Mapping\DiscriminatorMap']; - $metadata->setDiscriminatorMap($discrMapAnnot->value); - } - - // Evaluate DoctrineChangeTrackingPolicy annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy'])) { - $changeTrackingAnnot = $classAnnotations['Doctrine\ORM\Mapping\ChangeTrackingPolicy']; - $metadata->setChangeTrackingPolicy($changeTrackingAnnot->value); - } - - // Evaluate annotations on properties/fields - foreach ($class->getProperties() as $property) { - if ($metadata->isMappedSuperclass && ! $property->isPrivate() - || - $metadata->isInheritedField($property->name) - || - $metadata->isInheritedAssociation($property->name)) { - continue; - } - - $mapping = array(); - $mapping['fieldName'] = $property->getName(); - - // Check for JoinColummn/JoinColumns annotations - $joinColumns = array(); - - if ($joinColumnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumn')) { - $joinColumns[] = array( - 'name' => $joinColumnAnnot->name, - 'referencedColumnName' => $joinColumnAnnot->referencedColumnName, - 'unique' => $joinColumnAnnot->unique, - 'nullable' => $joinColumnAnnot->nullable, - 'onDelete' => $joinColumnAnnot->onDelete, - 'onUpdate' => $joinColumnAnnot->onUpdate - ); - } else if ($joinColumnsAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinColumns')) { - foreach ($joinColumnsAnnot->value as $joinColumn) { - $joinColumns[] = array( - 'name' => $joinColumn->name, - 'referencedColumnName' => $joinColumn->referencedColumnName, - 'unique' => $joinColumn->unique, - 'nullable' => $joinColumn->nullable, - 'onDelete' => $joinColumn->onDelete, - 'onUpdate' => $joinColumn->onUpdate - ); - } - } - - // Field can only be annotated with one of: - // @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany - if ($columnAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Column')) { - if ($columnAnnot->type == null) { - throw DoctrineException::propertyTypeIsRequired($property->getName()); - } - - $mapping['type'] = $columnAnnot->type; - $mapping['length'] = $columnAnnot->length; - $mapping['precision'] = $columnAnnot->precision; - $mapping['scale'] = $columnAnnot->scale; - $mapping['nullable'] = $columnAnnot->nullable; - $mapping['unique'] = $columnAnnot->unique; - if ($columnAnnot->options) { - $mapping['options'] = $columnAnnot->options; - } - - if (isset($columnAnnot->default)) { - $mapping['default'] = $columnAnnot->default; - } - - if (isset($columnAnnot->name)) { - $mapping['columnName'] = $columnAnnot->name; - } - - if ($idAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Id')) { - $mapping['id'] = true; - } - - if ($generatedValueAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\GeneratedValue')) { - $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' . $generatedValueAnnot->strategy)); - } - - if ($versionAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\Version')) { - $metadata->setVersionMapping($mapping); - } - - $metadata->mapField($mapping); - - // Check for SequenceGenerator/TableGenerator definition - if ($seqGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\SequenceGenerator')) { - $metadata->setSequenceGeneratorDefinition(array( - 'sequenceName' => $seqGeneratorAnnot->sequenceName, - 'allocationSize' => $seqGeneratorAnnot->allocationSize, - 'initialValue' => $seqGeneratorAnnot->initialValue - )); - } else if ($tblGeneratorAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\TableGenerator')) { - throw DoctrineException::tableIdGeneratorNotImplemented(); - } - } else if ($oneToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToOne')) { - $mapping['targetEntity'] = $oneToOneAnnot->targetEntity; - $mapping['joinColumns'] = $joinColumns; - $mapping['mappedBy'] = $oneToOneAnnot->mappedBy; - $mapping['cascade'] = $oneToOneAnnot->cascade; - $mapping['orphanRemoval'] = $oneToOneAnnot->orphanRemoval; - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $oneToOneAnnot->fetch); - $metadata->mapOneToOne($mapping); - } else if ($oneToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\OneToMany')) { - $mapping['mappedBy'] = $oneToManyAnnot->mappedBy; - $mapping['targetEntity'] = $oneToManyAnnot->targetEntity; - $mapping['cascade'] = $oneToManyAnnot->cascade; - $mapping['orphanRemoval'] = $oneToManyAnnot->orphanRemoval; - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $oneToManyAnnot->fetch); - $metadata->mapOneToMany($mapping); - } else if ($manyToOneAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToOne')) { - $mapping['joinColumns'] = $joinColumns; - $mapping['cascade'] = $manyToOneAnnot->cascade; - $mapping['targetEntity'] = $manyToOneAnnot->targetEntity; - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToOneAnnot->fetch); - $metadata->mapManyToOne($mapping); - } else if ($manyToManyAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\ManyToMany')) { - $joinTable = array(); - - if ($joinTableAnnot = $this->_reader->getPropertyAnnotation($property, 'Doctrine\ORM\Mapping\JoinTable')) { - $joinTable = array( - 'name' => $joinTableAnnot->name, - 'schema' => $joinTableAnnot->schema - ); - - foreach ($joinTableAnnot->joinColumns as $joinColumn) { - $joinTable['joinColumns'][] = array( - 'name' => $joinColumn->name, - 'referencedColumnName' => $joinColumn->referencedColumnName, - 'unique' => $joinColumn->unique, - 'nullable' => $joinColumn->nullable, - 'onDelete' => $joinColumn->onDelete, - 'onUpdate' => $joinColumn->onUpdate - ); - } - - foreach ($joinTableAnnot->inverseJoinColumns as $joinColumn) { - $joinTable['inverseJoinColumns'][] = array( - 'name' => $joinColumn->name, - 'referencedColumnName' => $joinColumn->referencedColumnName, - 'unique' => $joinColumn->unique, - 'nullable' => $joinColumn->nullable, - 'onDelete' => $joinColumn->onDelete, - 'onUpdate' => $joinColumn->onUpdate - ); - } - } - - $mapping['joinTable'] = $joinTable; - $mapping['targetEntity'] = $manyToManyAnnot->targetEntity; - $mapping['mappedBy'] = $manyToManyAnnot->mappedBy; - $mapping['cascade'] = $manyToManyAnnot->cascade; - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToManyAnnot->fetch); - $metadata->mapManyToMany($mapping); - } - } - - // Evaluate HasLifecycleCallbacks annotation - if (isset($classAnnotations['Doctrine\ORM\Mapping\HasLifecycleCallbacks'])) { - foreach ($class->getMethods() as $method) { - if ($method->isPublic()) { - $annotations = $this->_reader->getMethodAnnotations($method); - - if (isset($annotations['Doctrine\ORM\Mapping\PrePersist'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::prePersist); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostPersist'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postPersist); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PreUpdate'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preUpdate); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostUpdate'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postUpdate); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PreRemove'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::preRemove); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostRemove'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postRemove); - } - - if (isset($annotations['Doctrine\ORM\Mapping\PostLoad'])) { - $metadata->addLifecycleCallback($method->getName(), \Doctrine\ORM\Events::postLoad); - } - } - } - } - } - - /** - * Whether the class with the specified name should have its metadata loaded. - * This is only the case if it is annotated with either @Entity or - * @MappedSuperclass in the class doc block. - * - * @param string $className - * @return boolean - */ - public function isTransient($className) - { - $classAnnotations = $this->_reader->getClassAnnotations(new \ReflectionClass($className)); - - return ! isset($classAnnotations['Doctrine\ORM\Mapping\Entity']) && - ! isset($classAnnotations['Doctrine\ORM\Mapping\MappedSuperclass']); - } - - /** - * {@inheritDoc} - */ - public function getAllClassNames() - { - if ($this->_classDirectory) { - $iter = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->_classDirectory), - \RecursiveIteratorIterator::LEAVES_ONLY); - - $declared = get_declared_classes(); - foreach ($iter as $item) { - $info = pathinfo($item->getPathName()); - if ( ! isset($info['extension']) || $info['extension'] != 'php') { - continue; - } - require_once $item->getPathName(); - } - $declared = array_diff(get_declared_classes(), $declared); - - $classes = array(); - foreach ($declared as $className) { - if ( ! $this->isTransient($className)) { - $classes[] = $className; - } - } - return $classes; - } else { - return array(); - } - } - -} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php.orig b/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php.orig deleted file mode 100644 index b440745ec..000000000 --- a/lib/Doctrine/ORM/Mapping/Driver/XmlDriver.php.orig +++ /dev/null @@ -1,452 +0,0 @@ -. - */ - -namespace Doctrine\ORM\Mapping\Driver; - -use Doctrine\ORM\Mapping\ClassMetadataInfo, - Doctrine\ORM\Mapping\MappingException; - -/** - * XmlDriver is a metadata driver that enables mapping through XML files. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision$ - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - */ -class XmlDriver extends AbstractFileDriver -{ - protected $_fileExtension = '.dcm.xml'; - - /** - * Loads the metadata for the specified class into the provided container. - * - * @param string $className - * @param ClassMetadata $metadata - */ - public function loadMetadataForClass($className, ClassMetadataInfo $metadata) - { - $xmlRoot = $this->getElement($className); - - if ($xmlRoot->getName() == 'entity') { - $metadata->setCustomRepositoryClass( - isset($xmlRoot['repository-class']) ? (string)$xmlRoot['repository-class'] : null - ); - } else if ($xmlRoot->getName() == 'mapped-superclass') { - $metadata->isMappedSuperclass = true; - } else { - throw DoctrineException::classIsNotAValidEntityOrMapperSuperClass($className); - } - - // Evaluate attributes - if (isset($xmlRoot['table'])) { - $metadata->primaryTable['name'] = (string)$xmlRoot['table']; - } - - if (isset($xmlRoot['schema'])) { - $metadata->primaryTable['schema'] = (string)$xmlRoot['schema']; - } - - if (isset($xmlRoot['inheritance-type'])) { - $metadata->setInheritanceType((string)$xmlRoot['inheritance-type']); - } - - // Evaluate - if (isset($xmlRoot->{'discriminator-column'})) { - $discrColumn = $xmlRoot->{'discriminator-column'}; - $metadata->setDiscriminatorColumn(array( - 'name' => (string)$discrColumn['name'], - 'type' => (string)$discrColumn['type'], - 'length' => (string)$discrColumn['length'] - )); - } - - // Evaluate - if (isset($xmlRoot->{'discriminator-map'})) { - $metadata->setDiscriminatorMap((array)$xmlRoot->{'discriminator-map'}); - } - - // Evaluate - if (isset($xmlRoot->{'change-tracking-policy'})) { - $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' - . strtoupper((string)$xmlRoot->{'change-tracking-policy'}))); - } - - // Evaluate - if (isset($xmlRoot->indexes)) { - foreach ($xmlRoot->indexes->index as $index) { - if (is_string($index['columns'])) { - $columns = explode(',', $index['columns']); - } else { - $columns = $index['columns']; - } - - $metadata->primaryTable['indexes'][$index['name']] = array( - 'columns' => $columns - ); - } - } - - // Evaluate - if (isset($xmlRoot->{'unique-constraints'})) { - foreach ($xmlRoot->{'unique-constraints'}->{'unique-constraint'} as $unique) { - if (is_string($unique['columns'])) { - $columns = explode(',', $unique['columns']); - } else { - $columns = $unique['columns']; - } - - $metadata->primaryTable['uniqueConstraints'][$unique['name']] = array( - 'columns' => $columns - ); - } - } - - // Evaluate mappings - if (isset($xmlRoot->field)) { - foreach ($xmlRoot->field as $fieldMapping) { - $mapping = array( - 'fieldName' => (string)$fieldMapping['name'], - 'type' => (string)$fieldMapping['type'] - ); - - if (isset($fieldMapping['column'])) { - $mapping['columnName'] = (string)$fieldMapping['column']; - } - - if (isset($fieldMapping['length'])) { - $mapping['length'] = (int)$fieldMapping['length']; - } - - if (isset($fieldMapping['precision'])) { - $mapping['precision'] = (int)$fieldMapping['precision']; - } - - if (isset($fieldMapping['scale'])) { - $mapping['scale'] = (int)$fieldMapping['scale']; - } - - if (isset($fieldMapping['unique'])) { - $mapping['unique'] = (bool)$fieldMapping['unique']; - } - - if (isset($fieldMapping['options'])) { - $mapping['options'] = (array)$fieldMapping['options']; - } - - if (isset($fieldMapping['version']) && $fieldMapping['version']) { - $metadata->setVersionMapping($mapping); - } - - $metadata->mapField($mapping); - } - } - - // Evaluate mappings - foreach ($xmlRoot->id as $idElement) { - $mapping = array( - 'id' => true, - 'fieldName' => (string)$idElement['name'], - 'type' => (string)$idElement['type'] - ); - - if (isset($idElement['column'])) { - $mapping['columnName'] = (string)$idElement['column']; - } - - $metadata->mapField($mapping); - - if (isset($idElement->generator)) { - $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' - . strtoupper((string)$idElement->generator['strategy']))); - } - - // Check for SequenceGenerator/TableGenerator definition - if (isset($idElement->{'sequence-generator'})) { - $seqGenerator = $idElement->{'sequence-generator'}; - $metadata->setSequenceGeneratorDefinition(array( - 'sequenceName' => $seqGenerator->{'sequence-name'}, - 'allocationSize' => $seqGenerator->{'allocation-size'}, - 'initialValue' => $seqGeneratorAnnot->{'initial-value'} - )); - } else if (isset($idElement->{'table-generator'})) { - throw DoctrineException::tableIdGeneratorNotImplemented(); - } - } - - // Evaluate mappings - if (isset($xmlRoot->{'one-to-one'})) { - foreach ($xmlRoot->{'one-to-one'} as $oneToOneElement) { - $mapping = array( - 'fieldName' => (string)$oneToOneElement['field'], - 'targetEntity' => (string)$oneToOneElement['target-entity'] - ); - - if (isset($oneToOneElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . (string)$oneToOneElement['fetch']); - } - - if (isset($oneToOneElement['mapped-by'])) { - $mapping['mappedBy'] = (string)$oneToOneElement['mapped-by']; - } else { - $joinColumns = array(); - - if (isset($oneToOneElement->{'join-column'})) { - $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement->{'join-column'}); - } else if (isset($oneToOneElement->{'join-columns'})) { - foreach ($oneToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { - $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); - } - } else { - throw MappingException::invalidMapping($mapping['fieldName']); - } - - $mapping['joinColumns'] = $joinColumns; - } - - if (isset($oneToOneElement->cascade)) { - $mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement->cascade); - } - - if (isset($oneToOneElement->{'orphan-removal'})) { - $mapping['orphanRemoval'] = (bool)$oneToOneElement->{'orphan-removal'}; - } - - $metadata->mapOneToOne($mapping); - } - } - - // Evaluate mappings - if (isset($xmlRoot->{'one-to-many'})) { - foreach ($xmlRoot->{'one-to-many'} as $oneToManyElement) { - $mapping = array( - 'fieldName' => (string)$oneToManyElement['field'], - 'targetEntity' => (string)$oneToManyElement['target-entity'], - 'mappedBy' => (string)$oneToManyElement['mapped-by'] - ); - - if (isset($oneToManyElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . (string)$oneToManyElement['fetch']); - } - - if (isset($oneToManyElement->cascade)) { - $mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement->cascade); - } - - if (isset($oneToManyElement->{'orphan-removal'})) { - $mapping['orphanRemoval'] = (bool)$oneToManyElement->{'orphan-removal'}; - } - - $metadata->mapOneToMany($mapping); - } - } - - // Evaluate mappings - if (isset($xmlRoot->{'many-to-one'})) { - foreach ($xmlRoot->{'many-to-one'} as $manyToOneElement) { - $mapping = array( - 'fieldName' => (string)$manyToOneElement['field'], - 'targetEntity' => (string)$manyToOneElement['target-entity'] - ); - - if (isset($manyToOneElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . (string)$manyToOneElement['fetch']); - } - - $joinColumns = array(); - - if (isset($manyToOneElement->{'join-column'})) { - $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement->{'join-column'}); - } else if (isset($manyToOneElement->{'join-columns'})) { - foreach ($manyToOneElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { - if (!isset($joinColumnElement['name'])) { - $joinColumnElement['name'] = $name; - } - - $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); - } - } else { - throw MappingException::invalidMapping($mapping['fieldName']); - } - - $mapping['joinColumns'] = $joinColumns; - - if (isset($manyToOneElement->cascade)) { - $mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement->cascade); - } - - if (isset($manyToOneElement->{'orphan-removal'})) { - $mapping['orphanRemoval'] = (bool)$manyToOneElement->{'orphan-removal'}; - } - - $metadata->mapManyToOne($mapping); - } - } - - // Evaluate mappings - if (isset($xmlRoot->{'many-to-many'})) { - foreach ($xmlRoot->{'many-to-many'} as $manyToManyElement) { - $mapping = array( - 'fieldName' => (string)$manyToManyElement['field'], - 'targetEntity' => (string)$manyToManyElement['target-entity'] - ); - - if (isset($manyToManyElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . (string)$manyToManyElement['fetch']); - } - - if (isset($manyToManyElement['mapped-by'])) { - $mapping['mappedBy'] = (string)$manyToManyElement['mapped-by']; - } else if (isset($manyToManyElement->{'join-table'})) { - $joinTableElement = $manyToManyElement->{'join-table'}; - $joinTable = array( - 'name' => (string)$joinTableElement['name'] - ); - - if (isset($joinTableElement['schema'])) { - $joinTable['schema'] = (string)$joinTableElement['schema']; - } - - foreach ($joinTableElement->{'join-columns'}->{'join-column'} as $joinColumnElement) { - $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); - } - - foreach ($joinTableElement->{'inverse-join-columns'}->{'join-column'} as $joinColumnElement) { - $joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); - } - - $mapping['joinTable'] = $joinTable; - } else { - throw MappingException::invalidMapping($mapping['fieldName']); - } - - if (isset($manyToManyElement->cascade)) { - $mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement->cascade); - } - - if (isset($manyToManyElement->{'orphan-removal'})) { - $mapping['orphanRemoval'] = (bool)$manyToManyElement->{'orphan-removal'}; - } - - $metadata->mapManyToMany($mapping); - } - } - - // Evaluate - if (isset($xmlRoot->{'lifecycle-callbacks'})) { - foreach ($xmlRoot->{'lifecycle-callbacks'}->{'lifecycle-callback'} as $lifecycleCallback) { - $metadata->addLifecycleCallback((string)$lifecycleCallback['method'], constant('\Doctrine\ORM\Events::' . (string)$lifecycleCallback['type'])); - } - } - } - - /** - * Loads a mapping file with the given name and returns a map - * from class/entity names to their corresponding SimpleXMLElement nodes. - * - * @param string $file The mapping file to load. - * @return array - */ - protected function _loadMappingFile($file) - { - $result = array(); - $xmlElement = simplexml_load_file($file); - - if (isset($xmlElement->entity)) { - foreach ($xmlElement->entity as $entityElement) { - $entityName = (string)$entityElement['name']; - $result[$entityName] = $entityElement; - } - } else if (isset($xmlElement->{'mapped-superclass'})) { - foreach ($xmlElement->{'mapped-superclass'} as $mapperSuperClass) { - $className = (string)$mappedSuperClass['name']; - $result[$className] = $mappedSuperClass; - } - } - - return $result; - } - - /** - * Constructs a joinColumn mapping array based on the information - * found in the given SimpleXMLElement. - * - * @param $joinColumnElement The XML element. - * @return array The mapping array. - */ - private function _getJoinColumnMapping(\SimpleXMLElement $joinColumnElement) - { - $joinColumn = array( - 'name' => (string)$joinColumnElement['name'], - 'referencedColumnName' => (string)$joinColumnElement['referenced-column-name'] - ); - - if (isset($joinColumnElement['unique'])) { - $joinColumn['unique'] = (bool)$joinColumnElement['unique']; - } - - if (isset($joinColumnElement['nullable'])) { - $joinColumn['nullable'] = (bool)$joinColumnElement['nullable']; - } - - if (isset($joinColumnElement['onDelete'])) { - $joinColumn['onDelete'] = (string)$joinColumnElement['on-delete']; - } - - if (isset($joinColumnElement['onUpdate'])) { - $joinColumn['onUpdate'] = (string)$joinColumnElement['on-update']; - } - - return $joinColumn; - } - - /** - * Gathers a list of cascade options found in the given cascade element. - * - * @param $cascadeElement The cascade element. - * @return array The list of cascade options. - */ - private function _getCascadeMappings($cascadeElement) - { - $cascades = array(); - - if (isset($cascadeElement->{'cascade-persist'})) { - $cascades[] = 'persist'; - } - - if (isset($cascadeElement->{'cascade-remove'})) { - $cascades[] = 'remove'; - } - - if (isset($cascadeElement->{'cascade-merge'})) { - $cascades[] = 'merge'; - } - - if (isset($cascadeElement->{'cascade-refresh'})) { - $cascades[] = 'refresh'; - } - - return $cascades; - } -} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php.orig b/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php.orig deleted file mode 100644 index 6ae95dd12..000000000 --- a/lib/Doctrine/ORM/Mapping/Driver/YamlDriver.php.orig +++ /dev/null @@ -1,451 +0,0 @@ -. - */ - -namespace Doctrine\ORM\Mapping\Driver; - -use Doctrine\ORM\Mapping\ClassMetadataInfo, - Doctrine\Common\DoctrineException, - Doctrine\ORM\Mapping\MappingException; - -if ( ! class_exists('sfYaml', false)) { - require_once __DIR__ . '/../../../../vendor/sfYaml/sfYaml.class.php'; - require_once __DIR__ . '/../../../../vendor/sfYaml/sfYamlDumper.class.php'; - require_once __DIR__ . '/../../../../vendor/sfYaml/sfYamlInline.class.php'; - require_once __DIR__ . '/../../../../vendor/sfYaml/sfYamlParser.class.php'; -} - -/** - * The YamlDriver reads the mapping metadata from yaml schema files. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision$ - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - */ -class YamlDriver extends AbstractFileDriver -{ - protected $_fileExtension = '.dcm.yml'; - - public function loadMetadataForClass($className, ClassMetadataInfo $metadata) - { - $element = $this->getElement($className); - - if ($element['type'] == 'entity') { - $metadata->setCustomRepositoryClass( - isset($element['repositoryClass']) ? $element['repositoryClass'] : null - ); - } else if ($element['type'] == 'mappedSuperclass') { - $metadata->isMappedSuperclass = true; - } else { - throw DoctrineException::classIsNotAValidEntityOrMapperSuperClass($className); - } - - // Evaluate root level properties - if (isset($element['table'])) { - $metadata->primaryTable['name'] = $element['table']; - } - - if (isset($element['schema'])) { - $metadata->primaryTable['schema'] = $element['schema']; - } - - if (isset($element['inheritanceType'])) { - $metadata->setInheritanceType(constant('Doctrine\ORM\Mapping\ClassMetadata::INHERITANCE_TYPE_' . strtoupper($element['inheritanceType']))); - } - - // Evaluate discriminatorColumn - if (isset($element['discriminatorColumn'])) { - $discrColumn = $element['discriminatorColumn']; - $metadata->setDiscriminatorColumn(array( - 'name' => $discrColumn['name'], - 'type' => $discrColumn['type'], - 'length' => $discrColumn['length'] - )); - } - - // Evaluate discriminatorMap - if (isset($element['discriminatorMap'])) { - $metadata->setDiscriminatorMap($element['discriminatorMap']); - } - - // Evaluate changeTrackingPolicy - if (isset($element['changeTrackingPolicy'])) { - $metadata->setChangeTrackingPolicy(constant('Doctrine\ORM\Mapping\ClassMetadata::CHANGETRACKING_' - . strtoupper($element['changeTrackingPolicy']))); - } - - // Evaluate indexes - if (isset($element['indexes'])) { - foreach ($element['indexes'] as $name => $index) { - if ( ! isset($index['name'])) { - $index['name'] = $name; - } - - if (is_string($index['columns'])) { - $columns = explode(',', $index['columns']); - } else { - $columns = $index['columns']; - } - - $metadata->primaryTable['indexes'][$index['name']] = array( - 'columns' => $columns - ); - } - } - - // Evaluate uniqueConstraints - if (isset($element['uniqueConstraints'])) { - foreach ($element['uniqueConstraints'] as $name => $unique) { - if ( ! isset($unique['name'])) { - $unique['name'] = $name; - } - - if (is_string($unique['columns'])) { - $columns = explode(',', $unique['columns']); - } else { - $columns = $unique['columns']; - } - - $metadata->primaryTable['uniqueConstraints'][$unique['name']] = array( - 'columns' => $columns - ); - } - } - - if (isset($element['id'])) { - // Evaluate identifier settings - foreach ($element['id'] as $name => $idElement) { - $mapping = array( - 'id' => true, - 'fieldName' => $name, - 'type' => $idElement['type'] - ); - - if (isset($idElement['column'])) { - $mapping['columnName'] = $idElement['column']; - } - - $metadata->mapField($mapping); - - if (isset($idElement['generator'])) { - $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' - . strtoupper($idElement['generator']['strategy']))); - } - } - } - - // Evaluate fields - if (isset($element['fields'])) { - foreach ($element['fields'] as $name => $fieldMapping) { - $e = explode('(', $fieldMapping['type']); - $fieldMapping['type'] = $e[0]; - if (isset($e[1])) { - $fieldMapping['length'] = substr($e[1], 0, strlen($e[1]) - 1); - } - $mapping = array( - 'fieldName' => $name, - 'type' => $fieldMapping['type'] - ); - if (isset($fieldMapping['id'])) { - $mapping['id'] = true; - if (isset($fieldMapping['generator']['strategy'])) { - $metadata->setIdGeneratorType(constant('Doctrine\ORM\Mapping\ClassMetadata::GENERATOR_TYPE_' - . strtoupper($fieldMapping['generator']['strategy']))); - } - } - // Check for SequenceGenerator/TableGenerator definition - if (isset($fieldMapping['sequenceGenerator'])) { - $metadata->setSequenceGeneratorDefinition($fieldMapping['sequenceGenerator']); - } else if (isset($fieldMapping['tableGenerator'])) { - throw DoctrineException::tableIdGeneratorNotImplemented(); - } - if (isset($fieldMapping['column'])) { - $mapping['columnName'] = $fieldMapping['column']; - } - if (isset($fieldMapping['length'])) { - $mapping['length'] = $fieldMapping['length']; - } - if (isset($fieldMapping['precision'])) { - $mapping['precision'] = $fieldMapping['precision']; - } - if (isset($fieldMapping['scale'])) { - $mapping['scale'] = $fieldMapping['scale']; - } - if (isset($fieldMapping['unique'])) { - $mapping['unique'] = (bool)$fieldMapping['unique']; - } - if (isset($fieldMapping['options'])) { - $mapping['options'] = $fieldMapping['options']; - } - if (isset($fieldMapping['nullable'])) { - $mapping['nullable'] = $fieldMapping['nullable']; - } - if (isset($fieldMapping['version']) && $fieldMapping['version']) { - $metadata->setVersionMapping($mapping); - } - - $metadata->mapField($mapping); - } - } - - // Evaluate oneToOne relationships - if (isset($element['oneToOne'])) { - foreach ($element['oneToOne'] as $name => $oneToOneElement) { - $mapping = array( - 'fieldName' => $name, - 'targetEntity' => $oneToOneElement['targetEntity'] - ); - - if (isset($oneToOneElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $oneToOneElement['fetch']); - } - - if (isset($oneToOneElement['mappedBy'])) { - $mapping['mappedBy'] = $oneToOneElement['mappedBy']; - } else { - $joinColumns = array(); - - if (isset($oneToOneElement['joinColumn'])) { - $joinColumns[] = $this->_getJoinColumnMapping($oneToOneElement['joinColumn']); - } else if (isset($oneToOneElement['joinColumns'])) { - foreach ($oneToOneElement['joinColumns'] as $name => $joinColumnElement) { - if (!isset($joinColumnElement['name'])) { - $joinColumnElement['name'] = $name; - } - - $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); - } - } else { - throw MappingException::invalidMapping($mapping['fieldName']); - } - - $mapping['joinColumns'] = $joinColumns; - } - - if (isset($oneToOneElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($oneToOneElement['cascade']); - } - - $metadata->mapOneToOne($mapping); - } - } - - // Evaluate oneToMany relationships - if (isset($element['oneToMany'])) { - foreach ($element['oneToMany'] as $name => $oneToManyElement) { - $mapping = array( - 'fieldName' => $name, - 'targetEntity' => $oneToManyElement['targetEntity'], - 'mappedBy' => $oneToManyElement['mappedBy'] - ); - - if (isset($oneToManyElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $oneToManyElement['fetch']); - } - - if (isset($oneToManyElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($oneToManyElement['cascade']); - } - - $metadata->mapOneToMany($mapping); - } - } - - // Evaluate manyToOne relationships - if (isset($element['manyToOne'])) { - foreach ($element['manyToOne'] as $name => $manyToOneElement) { - $mapping = array( - 'fieldName' => $name, - 'targetEntity' => $manyToOneElement['targetEntity'] - ); - - if (isset($manyToOneElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToOneElement['fetch']); - } - - $joinColumns = array(); - - if (isset($manyToOneElement['joinColumn'])) { - $joinColumns[] = $this->_getJoinColumnMapping($manyToOneElement['joinColumn']); - } else if (isset($manyToOneElement['joinColumns'])) { - foreach ($manyToOneElement['joinColumns'] as $name => $joinColumnElement) { - if (!isset($joinColumnElement['name'])) { - $joinColumnElement['name'] = $name; - } - - $joinColumns[] = $this->_getJoinColumnMapping($joinColumnElement); - } - } else { - throw MappingException::invalidMapping($mapping['fieldName']); - } - - $mapping['joinColumns'] = $joinColumns; - - if (isset($manyToOneElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($manyToOneElement['cascade']); - } - - $metadata->mapManyToOne($mapping); - } - } - - // Evaluate manyToMany relationships - if (isset($element['manyToMany'])) { - foreach ($element['manyToMany'] as $name => $manyToManyElement) { - $mapping = array( - 'fieldName' => $name, - 'targetEntity' => $manyToManyElement['targetEntity'] - ); - - if (isset($manyToManyElement['fetch'])) { - $mapping['fetch'] = constant('Doctrine\ORM\Mapping\AssociationMapping::FETCH_' . $manyToManyElement['fetch']); - } - - if (isset($manyToManyElement['mappedBy'])) { - $mapping['mappedBy'] = $manyToManyElement['mappedBy']; - } else if (isset($manyToManyElement['joinTable'])) { - $joinTableElement = $manyToManyElement['joinTable']; - $joinTable = array( - 'name' => $joinTableElement['name'] - ); - - if (isset($joinTableElement['schema'])) { - $joinTable['schema'] = $joinTableElement['schema']; - } - - foreach ($joinTableElement['joinColumns'] as $name => $joinColumnElement) { - if (!isset($joinColumnElement['name'])) { - $joinColumnElement['name'] = $name; - } - - $joinTable['joinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); - } - - foreach ($joinTableElement['inverseJoinColumns'] as $name => $joinColumnElement) { - if (!isset($joinColumnElement['name'])) { - $joinColumnElement['name'] = $name; - } - - $joinTable['inverseJoinColumns'][] = $this->_getJoinColumnMapping($joinColumnElement); - } - - $mapping['joinTable'] = $joinTable; - } else { - throw MappingException::invalidMapping($mapping['fieldName']); - } - - if (isset($manyToManyElement['cascade'])) { - $mapping['cascade'] = $this->_getCascadeMappings($manyToManyElement['cascade']); - } - - $metadata->mapManyToMany($mapping); - } - } - - // Evaluate lifeCycleCallbacks - if (isset($element['lifecycleCallbacks'])) { - foreach ($element['lifecycleCallbacks'] as $method => $type) { - $metadata->addLifecycleCallback($method, constant('\Doctrine\ORM\Events::' . $type)); - } - } - } - - /** - * Constructs a joinColumn mapping array based on the information - * found in the given join column element. - * - * @param $joinColumnElement The array join column element - * @return array The mapping array. - */ - private function _getJoinColumnMapping($joinColumnElement) - { - $joinColumn = array( - 'name' => $joinColumnElement['name'], - 'referencedColumnName' => $joinColumnElement['referencedColumnName'] - ); - - if (isset($joinColumnElement['fieldName'])) { - $joinColumn['fieldName'] = (string) $joinColumnElement['fieldName']; - } - - if (isset($joinColumnElement['unique'])) { - $joinColumn['unique'] = (bool) $joinColumnElement['unique']; - } - - if (isset($joinColumnElement['nullable'])) { - $joinColumn['nullable'] = (bool) $joinColumnElement['nullable']; - } - - if (isset($joinColumnElement['onDelete'])) { - $joinColumn['onDelete'] = $joinColumnElement['onDelete']; - } - - if (isset($joinColumnElement['onUpdate'])) { - $joinColumn['onUpdate'] = $joinColumnElement['onUpdate']; - } - - return $joinColumn; - } - - /** - * Gathers a list of cascade options found in the given cascade element. - * - * @param $cascadeElement The cascade element. - * @return array The list of cascade options. - */ - private function _getCascadeMappings($cascadeElement) - { - $cascades = array(); - - if (isset($cascadeElement['cascadePersist'])) { - $cascades[] = 'persist'; - } - - if (isset($cascadeElement['cascadeRemove'])) { - $cascades[] = 'remove'; - } - - if (isset($cascadeElement['cascadeMerge'])) { - $cascades[] = 'merge'; - } - - if (isset($cascadeElement['cascadeRefresh'])) { - $cascades[] = 'refresh'; - } - - return $cascades; - } - - /** - * Loads a mapping file with the given name and returns a map - * from class/entity names to their corresponding elements. - * - * @param string $file The mapping file to load. - * @return array - */ - protected function _loadMappingFile($file) - { - return \sfYaml::load($file); - } -} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php.orig b/lib/Doctrine/ORM/Tools/SchemaTool.php.orig deleted file mode 100644 index f3f1aeb30..000000000 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php.orig +++ /dev/null @@ -1,605 +0,0 @@ -. - */ - -namespace Doctrine\ORM\Tools; - -use Doctrine\DBAL\Types\Type, - Doctrine\ORM\EntityManager, - Doctrine\ORM\Internal\CommitOrderCalculator; - -/** - * The SchemaTool is a tool to create/drop/update database schemas based on - * ClassMetadata class descriptors. - * - * @license http://www.opensource.org/licenses/lgpl-license.php LGPL - * @link www.doctrine-project.org - * @since 2.0 - * @version $Revision$ - * @author Guilherme Blanco - * @author Jonathan Wage - * @author Roman Borschel - * @author Benjamin Eberlei - */ -class SchemaTool -{ - /** - * @var string - */ - const DROP_METADATA = "metadata"; - /** - * @var string - */ - const DROP_DATABASE = "database"; - - /** - * @var \Doctrine\ORM\EntityManager - */ - private $_em; - - /** - * @var \Doctrine\DBAL\Platforms\AbstractPlatform - */ - private $_platform; - - /** - * Initializes a new SchemaTool instance that uses the connection of the - * provided EntityManager. - * - * @param Doctrine\ORM\EntityManager $em - */ - public function __construct(EntityManager $em) - { - $this->_em = $em; - $this->_platform = $em->getConnection()->getDatabasePlatform(); - } - - /** - * Creates the database schema for the given array of ClassMetadata instances. - * - * @param array $classes - */ - public function createSchema(array $classes) - { - $createSchemaSql = $this->getCreateSchemaSql($classes); - $conn = $this->_em->getConnection(); - - foreach ($createSchemaSql as $sql) { - $conn->execute($sql); - } - } - - /** - * Gets the list of DDL statements that are required to create the database schema for - * the given list of ClassMetadata instances. - * - * @param array $classes - * @return array $sql The SQL statements needed to create the schema for the classes. - */ - public function getCreateSchemaSql(array $classes) - { - $schema = $this->getSchemaFromMetadata($classes); - return $schema->toSql($this->_platform); - } - - /** - * From a given set of metadata classes this method creates a Schema instance. - * - * @param array $classes - * @return Schema - */ - public function getSchemaFromMetadata(array $classes) - { - $processedClasses = array(); // Reminder for processed classes, used for hierarchies - - $sm = $this->_em->getConnection()->getSchemaManager(); - $schema = new \Doctrine\DBAL\Schema\Schema(array(), array(), $sm->createSchemaConfig()); - - foreach ($classes as $class) { - if (isset($processedClasses[$class->name]) || $class->isMappedSuperclass) { - continue; - } - - $table = $schema->createTable($class->getQuotedTableName($this->_platform)); - - if ($class->isIdGeneratorIdentity()) { - $table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_IDENTITY); - } else if ($class->isIdGeneratorSequence()) { - $table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_SEQUENCE); - } - - $columns = array(); // table columns - - if ($class->isInheritanceTypeSingleTable()) { - $columns = $this->_gatherColumns($class, $table); - $this->_gatherRelationsSql($class, $table, $schema); - - // Add the discriminator column - $discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table); - - // Aggregate all the information from all classes in the hierarchy - foreach ($class->parentClasses as $parentClassName) { - // Parent class information is already contained in this class - $processedClasses[$parentClassName] = true; - } - - foreach ($class->subClasses as $subClassName) { - $subClass = $this->_em->getClassMetadata($subClassName); - $this->_gatherColumns($subClass, $table); - $this->_gatherRelationsSql($subClass, $table, $schema); - $processedClasses[$subClassName] = true; - } - } else if ($class->isInheritanceTypeJoined()) { - // Add all non-inherited fields as columns - $pkColumns = array(); - foreach ($class->fieldMappings as $fieldName => $mapping) { - if ( ! isset($mapping['inherited'])) { - $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); - $this->_gatherColumn($class, $mapping, $table); - - if ($class->isIdentifier($fieldName)) { - $pkColumns[] = $columnName; - } - } - } - - $this->_gatherRelationsSql($class, $table, $schema); - - // Add the discriminator column only to the root table - if ($class->name == $class->rootEntityName) { - $discrColumnDef = $this->_getDiscriminatorColumnDefinition($class, $table); - } else { - // Add an ID FK column to child tables - /* @var Doctrine\ORM\Mapping\ClassMetadata $class */ - $idMapping = $class->fieldMappings[$class->identifier[0]]; - $this->_gatherColumn($class, $idMapping, $table); - $columnName = $class->getQuotedColumnName($class->identifier[0], $this->_platform); - - $pkColumns[] = $columnName; - if ($table->isIdGeneratorIdentity()) { - $table->setIdGeneratorType(\Doctrine\DBAL\Schema\Table::ID_NONE); - } - - // Add a FK constraint on the ID column - $table->addUnnamedForeignKeyConstraint( - $this->_em->getClassMetadata($class->rootEntityName)->getQuotedTableName($this->_platform), - array($columnName), array($columnName), array('onDelete' => 'CASCADE') - ); - } - - $table->setPrimaryKey($pkColumns); - - } else if ($class->isInheritanceTypeTablePerClass()) { - throw DoctrineException::notSupported(); - } else { - $this->_gatherColumns($class, $table); - $this->_gatherRelationsSql($class, $table, $schema); - } - - if (isset($class->primaryTable['indexes'])) { - foreach ($class->primaryTable['indexes'] AS $indexName => $indexData) { - $table->addIndex($indexData['columns'], $indexName); - } - } - - if (isset($class->primaryTable['uniqueConstraints'])) { - foreach ($class->primaryTable['uniqueConstraints'] AS $indexName => $indexData) { - $table->addUniqueIndex($indexData['columns'], $indexName); - } - } - - $processedClasses[$class->name] = true; - - if ($class->isIdGeneratorSequence() && $class->name == $class->rootEntityName) { - $seqDef = $class->getSequenceGeneratorDefinition(); - - if (!$schema->hasSequence($seqDef['sequenceName'])) { - $schema->createSequence( - $seqDef['sequenceName'], - $seqDef['allocationSize'], - $seqDef['initialValue'] - ); - } - } - } - - return $schema; - } - - /** - * Gets a portable column definition as required by the DBAL for the discriminator - * column of a class. - * - * @param ClassMetadata $class - * @return array The portable column definition of the discriminator column as required by - * the DBAL. - */ - private function _getDiscriminatorColumnDefinition($class, $table) - { - $discrColumn = $class->discriminatorColumn; - - $table->createColumn( - $class->getQuotedDiscriminatorColumnName($this->_platform), - $discrColumn['type'], - array('length' => $discrColumn['length'], 'notnull' => true) - ); - } - - /** - * Gathers the column definitions as required by the DBAL of all field mappings - * found in the given class. - * - * @param ClassMetadata $class - * @param Table $table - * @return array The list of portable column definitions as required by the DBAL. - */ - private function _gatherColumns($class, $table) - { - $columns = array(); - $pkColumns = array(); - - foreach ($class->fieldMappings as $fieldName => $mapping) { - $column = $this->_gatherColumn($class, $mapping, $table); - - if ($class->isIdentifier($mapping['fieldName'])) { - $pkColumns[] = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); - } - } - // For now, this is a hack required for single table inheritence, since this method is called - // twice by single table inheritence relations - if(!$table->hasIndex('primary')) { - $table->setPrimaryKey($pkColumns); - } - - return $columns; - } - - /** - * Creates a column definition as required by the DBAL from an ORM field mapping definition. - * - * @param ClassMetadata $class The class that owns the field mapping. - * @param array $mapping The field mapping. - * @param Table $table - * @return array The portable column definition as required by the DBAL. - */ - private function _gatherColumn($class, array $mapping, $table) - { - $columnName = $class->getQuotedColumnName($mapping['fieldName'], $this->_platform); - $columnType = $mapping['type']; - - $options = array(); - $options['length'] = isset($mapping['length']) ? $mapping['length'] : null; - $options['notnull'] = isset($mapping['nullable']) ? ! $mapping['nullable'] : true; - - $options['platformOptions'] = array(); - $options['platformOptions']['version'] = $class->isVersioned && $class->versionField == $mapping['fieldName'] ? true : false; - - if(strtolower($columnType) == 'string' && $options['length'] === null) { - $options['length'] = 255; - } - - if (isset($mapping['precision'])) { - $options['precision'] = $mapping['precision']; - } - - if (isset($mapping['scale'])) { - $options['scale'] = $mapping['scale']; - } - - if (isset($mapping['default'])) { - $options['default'] = $mapping['default']; - } - - if ($table->hasColumn($columnName)) { - // required in some inheritence scenarios - $table->changeColumn($columnName, $options); - } else { - $table->createColumn($columnName, $columnType, $options); - } - - $isUnique = isset($mapping['unique']) ? $mapping['unique'] : false; - if ($isUnique) { - $table->addUniqueIndex(array($columnName)); - } - } - - /** - * Gathers the SQL for properly setting up the relations of the given class. - * This includes the SQL for foreign key constraints and join tables. - * - * @param ClassMetadata $class - * @param array $sql The sequence of SQL statements where any new statements should be appended. - * @param array $columns The list of columns in the class's primary table where any additional - * columns required by relations should be appended. - * @param array $constraints The constraints of the table where any additional constraints - * required by relations should be appended. - * @return void - */ - private function _gatherRelationsSql($class, $table, $schema) - { - foreach ($class->associationMappings as $fieldName => $mapping) { - if (isset($class->inheritedAssociationFields[$fieldName])) { - continue; - } - - $foreignClass = $this->_em->getClassMetadata($mapping->targetEntityName); - - if ($mapping->isOneToOne() && $mapping->isOwningSide) { - $primaryKeyColumns = $uniqueConstraints = array(); // unnecessary for this relation-type - - $this->_gatherRelationJoinColumns($mapping->getJoinColumns(), $table, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints); - } else if ($mapping->isOneToMany() && $mapping->isOwningSide) { - //... create join table, one-many through join table supported later - throw DoctrineException::notSupported(); - } else if ($mapping->isManyToMany() && $mapping->isOwningSide) { - // create join table - $joinTable = $mapping->getJoinTable(); - - $theJoinTable = $schema->createTable($mapping->getQuotedJoinTableName($this->_platform)); - - $primaryKeyColumns = $uniqueConstraints = array(); - - // Build first FK constraint (relation table => source table) - $this->_gatherRelationJoinColumns($joinTable['joinColumns'], $theJoinTable, $class, $mapping, $primaryKeyColumns, $uniqueConstraints); - - // Build second FK constraint (relation table => target table) - $this->_gatherRelationJoinColumns($joinTable['inverseJoinColumns'], $theJoinTable, $foreignClass, $mapping, $primaryKeyColumns, $uniqueConstraints); - - foreach($uniqueConstraints AS $indexName => $unique) { - $theJoinTable->addUniqueIndex( - $unique['columns'], is_numeric($indexName) ? null : $indexName - ); - } - - $theJoinTable->setPrimaryKey($primaryKeyColumns); - } - } - } - - /** - * Gather columns and fk constraints that are required for one part of relationship. - * - * @param array $joinColumns - * @param \Doctrine\DBAL\Schema\Table $theJoinTable - * @param ClassMetadata $class - * @param \Doctrine\ORM\Mapping\AssociationMapping $mapping - * @param array $primaryKeyColumns - * @param array $uniqueConstraints - */ - private function _gatherRelationJoinColumns($joinColumns, $theJoinTable, $class, $mapping, &$primaryKeyColumns, &$uniqueConstraints) - { - $localColumns = array(); - $foreignColumns = array(); - $fkOptions = array(); - - foreach ($joinColumns as $joinColumn) { - // Note that this thing might be quoted, i.e. `foo`, [foo], ... - $columnName = $mapping->getQuotedJoinColumnName($joinColumn['name'], $this->_platform); - - if (!$class->hasField($class->getFieldName($joinColumn['referencedColumnName']))) { - throw new \Doctrine\Common\DoctrineException( - "Column name `".$joinColumn['referencedColumnName']."` referenced for relation from ". - "$mapping->sourceEntityName towards $mapping->targetEntityName does not exist." - ); - } - - $primaryKeyColumns[] = $columnName; - $localColumns[] = $columnName; - $foreignColumns[] = $joinColumn['referencedColumnName']; - - if ( ! $theJoinTable->hasColumn($joinColumn['name'])) { - // Only add the column to the table if it does not exist already. - // It might exist already if the foreign key is mapped into a regular - // property as well. - $theJoinTable->createColumn( - $columnName, $class->getTypeOfColumn($joinColumn['referencedColumnName']), array('notnull' => false) - ); - } - - if (isset($joinColumn['unique']) && $joinColumn['unique'] == true) { - $uniqueConstraints[] = array('columns' => $columnName); - } - - if (isset($joinColumn['onUpdate'])) { - $fkOptions['onUpdate'] = $joinColumn['onUpdate']; - } - - if (isset($joinColumn['onDelete'])) { - $fkOptions['onDelete'] = $joinColumn['onDelete']; - } - } - - $theJoinTable->addUnnamedForeignKeyConstraint( - $class->getQuotedTableName($this->_platform), $localColumns, $foreignColumns, $fkOptions - ); - } - - /** - * Drops the database schema for the given classes. - * - * In any way when an exception is thrown it is supressed since drop was - * issued for all classes of the schema and some probably just don't exist. - * - * @param array $classes - * @param string $mode - * @return void - */ - public function dropSchema(array $classes, $mode=self::DROP_METADATA) - { - $dropSchemaSql = $this->getDropSchemaSql($classes, $mode); - $conn = $this->_em->getConnection(); - - foreach ($dropSchemaSql as $sql) { - $conn->execute($sql); - } - } - - /** - * Gets the SQL needed to drop the database schema for the given classes. - * - * @param array $classes - * @param string $mode - * @return array - */ - public function getDropSchemaSql(array $classes) - { - $sm = $this->_em->getConnection()->getSchemaManager(); - $schema = $sm->createSchema(); - - $visitor = new \Doctrine\DBAL\Schema\Visitor\DropSchemaSqlCollector($this->_platform); - /* @var $schema \Doctrine\DBAL\Schema\Schema */ - $schema->visit($visitor); - return $visitor->getQueries(); - } - - /** - * Drop all tables of the database connection. - * - * @return array - */ - private function _getDropSchemaTablesDatabaseMode($classes) - { - $conn = $this->_em->getConnection(); - - $sm = $conn->getSchemaManager(); - /* @var $sm \Doctrine\DBAL\Schema\AbstractSchemaManager */ - - $allTables = $sm->listTables(); - - $orderedTables = $this->_getDropSchemaTablesMetadataMode($classes); - foreach($allTables AS $tableName) { - if(!in_array($tableName, $orderedTables)) { - $orderedTables[] = $tableName; - } - } - - return $orderedTables; - } - - private function _getDropSchemaTablesMetadataMode(array $classes) - { - $orderedTables = array(); - - $commitOrder = $this->_getCommitOrder($classes); - $associationTables = $this->_getAssociationTables($commitOrder); - - // Drop association tables first - foreach ($associationTables as $associationTable) { - $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; - } - - $orderedTables[] = $class->getTableName(); - } - - //TODO: Drop other schema elements, like sequences etc. - - return $orderedTables; - } - - /** - * Updates the database schema of the given classes by comparing the ClassMetadata - * instances to the current database schema that is inspected. - * - * @param array $classes - * @return void - */ - public function updateSchema(array $classes, $saveMode=false) - { - $updateSchemaSql = $this->getUpdateSchemaSql($classes, $saveMode); - $conn = $this->_em->getConnection(); - - foreach ($updateSchemaSql as $sql) { - $conn->execute($sql); - } - } - - /** - * Gets the sequence of SQL statements that need to be performed in order - * to bring the given class mappings in-synch with the relational schema. - * - * @param array $classes The classes to consider. - * @return array The sequence of SQL statements. - */ - public function getUpdateSchemaSql(array $classes, $saveMode=false) - { - $sm = $this->_em->getConnection()->getSchemaManager(); - - $fromSchema = $sm->createSchema(); - $toSchema = $this->getSchemaFromMetadata($classes); - - $comparator = new \Doctrine\DBAL\Schema\Comparator(); - $schemaDiff = $comparator->compare($fromSchema, $toSchema); - - if ($saveMode) { - return $schemaDiff->toSaveSql($this->_platform); - } else { - 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->targetEntityName); - - 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->isManyToMany()) { - $associationTables[] = $assoc->joinTable['name']; - } - } - } - - return $associationTables; - } -}