Commit e2b11774 authored by Tiago Brito's avatar Tiago Brito

Merge pull request #8 from doctrine/master

Update from master main repository
parents f2aa22cc a67db17b
...@@ -31,7 +31,7 @@ before_script: ...@@ -31,7 +31,7 @@ before_script:
- sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi" - sh -c "if [ '$DB' = 'mysql' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
- sh -c "if [ '$DB' = 'mysqli' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi" - sh -c "if [ '$DB' = 'mysqli' ]; then mysql -e 'create database IF NOT EXISTS doctrine_tests_tmp;create database IF NOT EXISTS doctrine_tests;'; fi"
script: phpunit --configuration tests/travis/$DB.travis.xml script: ./vendor/bin/phpunit --configuration tests/travis/$DB.travis.xml
matrix: matrix:
allow_failures: allow_failures:
...@@ -44,7 +44,7 @@ matrix: ...@@ -44,7 +44,7 @@ matrix:
- php: hhvm - php: hhvm
env: DB=sqlite env: DB=sqlite
- php: hhvm - php: hhvm
env: DB=mysqli env: DB=mysql
- php: hhvm-nightly - php: hhvm-nightly
exclude: exclude:
- php: hhvm - php: hhvm
......
# Upgrade to 2.5 # Upgrade to 2.5
## BC BREAK: time type resets date fields to UNIX epoch
When mapping `time` type field to PHP's `DateTime` instance all unused date fields are
reset to UNIX epoch (i.e. 1970-01-01). This might break any logic which relies on comparing
`DateTime` instances with date fields set to the current date.
Use `!` format prefix (see http://php.net/manual/en/datetime.createfromformat.php) for parsing
time strings to prevent having different date fields when comparing user input and `DateTime`
instances as mapped by Doctrine.
## BC BREAK: Doctrine\DBAL\Schema\Table ## BC BREAK: Doctrine\DBAL\Schema\Table
The methods ``addIndex()`` and ``addUniqueIndex()`` in ``Doctrine\DBAL\Schema\Table`` The methods ``addIndex()`` and ``addUniqueIndex()`` in ``Doctrine\DBAL\Schema\Table``
......
...@@ -307,7 +307,7 @@ Prepare a given SQL statement and return the ...@@ -307,7 +307,7 @@ Prepare a given SQL statement and return the
array( array(
0 => array( 0 => array(
'username' => 'jwage', 'username' => 'jwage',
'password' => 'changeme 'password' => 'changeme'
) )
) )
*/ */
...@@ -344,7 +344,7 @@ parameters to the execute method, then returning the statement: ...@@ -344,7 +344,7 @@ parameters to the execute method, then returning the statement:
/* /*
array( array(
0 => 'jwage', 0 => 'jwage',
1 => 'changeme 1 => 'changeme'
) )
*/ */
...@@ -367,7 +367,7 @@ Execute the query and fetch all results into an array: ...@@ -367,7 +367,7 @@ Execute the query and fetch all results into an array:
array( array(
0 => array( 0 => array(
'username' => 'jwage', 'username' => 'jwage',
'password' => 'changeme 'password' => 'changeme'
) )
) )
*/ */
...@@ -385,7 +385,7 @@ Numeric index retrieval of first result row of the given query: ...@@ -385,7 +385,7 @@ Numeric index retrieval of first result row of the given query:
/* /*
array( array(
0 => 'jwage', 0 => 'jwage',
1 => 'changeme 1 => 'changeme'
) )
*/ */
...@@ -412,7 +412,7 @@ Retrieve assoc row of the first result row. ...@@ -412,7 +412,7 @@ Retrieve assoc row of the first result row.
/* /*
array( array(
'username' => 'jwage', 'username' => 'jwage',
'password' => 'changeme 'password' => 'changeme'
) )
*/ */
......
...@@ -597,7 +597,7 @@ class Connection implements DriverConnection ...@@ -597,7 +597,7 @@ class Connection implements DriverConnection
*/ */
public function close() public function close()
{ {
unset($this->_conn); $this->_conn = null;
$this->_isConnected = false; $this->_isConnected = false;
} }
......
...@@ -50,6 +50,12 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar ...@@ -50,6 +50,12 @@ class MysqliConnection implements Connection, PingableConnection, ServerInfoAwar
public function __construct(array $params, $username, $password, array $driverOptions = array()) public function __construct(array $params, $username, $password, array $driverOptions = array())
{ {
$port = isset($params['port']) ? $params['port'] : ini_get('mysqli.default_port'); $port = isset($params['port']) ? $params['port'] : ini_get('mysqli.default_port');
// Fallback to default MySQL port if not given.
if ( ! $port) {
$port = 3306;
}
$socket = isset($params['unix_socket']) ? $params['unix_socket'] : ini_get('mysqli.default_socket'); $socket = isset($params['unix_socket']) ? $params['unix_socket'] : ini_get('mysqli.default_socket');
$dbname = isset($params['dbname']) ? $params['dbname'] : null; $dbname = isset($params['dbname']) ? $params['dbname'] : null;
......
...@@ -48,6 +48,18 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection ...@@ -48,6 +48,18 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
} }
} }
/**
* {@inheritdoc}
*/
public function exec($statement)
{
try {
return parent::exec($statement);
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -100,11 +112,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection ...@@ -100,11 +112,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
*/ */
public function quote($input, $type = \PDO::PARAM_STR) public function quote($input, $type = \PDO::PARAM_STR)
{ {
try {
return parent::quote($input, $type); return parent::quote($input, $type);
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
} }
/** /**
...@@ -112,11 +120,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection ...@@ -112,11 +120,7 @@ class PDOConnection extends PDO implements Connection, ServerInfoAwareConnection
*/ */
public function lastInsertId($name = null) public function lastInsertId($name = null)
{ {
try {
return parent::lastInsertId($name); return parent::lastInsertId($name);
} catch (\PDOException $exception) {
throw new PDOException($exception);
}
} }
/** /**
......
...@@ -44,6 +44,10 @@ class Driver extends AbstractSQLServerDriver ...@@ -44,6 +44,10 @@ class Driver extends AbstractSQLServerDriver
$driverOptions['Database'] = $params['dbname']; $driverOptions['Database'] = $params['dbname'];
} }
if (isset($params['charset'])) {
$driverOptions['CharacterSet'] = $params['charset'];
}
$driverOptions['UID'] = $username; $driverOptions['UID'] = $username;
$driverOptions['PWD'] = $password; $driverOptions['PWD'] = $password;
......
...@@ -1574,8 +1574,10 @@ abstract class AbstractPlatform ...@@ -1574,8 +1574,10 @@ abstract class AbstractPlatform
$sql = $this->_getCreateTableSQL($tableName, $columns, $options); $sql = $this->_getCreateTableSQL($tableName, $columns, $options);
if ($this->supportsCommentOnStatement()) { if ($this->supportsCommentOnStatement()) {
foreach ($table->getColumns() as $column) { foreach ($table->getColumns() as $column) {
if ($this->getColumnComment($column)) { $comment = $this->getColumnComment($column);
$sql[] = $this->getCommentOnColumnSQL($tableName, $column->getQuotedName($this), $this->getColumnComment($column));
if (null !== $comment && '' !== $comment) {
$sql[] = $this->getCommentOnColumnSQL($tableName, $column->getQuotedName($this), $comment);
} }
} }
} }
...@@ -1592,9 +1594,12 @@ abstract class AbstractPlatform ...@@ -1592,9 +1594,12 @@ abstract class AbstractPlatform
*/ */
public function getCommentOnColumnSQL($tableName, $columnName, $comment) public function getCommentOnColumnSQL($tableName, $columnName, $comment)
{ {
$tableName = new Identifier($tableName);
$columnName = new Identifier($columnName);
$comment = $this->quoteStringLiteral($comment); $comment = $this->quoteStringLiteral($comment);
return "COMMENT ON COLUMN " . $tableName . "." . $columnName . " IS " . $comment; return "COMMENT ON COLUMN " . $tableName->getQuotedName($this) . "." . $columnName->getQuotedName($this) .
" IS " . $comment;
} }
/** /**
...@@ -2014,7 +2019,7 @@ abstract class AbstractPlatform ...@@ -2014,7 +2019,7 @@ abstract class AbstractPlatform
*/ */
protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
{ {
$tableName = $diff->getName()->getQuotedName($this); $tableName = $diff->getName($this)->getQuotedName($this);
$sql = array(); $sql = array();
if ($this->supportsForeignKeyConstraints()) { if ($this->supportsForeignKeyConstraints()) {
...@@ -2045,7 +2050,7 @@ abstract class AbstractPlatform ...@@ -2045,7 +2050,7 @@ abstract class AbstractPlatform
{ {
$tableName = (false !== $diff->newName) $tableName = (false !== $diff->newName)
? $diff->getNewName()->getQuotedName($this) ? $diff->getNewName()->getQuotedName($this)
: $diff->getName()->getQuotedName($this); : $diff->getName($this)->getQuotedName($this);
$sql = array(); $sql = array();
...@@ -2205,7 +2210,7 @@ abstract class AbstractPlatform ...@@ -2205,7 +2210,7 @@ abstract class AbstractPlatform
$columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation; $columnDef = $typeDecl . $charset . $default . $notnull . $unique . $check . $collation;
} }
if ($this->supportsInlineColumnComments() && isset($field['comment']) && $field['comment']) { if ($this->supportsInlineColumnComments() && isset($field['comment']) && $field['comment'] !== '') {
$columnDef .= " COMMENT " . $this->quoteStringLiteral($field['comment']); $columnDef .= " COMMENT " . $this->quoteStringLiteral($field['comment']);
} }
......
...@@ -519,12 +519,16 @@ class DB2Platform extends AbstractPlatform ...@@ -519,12 +519,16 @@ class DB2Platform extends AbstractPlatform
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
if (count($queryParts) > 0) { if (count($queryParts) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . implode(" ", $queryParts); $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(" ", $queryParts);
} }
// Some table alteration operations require a table reorganization. // Some table alteration operations require a table reorganization.
if ( ! empty($diff->removedColumns) || ! empty($diff->changedColumns)) { if ( ! empty($diff->removedColumns) || ! empty($diff->changedColumns)) {
$sql[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE " . $diff->getName()->getQuotedName($this) . "')"; $sql[] = "CALL SYSPROC.ADMIN_CMD ('REORG TABLE " . $diff->getName($this)->getQuotedName($this) . "')";
}
if ($diff->newName !== false) {
$sql[] = 'RENAME TABLE ' . $diff->getName($this)->getQuotedName($this) . ' TO ' . $diff->getNewName()->getQuotedName($this);
} }
$sql = array_merge( $sql = array_merge(
...@@ -532,10 +536,6 @@ class DB2Platform extends AbstractPlatform ...@@ -532,10 +536,6 @@ class DB2Platform extends AbstractPlatform
$sql, $sql,
$this->getPostAlterTableIndexForeignKeySQL($diff) $this->getPostAlterTableIndexForeignKeySQL($diff)
); );
if ($diff->newName !== false) {
$sql[] = 'RENAME TABLE ' . $diff->getName()->getQuotedName($this) . ' TO ' . $diff->getNewName()->getQuotedName($this);
}
} }
return array_merge($sql, $tableSql, $columnSql); return array_merge($sql, $tableSql, $columnSql);
...@@ -547,7 +547,7 @@ class DB2Platform extends AbstractPlatform ...@@ -547,7 +547,7 @@ class DB2Platform extends AbstractPlatform
protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
{ {
$sql = array(); $sql = array();
$table = $diff->getName()->getQuotedName($this); $table = $diff->getName($this)->getQuotedName($this);
foreach ($diff->removedIndexes as $remKey => $remIndex) { foreach ($diff->removedIndexes as $remKey => $remIndex) {
foreach ($diff->addedIndexes as $addKey => $addIndex) { foreach ($diff->addedIndexes as $addKey => $addIndex) {
......
...@@ -549,7 +549,7 @@ class DrizzlePlatform extends AbstractPlatform ...@@ -549,7 +549,7 @@ class DrizzlePlatform extends AbstractPlatform
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
if (count($queryParts) > 0) { if (count($queryParts) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . implode(", ", $queryParts); $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(", ", $queryParts);
} }
$sql = array_merge( $sql = array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPreAlterTableIndexForeignKeySQL($diff),
......
...@@ -593,7 +593,7 @@ class MySqlPlatform extends AbstractPlatform ...@@ -593,7 +593,7 @@ class MySqlPlatform extends AbstractPlatform
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
if (count($queryParts) > 0) { if (count($queryParts) > 0) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . implode(", ", $queryParts); $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . implode(", ", $queryParts);
} }
$sql = array_merge( $sql = array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff), $this->getPreAlterTableIndexForeignKeySQL($diff),
...@@ -611,7 +611,7 @@ class MySqlPlatform extends AbstractPlatform ...@@ -611,7 +611,7 @@ class MySqlPlatform extends AbstractPlatform
protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff) protected function getPreAlterTableIndexForeignKeySQL(TableDiff $diff)
{ {
$sql = array(); $sql = array();
$table = $diff->getName()->getQuotedName($this); $table = $diff->getName($this)->getQuotedName($this);
foreach ($diff->removedIndexes as $remKey => $remIndex) { foreach ($diff->removedIndexes as $remKey => $remIndex) {
// Dropping primary keys requires to unset autoincrement attribute on the particular column first. // Dropping primary keys requires to unset autoincrement attribute on the particular column first.
......
...@@ -374,8 +374,10 @@ class OraclePlatform extends AbstractPlatform ...@@ -374,8 +374,10 @@ class OraclePlatform extends AbstractPlatform
*/ */
public function getListSequencesSQL($database) public function getListSequencesSQL($database)
{ {
$database = $this->normalizeIdentifier($database);
return "SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ". return "SELECT sequence_name, min_value, increment_by FROM sys.all_sequences ".
"WHERE SEQUENCE_OWNER = '".strtoupper($database)."'"; "WHERE SEQUENCE_OWNER = '" . $database->getName() . "'";
} }
/** /**
...@@ -415,7 +417,7 @@ class OraclePlatform extends AbstractPlatform ...@@ -415,7 +417,7 @@ class OraclePlatform extends AbstractPlatform
*/ */
public function getListTableIndexesSQL($table, $currentDatabase = null) public function getListTableIndexesSQL($table, $currentDatabase = null)
{ {
$table = strtoupper($table); $table = $this->normalizeIdentifier($table);
return "SELECT uind.index_name AS name, " . return "SELECT uind.index_name AS name, " .
" uind.index_type AS type, " . " uind.index_type AS type, " .
...@@ -424,7 +426,8 @@ class OraclePlatform extends AbstractPlatform ...@@ -424,7 +426,8 @@ class OraclePlatform extends AbstractPlatform
" uind_col.column_position AS column_pos, " . " uind_col.column_position AS column_pos, " .
" (SELECT ucon.constraint_type FROM user_constraints ucon WHERE ucon.constraint_name = uind.index_name) AS is_primary ". " (SELECT ucon.constraint_type FROM user_constraints ucon WHERE ucon.constraint_name = uind.index_name) AS is_primary ".
"FROM user_indexes uind, user_ind_columns uind_col " . "FROM user_indexes uind, user_ind_columns uind_col " .
"WHERE uind.index_name = uind_col.index_name AND uind_col.table_name = '$table' ORDER BY uind_col.column_position ASC"; "WHERE uind.index_name = uind_col.index_name AND uind_col.table_name = '" . $table->getName() . "' " .
"ORDER BY uind_col.column_position ASC";
} }
/** /**
...@@ -468,45 +471,52 @@ class OraclePlatform extends AbstractPlatform ...@@ -468,45 +471,52 @@ class OraclePlatform extends AbstractPlatform
*/ */
public function getCreateAutoincrementSql($name, $table, $start = 1) public function getCreateAutoincrementSql($name, $table, $start = 1)
{ {
$table = strtoupper($table); $tableIdentifier = $this->normalizeIdentifier($table);
$name = strtoupper($name); $quotedTableName = $tableIdentifier->getQuotedName($this);
$unquotedTableName = $tableIdentifier->getName();
$nameIdentifier = $this->normalizeIdentifier($name);
$quotedName = $nameIdentifier->getQuotedName($this);
$unquotedName = $nameIdentifier->getName();
$sql = array(); $sql = array();
$indexName = $table . '_AI_PK'; $autoincrementIdentifierName = $this->getAutoincrementIdentifierName($tableIdentifier);
$idx = new Index($indexName, array($name), true, true); $idx = new Index($autoincrementIdentifierName, array($quotedName), true, true);
$sql[] = 'DECLARE $sql[] = 'DECLARE
constraints_Count NUMBER; constraints_Count NUMBER;
BEGIN BEGIN
SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \''.$table.'\' AND CONSTRAINT_TYPE = \'P\'; SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = \'' . $unquotedTableName . '\' AND CONSTRAINT_TYPE = \'P\';
IF constraints_Count = 0 OR constraints_Count = \'\' THEN IF constraints_Count = 0 OR constraints_Count = \'\' THEN
EXECUTE IMMEDIATE \''.$this->getCreateConstraintSQL($idx, $table).'\'; EXECUTE IMMEDIATE \''.$this->getCreateConstraintSQL($idx, $quotedTableName).'\';
END IF; END IF;
END;'; END;';
$sequenceName = $this->getIdentitySequenceName($table, $name); $sequenceName = $this->getIdentitySequenceName(
$tableIdentifier->isQuoted() ? $quotedTableName : $unquotedTableName,
$nameIdentifier->isQuoted() ? $quotedName : $unquotedName
);
$sequence = new Sequence($sequenceName, $start); $sequence = new Sequence($sequenceName, $start);
$sql[] = $this->getCreateSequenceSQL($sequence); $sql[] = $this->getCreateSequenceSQL($sequence);
$triggerName = $table . '_AI_PK'; $sql[] = 'CREATE TRIGGER ' . $autoincrementIdentifierName . '
$sql[] = 'CREATE TRIGGER ' . $triggerName . '
BEFORE INSERT BEFORE INSERT
ON ' . $table . ' ON ' . $quotedTableName . '
FOR EACH ROW FOR EACH ROW
DECLARE DECLARE
last_Sequence NUMBER; last_Sequence NUMBER;
last_InsertID NUMBER; last_InsertID NUMBER;
BEGIN BEGIN
SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL; SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $quotedName . ' FROM DUAL;
IF (:NEW.' . $name . ' IS NULL OR :NEW.'.$name.' = 0) THEN IF (:NEW.' . $quotedName . ' IS NULL OR :NEW.'.$quotedName.' = 0) THEN
SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $name . ' FROM DUAL; SELECT ' . $sequenceName . '.NEXTVAL INTO :NEW.' . $quotedName . ' FROM DUAL;
ELSE ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences FROM User_Sequences
WHERE Sequence_Name = \'' . $sequenceName . '\'; WHERE Sequence_Name = \'' . $sequence->getName() . '\';
SELECT :NEW.' . $name . ' INTO last_InsertID FROM DUAL; SELECT :NEW.' . $quotedName . ' INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP WHILE (last_InsertID > last_Sequence) LOOP
SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL; SELECT ' . $sequenceName . '.NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP; END LOOP;
...@@ -517,22 +527,62 @@ END;'; ...@@ -517,22 +527,62 @@ END;';
} }
/** /**
* @param string $table * Returns the SQL statements to drop the autoincrement for the given table name.
*
* @param string $table The table name to drop the autoincrement for.
* *
* @return array * @return array
*/ */
public function getDropAutoincrementSql($table) public function getDropAutoincrementSql($table)
{ {
$table = strtoupper($table); $table = $this->normalizeIdentifier($table);
$trigger = $table . '_AI_PK'; $autoincrementIdentifierName = $this->getAutoincrementIdentifierName($table);
$identitySequenceName = $this->getIdentitySequenceName(
$table->isQuoted() ? $table->getQuotedName($this) : $table->getName(),
''
);
$sql[] = 'DROP TRIGGER ' . $trigger; return array(
$sql[] = $this->getDropSequenceSQL($table.'_SEQ'); 'DROP TRIGGER ' . $autoincrementIdentifierName,
$this->getDropSequenceSQL($identitySequenceName),
$this->getDropConstraintSQL($autoincrementIdentifierName, $table->getQuotedName($this)),
);
}
$indexName = $table . '_AI_PK'; /**
$sql[] = $this->getDropConstraintSQL($indexName, $table); * Normalizes the given identifier.
*
* Uppercases the given identifier if it is not quoted by intention
* to reflect Oracle's internal auto uppercasing strategy of unquoted identifiers.
*
* @param string $name The identifier to normalize.
*
* @return Identifier The normalized identifier.
*/
private function normalizeIdentifier($name)
{
$identifier = new Identifier($name);
return $sql; return $identifier->isQuoted() ? $identifier : new Identifier(strtoupper($name));
}
/**
* Returns the autoincrement primary key identifier name for the given table identifier.
*
* Quotes the autoincrement primary key identifier name
* if the given table name is quoted by intention.
*
* @param Identifier $table The table identifier to return the autoincrement primary key identifier name for.
*
* @return string
*/
private function getAutoincrementIdentifierName(Identifier $table)
{
$identifierName = $table->getName() . '_AI_PK';
return $table->isQuoted()
? $this->quoteSingleIdentifier($identifierName)
: $identifierName;
} }
/** /**
...@@ -540,7 +590,7 @@ END;'; ...@@ -540,7 +590,7 @@ END;';
*/ */
public function getListTableForeignKeysSQL($table) public function getListTableForeignKeysSQL($table)
{ {
$table = strtoupper($table); $table = $table = $this->normalizeIdentifier($table);
return "SELECT alc.constraint_name, return "SELECT alc.constraint_name,
alc.DELETE_RULE, alc.DELETE_RULE,
...@@ -559,7 +609,7 @@ LEFT JOIN user_cons_columns r_cols ...@@ -559,7 +609,7 @@ LEFT JOIN user_cons_columns r_cols
AND cols.position = r_cols.position AND cols.position = r_cols.position
WHERE alc.constraint_name = cols.constraint_name WHERE alc.constraint_name = cols.constraint_name
AND alc.constraint_type = 'R' AND alc.constraint_type = 'R'
AND alc.table_name = '".$table."' AND alc.table_name = '" . $table->getName() . "'
ORDER BY alc.constraint_name ASC, cols.position ASC"; ORDER BY alc.constraint_name ASC, cols.position ASC";
} }
...@@ -568,8 +618,9 @@ LEFT JOIN user_cons_columns r_cols ...@@ -568,8 +618,9 @@ LEFT JOIN user_cons_columns r_cols
*/ */
public function getListTableConstraintsSQL($table) public function getListTableConstraintsSQL($table)
{ {
$table = strtoupper($table); $table = $this->normalizeIdentifier($table);
return 'SELECT * FROM user_constraints WHERE table_name = \'' . $table . '\'';
return "SELECT * FROM user_constraints WHERE table_name = '" . $table->getName() . "'";
} }
/** /**
...@@ -577,22 +628,22 @@ LEFT JOIN user_cons_columns r_cols ...@@ -577,22 +628,22 @@ LEFT JOIN user_cons_columns r_cols
*/ */
public function getListTableColumnsSQL($table, $database = null) public function getListTableColumnsSQL($table, $database = null)
{ {
$table = strtoupper($table); $table = $this->normalizeIdentifier($table);
$tabColumnsTableName = "user_tab_columns"; $tabColumnsTableName = "user_tab_columns";
$colCommentsTableName = "user_col_comments"; $colCommentsTableName = "user_col_comments";
$ownerCondition = ''; $ownerCondition = '';
if (null !== $database) { if (null !== $database) {
$database = strtoupper($database); $database = $this->normalizeIdentifier($database);
$tabColumnsTableName = "all_tab_columns"; $tabColumnsTableName = "all_tab_columns";
$colCommentsTableName = "all_col_comments"; $colCommentsTableName = "all_col_comments";
$ownerCondition = "AND c.owner = '".$database."'"; $ownerCondition = "AND c.owner = '" . $database->getName() . "'";
} }
return "SELECT c.*, d.comments FROM $tabColumnsTableName c ". return "SELECT c.*, d.comments FROM $tabColumnsTableName c ".
"INNER JOIN " . $colCommentsTableName . " d ON d.TABLE_NAME = c.TABLE_NAME AND d.COLUMN_NAME = c.COLUMN_NAME ". "INNER JOIN " . $colCommentsTableName . " d ON d.TABLE_NAME = c.TABLE_NAME AND d.COLUMN_NAME = c.COLUMN_NAME ".
"WHERE c.table_name = '" . $table . "' ".$ownerCondition." ORDER BY c.column_name"; "WHERE c.table_name = '" . $table->getName() . "' ".$ownerCondition." ORDER BY c.column_name";
} }
/** /**
...@@ -649,12 +700,16 @@ LEFT JOIN user_cons_columns r_cols ...@@ -649,12 +700,16 @@ LEFT JOIN user_cons_columns r_cols
$fields[] = $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); $fields[] = $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
if ($comment = $this->getColumnComment($column)) { if ($comment = $this->getColumnComment($column)) {
$commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); $commentsSQL[] = $this->getCommentOnColumnSQL(
$diff->getName($this)->getQuotedName($this),
$column->getQuotedName($this),
$comment
);
} }
} }
if (count($fields)) { if (count($fields)) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ADD (' . implode(', ', $fields) . ')'; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ADD (' . implode(', ', $fields) . ')';
} }
$fields = array(); $fields = array();
...@@ -685,7 +740,7 @@ LEFT JOIN user_cons_columns r_cols ...@@ -685,7 +740,7 @@ LEFT JOIN user_cons_columns r_cols
$columnInfo = $column->toArray(); $columnInfo = $column->toArray();
if ( ! $columnDiff->hasChanged('notnull')) { if ( ! $columnDiff->hasChanged('notnull')) {
$columnInfo['notnull'] = false; unset($columnInfo['notnull']);
} }
$fields[] = $column->getQuotedName($this) . $this->getColumnDeclarationSQL('', $columnInfo); $fields[] = $column->getQuotedName($this) . $this->getColumnDeclarationSQL('', $columnInfo);
...@@ -693,15 +748,15 @@ LEFT JOIN user_cons_columns r_cols ...@@ -693,15 +748,15 @@ LEFT JOIN user_cons_columns r_cols
if ($columnHasChangedComment) { if ($columnHasChangedComment) {
$commentsSQL[] = $this->getCommentOnColumnSQL( $commentsSQL[] = $this->getCommentOnColumnSQL(
$diff->name, $diff->getName($this)->getQuotedName($this),
$column->getName(), $column->getQuotedName($this),
$this->getColumnComment($column) $this->getColumnComment($column)
); );
} }
} }
if (count($fields)) { if (count($fields)) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' MODIFY (' . implode(', ', $fields) . ')'; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' MODIFY (' . implode(', ', $fields) . ')';
} }
foreach ($diff->renamedColumns as $oldColumnName => $column) { foreach ($diff->renamedColumns as $oldColumnName => $column) {
...@@ -711,7 +766,7 @@ LEFT JOIN user_cons_columns r_cols ...@@ -711,7 +766,7 @@ LEFT JOIN user_cons_columns r_cols
$oldColumnName = new Identifier($oldColumnName); $oldColumnName = new Identifier($oldColumnName);
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) .
' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) .' TO ' . $column->getQuotedName($this); ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) .' TO ' . $column->getQuotedName($this);
} }
...@@ -725,17 +780,23 @@ LEFT JOIN user_cons_columns r_cols ...@@ -725,17 +780,23 @@ LEFT JOIN user_cons_columns r_cols
} }
if (count($fields)) { if (count($fields)) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' DROP (' . implode(', ', $fields).')'; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' DROP (' . implode(', ', $fields).')';
} }
$tableSql = array(); $tableSql = array();
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
$sql = array_merge($sql, $commentsSQL);
if ($diff->newName !== false) { if ($diff->newName !== false) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this); $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this);
} }
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL); $sql = array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff),
$sql,
$this->getPostAlterTableIndexForeignKeySQL($diff)
);
} }
return array_merge($sql, $tableSql, $columnSql); return array_merge($sql, $tableSql, $columnSql);
...@@ -751,7 +812,11 @@ LEFT JOIN user_cons_columns r_cols ...@@ -751,7 +812,11 @@ LEFT JOIN user_cons_columns r_cols
} else { } else {
$default = $this->getDefaultValueDeclarationSQL($field); $default = $this->getDefaultValueDeclarationSQL($field);
$notnull = empty($field['notnull']) ? ' NULL' : ' NOT NULL'; $notnull = '';
if (isset($field['notnull'])) {
$notnull = $field['notnull'] ? ' NOT NULL' : ' NULL';
}
$unique = (isset($field['unique']) && $field['unique']) ? $unique = (isset($field['unique']) && $field['unique']) ?
' ' . $this->getUniqueFieldDeclarationSQL() : ''; ' ' . $this->getUniqueFieldDeclarationSQL() : '';
...@@ -800,7 +865,18 @@ LEFT JOIN user_cons_columns r_cols ...@@ -800,7 +865,18 @@ LEFT JOIN user_cons_columns r_cols
*/ */
public function getIdentitySequenceName($tableName, $columnName) public function getIdentitySequenceName($tableName, $columnName)
{ {
return $tableName . '_' . $columnName . '_SEQ'; $table = new Identifier($tableName);
// No usage of column name to preserve BC compatibility with <2.5
$identitySequenceName = $table->getName() . '_SEQ';
if ($table->isQuoted()) {
$identitySequenceName = '"' . $identitySequenceName . '"';
}
$identitySequenceIdentifier = $this->normalizeIdentifier($identitySequenceName);
return $identitySequenceIdentifier->getQuotedName($this);
} }
/** /**
......
...@@ -453,9 +453,16 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -453,9 +453,16 @@ class PostgreSqlPlatform extends AbstractPlatform
} }
$query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray()); $query = 'ADD ' . $this->getColumnDeclarationSQL($column->getQuotedName($this), $column->toArray());
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
if ($comment = $this->getColumnComment($column)) {
$commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getName(), $comment); $comment = $this->getColumnComment($column);
if (null !== $comment && '' !== $comment) {
$commentsSQL[] = $this->getCommentOnColumnSQL(
$diff->getName($this)->getQuotedName($this),
$column->getQuotedName($this),
$comment
);
} }
} }
...@@ -465,7 +472,7 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -465,7 +472,7 @@ class PostgreSqlPlatform extends AbstractPlatform
} }
$query = 'DROP ' . $column->getQuotedName($this); $query = 'DROP ' . $column->getQuotedName($this);
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} }
foreach ($diff->changedColumns as $columnDiff) { foreach ($diff->changedColumns as $columnDiff) {
...@@ -486,7 +493,7 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -486,7 +493,7 @@ class PostgreSqlPlatform extends AbstractPlatform
// here was a server version check before, but DBAL API does not support this anymore. // here was a server version check before, but DBAL API does not support this anymore.
$query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this); $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $type->getSqlDeclaration($column->toArray(), $this);
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} }
if ($columnDiff->hasChanged('default') || $columnDiff->hasChanged('type')) { if ($columnDiff->hasChanged('default') || $columnDiff->hasChanged('type')) {
...@@ -494,12 +501,12 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -494,12 +501,12 @@ class PostgreSqlPlatform extends AbstractPlatform
? ' DROP DEFAULT' ? ' DROP DEFAULT'
: ' SET' . $this->getDefaultValueDeclarationSQL($column->toArray()); : ' SET' . $this->getDefaultValueDeclarationSQL($column->toArray());
$query = 'ALTER ' . $oldColumnName . $defaultClause; $query = 'ALTER ' . $oldColumnName . $defaultClause;
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} }
if ($columnDiff->hasChanged('notnull')) { if ($columnDiff->hasChanged('notnull')) {
$query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL'; $query = 'ALTER ' . $oldColumnName . ' ' . ($column->getNotNull() ? 'SET' : 'DROP') . ' NOT NULL';
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} }
if ($columnDiff->hasChanged('autoincrement')) { if ($columnDiff->hasChanged('autoincrement')) {
...@@ -508,27 +515,27 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -508,27 +515,27 @@ class PostgreSqlPlatform extends AbstractPlatform
$seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName); $seqName = $this->getIdentitySequenceName($diff->name, $oldColumnName);
$sql[] = "CREATE SEQUENCE " . $seqName; $sql[] = "CREATE SEQUENCE " . $seqName;
$sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ") FROM " . $diff->getName()->getQuotedName($this) . "))"; $sql[] = "SELECT setval('" . $seqName . "', (SELECT MAX(" . $oldColumnName . ") FROM " . $diff->getName($this)->getQuotedName($this) . "))";
$query = "ALTER " . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')"; $query = "ALTER " . $oldColumnName . " SET DEFAULT nextval('" . $seqName . "')";
$sql[] = "ALTER TABLE " . $diff->getName()->getQuotedName($this) . " " . $query; $sql[] = "ALTER TABLE " . $diff->getName($this)->getQuotedName($this) . " " . $query;
} else { } else {
// Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have // Drop autoincrement, but do NOT drop the sequence. It might be re-used by other tables or have
$query = "ALTER " . $oldColumnName . " " . "DROP DEFAULT"; $query = "ALTER " . $oldColumnName . " " . "DROP DEFAULT";
$sql[] = "ALTER TABLE " . $diff->getName()->getQuotedName($this) . " " . $query; $sql[] = "ALTER TABLE " . $diff->getName($this)->getQuotedName($this) . " " . $query;
} }
} }
if ($columnDiff->hasChanged('comment')) { if ($columnDiff->hasChanged('comment')) {
$commentsSQL[] = $this->getCommentOnColumnSQL( $commentsSQL[] = $this->getCommentOnColumnSQL(
$diff->name, $diff->getName($this)->getQuotedName($this),
$column->getName(), $column->getQuotedName($this),
$this->getColumnComment($column) $this->getColumnComment($column)
); );
} }
if ($columnDiff->hasChanged('length')) { if ($columnDiff->hasChanged('length')) {
$query = 'ALTER ' . $oldColumnName . ' TYPE ' . $column->getType()->getSqlDeclaration($column->toArray(), $this); $query = 'ALTER ' . $oldColumnName . ' TYPE ' . $column->getType()->getSqlDeclaration($column->toArray(), $this);
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} }
} }
...@@ -539,18 +546,24 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -539,18 +546,24 @@ class PostgreSqlPlatform extends AbstractPlatform
$oldColumnName = new Identifier($oldColumnName); $oldColumnName = new Identifier($oldColumnName);
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) .
' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . ' TO ' . $column->getQuotedName($this); ' RENAME COLUMN ' . $oldColumnName->getQuotedName($this) . ' TO ' . $column->getQuotedName($this);
} }
$tableSql = array(); $tableSql = array();
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
$sql = array_merge($sql, $commentsSQL);
if ($diff->newName !== false) { if ($diff->newName !== false) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this); $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' RENAME TO ' . $diff->getNewName()->getQuotedName($this);
} }
$sql = array_merge($this->getPreAlterTableIndexForeignKeySQL($diff), $sql, $this->getPostAlterTableIndexForeignKeySQL($diff), $commentsSQL); $sql = array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff),
$sql,
$this->getPostAlterTableIndexForeignKeySQL($diff)
);
} }
return array_merge($sql, $tableSql, $columnSql); return array_merge($sql, $tableSql, $columnSql);
...@@ -615,9 +628,12 @@ class PostgreSqlPlatform extends AbstractPlatform ...@@ -615,9 +628,12 @@ class PostgreSqlPlatform extends AbstractPlatform
*/ */
public function getCommentOnColumnSQL($tableName, $columnName, $comment) public function getCommentOnColumnSQL($tableName, $columnName, $comment)
{ {
$tableName = new Identifier($tableName);
$columnName = new Identifier($columnName);
$comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment); $comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment);
return "COMMENT ON COLUMN $tableName.$columnName IS $comment"; return "COMMENT ON COLUMN " . $tableName->getQuotedName($this) . "." . $columnName->getQuotedName($this) .
" IS $comment";
} }
/** /**
......
...@@ -143,8 +143,12 @@ class SQLAnywherePlatform extends AbstractPlatform ...@@ -143,8 +143,12 @@ class SQLAnywherePlatform extends AbstractPlatform
$comment = $this->getColumnComment($column); $comment = $this->getColumnComment($column);
if ($comment) { if (null !== $comment && '' !== $comment) {
$commentsSQL[] = $this->getCommentOnColumnSQL($diff->name, $column->getQuotedName($this), $comment); $commentsSQL[] = $this->getCommentOnColumnSQL(
$diff->getName($this)->getQuotedName($this),
$column->getQuotedName($this),
$comment
);
} }
} }
...@@ -173,7 +177,7 @@ class SQLAnywherePlatform extends AbstractPlatform ...@@ -173,7 +177,7 @@ class SQLAnywherePlatform extends AbstractPlatform
$column = $columnDiff->column; $column = $columnDiff->column;
$commentsSQL[] = $this->getCommentOnColumnSQL( $commentsSQL[] = $this->getCommentOnColumnSQL(
$diff->name, $diff->getName($this)->getQuotedName($this),
$column->getQuotedName($this), $column->getQuotedName($this),
$this->getColumnComment($column) $this->getColumnComment($column)
); );
...@@ -185,21 +189,27 @@ class SQLAnywherePlatform extends AbstractPlatform ...@@ -185,21 +189,27 @@ class SQLAnywherePlatform extends AbstractPlatform
continue; continue;
} }
$sql[] = $this->getAlterTableClause($diff->getName()) . ' ' . $sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' .
$this->getAlterTableRenameColumnClause($oldColumnName, $column); $this->getAlterTableRenameColumnClause($oldColumnName, $column);
} }
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
if ( ! empty($alterClauses)) { if ( ! empty($alterClauses)) {
$sql[] = $this->getAlterTableClause($diff->getName()) . ' ' . implode(", ", $alterClauses); $sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' . implode(", ", $alterClauses);
} }
$sql = array_merge($sql, $commentsSQL);
if ($diff->newName !== false) { if ($diff->newName !== false) {
$sql[] = $this->getAlterTableClause($diff->getName()) . ' ' . $sql[] = $this->getAlterTableClause($diff->getName($this)) . ' ' .
$this->getAlterTableRenameTableClause($diff->getNewName()); $this->getAlterTableRenameTableClause($diff->getNewName());
} }
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSQL); $sql = array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff),
$sql,
$this->getPostAlterTableIndexForeignKeySQL($diff)
);
} }
return array_merge($sql, $tableSql, $columnSql); return array_merge($sql, $tableSql, $columnSql);
...@@ -357,9 +367,12 @@ class SQLAnywherePlatform extends AbstractPlatform ...@@ -357,9 +367,12 @@ class SQLAnywherePlatform extends AbstractPlatform
*/ */
public function getCommentOnColumnSQL($tableName, $columnName, $comment) public function getCommentOnColumnSQL($tableName, $columnName, $comment)
{ {
$tableName = new Identifier($tableName);
$columnName = new Identifier($columnName);
$comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment); $comment = $comment === null ? 'NULL' : $this->quoteStringLiteral($comment);
return "COMMENT ON COLUMN $tableName.$columnName IS $comment"; return "COMMENT ON COLUMN " . $tableName->getQuotedName($this) . '.' . $columnName->getQuotedName($this) .
" IS $comment";
} }
/** /**
......
...@@ -501,12 +501,16 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -501,12 +501,16 @@ class SQLServerPlatform extends AbstractPlatform
$oldColumnName = new Identifier($oldColumnName); $oldColumnName = new Identifier($oldColumnName);
$sql[] = "sp_RENAME '" . $diff->name . "." . $oldColumnName->getQuotedName($this) . $sql[] = "sp_RENAME '" .
$diff->getName($this)->getQuotedName($this) . "." . $oldColumnName->getQuotedName($this) .
"', '" . $column->getQuotedName($this) . "', 'COLUMN'"; "', '" . $column->getQuotedName($this) . "', 'COLUMN'";
// Recreate default constraint with new column name if necessary (for future reference). // Recreate default constraint with new column name if necessary (for future reference).
if ($column->getDefault() !== null) { if ($column->getDefault() !== null) {
$queryParts[] = $this->getAlterTableDropDefaultConstraintClause($diff->name, $oldColumnName); $queryParts[] = $this->getAlterTableDropDefaultConstraintClause(
$diff->name,
$oldColumnName->getQuotedName($this)
);
$queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column); $queryParts[] = $this->getAlterTableAddDefaultConstraintClause($diff->name, $column);
} }
} }
...@@ -518,13 +522,13 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -518,13 +522,13 @@ class SQLServerPlatform extends AbstractPlatform
} }
foreach ($queryParts as $query) { foreach ($queryParts as $query) {
$sql[] = 'ALTER TABLE ' . $diff->getName()->getQuotedName($this) . ' ' . $query; $sql[] = 'ALTER TABLE ' . $diff->getName($this)->getQuotedName($this) . ' ' . $query;
} }
$sql = array_merge($sql, $this->_getAlterTableIndexForeignKeySQL($diff), $commentsSql); $sql = array_merge($sql, $commentsSql);
if ($diff->newName !== false) { if ($diff->newName !== false) {
$sql[] = "sp_RENAME '" . $diff->getName()->getQuotedName($this) . "', '" . $diff->getNewName()->getQuotedName($this) . "'"; $sql[] = "sp_RENAME '" . $diff->getName($this)->getQuotedName($this) . "', '" . $diff->getNewName()->getName() . "'";
/** /**
* Rename table's default constraints names * Rename table's default constraints names
...@@ -540,10 +544,16 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -540,10 +544,16 @@ class SQLServerPlatform extends AbstractPlatform
"'" . $this->generateIdentifierName($diff->newName) . "') + ''', ''OBJECT'';' " . "'" . $this->generateIdentifierName($diff->newName) . "') + ''', ''OBJECT'';' " .
"FROM sys.default_constraints dc " . "FROM sys.default_constraints dc " .
"JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id " . "JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id " .
"WHERE tbl.name = '" . $diff->getNewName()->getQuotedName($this) . "';" . "WHERE tbl.name = '" . $diff->getNewName()->getName() . "';" .
"EXEC sp_executesql @sql"; "EXEC sp_executesql @sql";
} }
$sql = array_merge(
$this->getPreAlterTableIndexForeignKeySQL($diff),
$sql,
$this->getPostAlterTableIndexForeignKeySQL($diff)
);
return array_merge($sql, $tableSql, $columnSql); return array_merge($sql, $tableSql, $columnSql);
} }
...@@ -719,10 +729,10 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -719,10 +729,10 @@ class SQLServerPlatform extends AbstractPlatform
$level2Name = null $level2Name = null
) { ) {
return "EXEC sp_addextendedproperty " . return "EXEC sp_addextendedproperty " .
"N'" . $name . "', N'" . $value . "', " . "N" . $this->quoteStringLiteral($name) . ", N" . $this->quoteStringLiteral($value) . ", " .
"N'" . $level0Type . "', " . $level0Name . ', ' . "N" . $this->quoteStringLiteral($level0Type) . ", " . $level0Name . ', ' .
"N'" . $level1Type . "', " . $level1Name . ', ' . "N" . $this->quoteStringLiteral($level1Type) . ", " . $level1Name . ', ' .
"N'" . $level2Type . "', " . $level2Name; "N" . $this->quoteStringLiteral($level2Type) . ", " . $level2Name;
} }
/** /**
...@@ -750,10 +760,10 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -750,10 +760,10 @@ class SQLServerPlatform extends AbstractPlatform
$level2Name = null $level2Name = null
) { ) {
return "EXEC sp_dropextendedproperty " . return "EXEC sp_dropextendedproperty " .
"N'" . $name . "', " . "N" . $this->quoteStringLiteral($name) . ", " .
"N'" . $level0Type . "', " . $level0Name . ', ' . "N" . $this->quoteStringLiteral($level0Type) . ", " . $level0Name . ', ' .
"N'" . $level1Type . "', " . $level1Name . ', ' . "N" . $this->quoteStringLiteral($level1Type) . ", " . $level1Name . ', ' .
"N'" . $level2Type . "', " . $level2Name; "N" . $this->quoteStringLiteral($level2Type) . ", " . $level2Name;
} }
/** /**
...@@ -783,10 +793,10 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -783,10 +793,10 @@ class SQLServerPlatform extends AbstractPlatform
$level2Name = null $level2Name = null
) { ) {
return "EXEC sp_updateextendedproperty " . return "EXEC sp_updateextendedproperty " .
"N'" . $name . "', N'" . $value . "', " . "N" . $this->quoteStringLiteral($name) . ", N" . $this->quoteStringLiteral($value) . ", " .
"N'" . $level0Type . "', " . $level0Name . ', ' . "N" . $this->quoteStringLiteral($level0Type) . ", " . $level0Name . ', ' .
"N'" . $level1Type . "', " . $level1Name . ', ' . "N" . $this->quoteStringLiteral($level1Type) . ", " . $level1Name . ', ' .
"N'" . $level2Type . "', " . $level2Name; "N" . $this->quoteStringLiteral($level2Type) . ", " . $level2Name;
} }
/** /**
...@@ -1175,7 +1185,7 @@ class SQLServerPlatform extends AbstractPlatform ...@@ -1175,7 +1185,7 @@ class SQLServerPlatform extends AbstractPlatform
//Remove ORDER BY from $query (including nested parentheses in order by list). //Remove ORDER BY from $query (including nested parentheses in order by list).
$query = preg_replace('/\s+ORDER\s+BY\s+([^()]+|\((?:(?:(?>[^()]+)|(?R))*)\))+/i', '', $query); $query = preg_replace('/\s+ORDER\s+BY\s+([^()]+|\((?:(?:(?>[^()]+)|(?R))*)\))+/i', '', $query);
$format = 'SELECT * FROM (%s) AS doctrine_tbl WHERE doctrine_rownum BETWEEN %d AND %d'; $format = 'SELECT * FROM (%s) AS doctrine_tbl WHERE doctrine_rownum BETWEEN %d AND %d ORDER BY doctrine_rownum';
// Pattern to match "main" SELECT ... FROM clause (including nested parentheses in select list). // Pattern to match "main" SELECT ... FROM clause (including nested parentheses in select list).
$selectFromPattern = '/^(\s*SELECT\s+(?:(.*)(?![^(]*\))))\sFROM\s/i'; $selectFromPattern = '/^(\s*SELECT\s+(?:(.*)(?![^(]*\))))\sFROM\s/i';
......
...@@ -645,13 +645,13 @@ class SqlitePlatform extends AbstractPlatform ...@@ -645,13 +645,13 @@ class SqlitePlatform extends AbstractPlatform
} }
$sql = array(); $sql = array();
$tableName = $diff->newName ?: $diff->name; $tableName = $diff->newName ? $diff->getNewName(): $diff->getName($this);
foreach ($this->getIndexesInAlteredTable($diff) as $index) { foreach ($this->getIndexesInAlteredTable($diff) as $index) {
if ($index->isPrimary()) { if ($index->isPrimary()) {
continue; continue;
} }
$sql[] = $this->getCreateIndexSQL($index, $tableName); $sql[] = $this->getCreateIndexSQL($index, $tableName->getQuotedName($this));
} }
return $sql; return $sql;
...@@ -836,7 +836,7 @@ class SqlitePlatform extends AbstractPlatform ...@@ -836,7 +836,7 @@ class SqlitePlatform extends AbstractPlatform
if ( ! $this->onSchemaAlterTable($diff, $tableSql)) { if ( ! $this->onSchemaAlterTable($diff, $tableSql)) {
$dataTable = new Table('__temp__'.$table->getName()); $dataTable = new Table('__temp__'.$table->getName());
$newTable = new Table($table->getName(), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions()); $newTable = new Table($table->getQuotedName($this), $columns, $this->getPrimaryIndexInAlteredTable($diff), $this->getForeignKeysInAlteredTable($diff), 0, $table->getOptions());
$newTable->addOption('alter', true); $newTable->addOption('alter', true);
$sql = $this->getPreAlterTableIndexForeignKeySQL($diff); $sql = $this->getPreAlterTableIndexForeignKeySQL($diff);
...@@ -849,7 +849,7 @@ class SqlitePlatform extends AbstractPlatform ...@@ -849,7 +849,7 @@ class SqlitePlatform extends AbstractPlatform
$sql[] = $this->getDropTableSQL($dataTable); $sql[] = $this->getDropTableSQL($dataTable);
if ($diff->newName && $diff->newName != $diff->name) { if ($diff->newName && $diff->newName != $diff->name) {
$renamedTable = new Identifier($diff->newName); $renamedTable = $diff->getNewName();
$sql[] = 'ALTER TABLE '.$newTable->getQuotedName($this).' RENAME TO '.$renamedTable->getQuotedName($this); $sql[] = 'ALTER TABLE '.$newTable->getQuotedName($this).' RENAME TO '.$renamedTable->getQuotedName($this);
} }
......
...@@ -276,26 +276,26 @@ class ExpressionBuilder ...@@ -276,26 +276,26 @@ class ExpressionBuilder
* Creates a IN () comparison expression with the given arguments. * Creates a IN () comparison expression with the given arguments.
* *
* @param string $x The field in string format to be inspected by IN() comparison. * @param string $x The field in string format to be inspected by IN() comparison.
* @param array $y The array of values to be used by IN() comparison. * @param string|array $y The placeholder or the array of values to be used by IN() comparison.
* *
* @return string * @return string
*/ */
public function in($x, array $y) public function in($x, $y)
{ {
return $this->comparison($x, 'IN', '('.implode(', ', $y).')'); return $this->comparison($x, 'IN', '('.implode(', ', (array) $y).')');
} }
/** /**
* Creates a NOT IN () comparison expression with the given arguments. * Creates a NOT IN () comparison expression with the given arguments.
* *
* @param string $x The field in string format to be inspected by NOT IN() comparison. * @param string $x The field in string format to be inspected by NOT IN() comparison.
* @param array $y The array of values to be used by NOT IN() comparison. * @param string|array $y The placeholder or the array of values to be used by NOT IN() comparison.
* *
* @return string * @return string
*/ */
public function notIn($x, array $y) public function notIn($x, $y)
{ {
return $this->comparison($x, 'NOT IN', '('.implode(', ', $y).')'); return $this->comparison($x, 'NOT IN', '('.implode(', ', (array) $y).')');
} }
/** /**
......
...@@ -90,6 +90,11 @@ class SQLParserUtils ...@@ -90,6 +90,11 @@ class SQLParserUtils
$arrayPositions = array(); $arrayPositions = array();
$bindIndex = -1; $bindIndex = -1;
if ($isPositional) {
ksort($params);
ksort($types);
}
foreach ($types as $name => $type) { foreach ($types as $name => $type) {
++$bindIndex; ++$bindIndex;
...@@ -113,6 +118,8 @@ class SQLParserUtils ...@@ -113,6 +118,8 @@ class SQLParserUtils
if ($isPositional) { if ($isPositional) {
$paramOffset = 0; $paramOffset = 0;
$queryOffset = 0; $queryOffset = 0;
$params = array_values($params);
$types = array_values($types);
foreach ($paramPos as $needle => $needlePos) { foreach ($paramPos as $needle => $needlePos) {
if ( ! isset($arrayPositions[$needle])) { if ( ! isset($arrayPositions[$needle])) {
......
...@@ -421,8 +421,11 @@ class Comparator ...@@ -421,8 +421,11 @@ class Comparator
} }
} }
// only allow to delete comment if its set to '' not to null. // A null value and an empty string are actually equal for a comment so they should not trigger a change.
if ($properties1['comment'] !== null && $properties1['comment'] != $properties2['comment']) { if ($properties1['comment'] !== $properties2['comment'] &&
! (null === $properties1['comment'] && '' === $properties2['comment']) &&
! (null === $properties2['comment'] && '' === $properties1['comment'])
) {
$changedProperties[] = 'comment'; $changedProperties[] = 'comment';
} }
......
...@@ -46,7 +46,9 @@ class DrizzleSchemaManager extends AbstractSchemaManager ...@@ -46,7 +46,9 @@ class DrizzleSchemaManager extends AbstractSchemaManager
'autoincrement' => (bool)$tableColumn['IS_AUTO_INCREMENT'], 'autoincrement' => (bool)$tableColumn['IS_AUTO_INCREMENT'],
'scale' => (int)$tableColumn['NUMERIC_SCALE'], 'scale' => (int)$tableColumn['NUMERIC_SCALE'],
'precision' => (int)$tableColumn['NUMERIC_PRECISION'], 'precision' => (int)$tableColumn['NUMERIC_PRECISION'],
'comment' => (isset($tableColumn['COLUMN_COMMENT']) ? $tableColumn['COLUMN_COMMENT'] : null), 'comment' => isset($tableColumn['COLUMN_COMMENT']) && '' !== $tableColumn['COLUMN_COMMENT']
? $tableColumn['COLUMN_COMMENT']
: null,
); );
$column = new Column($tableColumn['COLUMN_NAME'], Type::getType($type), $options); $column = new Column($tableColumn['COLUMN_NAME'], Type::getType($type), $options);
......
...@@ -187,7 +187,9 @@ class MySqlSchemaManager extends AbstractSchemaManager ...@@ -187,7 +187,9 @@ class MySqlSchemaManager extends AbstractSchemaManager
'scale' => null, 'scale' => null,
'precision' => null, 'precision' => null,
'autoincrement' => (bool) (strpos($tableColumn['extra'], 'auto_increment') !== false), 'autoincrement' => (bool) (strpos($tableColumn['extra'], 'auto_increment') !== false),
'comment' => isset($tableColumn['comment']) ? $tableColumn['comment'] : null, 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== ''
? $tableColumn['comment']
: null,
); );
if ($scale !== null && $precision !== null) { if ($scale !== null && $precision !== null) {
......
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
namespace Doctrine\DBAL\Schema; namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Types\Type;
/** /**
* Oracle Schema Manager. * Oracle Schema Manager.
* *
...@@ -36,7 +38,7 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -36,7 +38,7 @@ class OracleSchemaManager extends AbstractSchemaManager
{ {
$view = \array_change_key_case($view, CASE_LOWER); $view = \array_change_key_case($view, CASE_LOWER);
return new View($view['view_name'], $view['text']); return new View($this->getQuotedIdentifierName($view['view_name']), $view['text']);
} }
/** /**
...@@ -58,7 +60,7 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -58,7 +60,7 @@ class OracleSchemaManager extends AbstractSchemaManager
{ {
$table = \array_change_key_case($table, CASE_LOWER); $table = \array_change_key_case($table, CASE_LOWER);
return $table['table_name']; return $this->getQuotedIdentifierName($table['table_name']);
} }
/** /**
...@@ -84,7 +86,7 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -84,7 +86,7 @@ class OracleSchemaManager extends AbstractSchemaManager
$buffer['non_unique'] = ($tableIndex['is_unique'] == 0) ? true : false; $buffer['non_unique'] = ($tableIndex['is_unique'] == 0) ? true : false;
} }
$buffer['key_name'] = $keyName; $buffer['key_name'] = $keyName;
$buffer['column_name'] = $tableIndex['column_name']; $buffer['column_name'] = $this->getQuotedIdentifierName($tableIndex['column_name']);
$indexBuffer[] = $buffer; $indexBuffer[] = $buffer;
} }
...@@ -203,11 +205,13 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -203,11 +205,13 @@ class OracleSchemaManager extends AbstractSchemaManager
'length' => $length, 'length' => $length,
'precision' => $precision, 'precision' => $precision,
'scale' => $scale, 'scale' => $scale,
'comment' => (isset($tableColumn['comments'])) ? $tableColumn['comments'] : null, 'comment' => isset($tableColumn['comments']) && '' !== $tableColumn['comments']
? $tableColumn['comments']
: null,
'platformDetails' => array(), 'platformDetails' => array(),
); );
return new Column($tableColumn['column_name'], \Doctrine\DBAL\Types\Type::getType($type), $options); return new Column($this->getQuotedIdentifierName($tableColumn['column_name']), Type::getType($type), $options);
} }
/** /**
...@@ -224,22 +228,26 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -224,22 +228,26 @@ class OracleSchemaManager extends AbstractSchemaManager
} }
$list[$value['constraint_name']] = array( $list[$value['constraint_name']] = array(
'name' => $value['constraint_name'], 'name' => $this->getQuotedIdentifierName($value['constraint_name']),
'local' => array(), 'local' => array(),
'foreign' => array(), 'foreign' => array(),
'foreignTable' => $value['references_table'], 'foreignTable' => $value['references_table'],
'onDelete' => $value['delete_rule'], 'onDelete' => $value['delete_rule'],
); );
} }
$list[$value['constraint_name']]['local'][$value['position']] = $value['local_column'];
$list[$value['constraint_name']]['foreign'][$value['position']] = $value['foreign_column']; $localColumn = $this->getQuotedIdentifierName($value['local_column']);
$foreignColumn = $this->getQuotedIdentifierName($value['foreign_column']);
$list[$value['constraint_name']]['local'][$value['position']] = $localColumn;
$list[$value['constraint_name']]['foreign'][$value['position']] = $foreignColumn;
} }
$result = array(); $result = array();
foreach ($list as $constraint) { foreach ($list as $constraint) {
$result[] = new ForeignKeyConstraint( $result[] = new ForeignKeyConstraint(
array_values($constraint['local']), $constraint['foreignTable'], array_values($constraint['local']), $this->getQuotedIdentifierName($constraint['foreignTable']),
array_values($constraint['foreign']), $constraint['name'], array_values($constraint['foreign']), $this->getQuotedIdentifierName($constraint['name']),
array('onDelete' => $constraint['onDelete']) array('onDelete' => $constraint['onDelete'])
); );
} }
...@@ -254,7 +262,11 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -254,7 +262,11 @@ class OracleSchemaManager extends AbstractSchemaManager
{ {
$sequence = \array_change_key_case($sequence, CASE_LOWER); $sequence = \array_change_key_case($sequence, CASE_LOWER);
return new Sequence($sequence['sequence_name'], $sequence['increment_by'], $sequence['min_value']); return new Sequence(
$this->getQuotedIdentifierName($sequence['sequence_name']),
$sequence['increment_by'],
$sequence['min_value']
);
} }
/** /**
...@@ -323,4 +335,23 @@ class OracleSchemaManager extends AbstractSchemaManager ...@@ -323,4 +335,23 @@ class OracleSchemaManager extends AbstractSchemaManager
parent::dropTable($name); parent::dropTable($name);
} }
/**
* Returns the quoted representation of the given identifier name.
*
* Quotes non-uppercase identifiers explicitly to preserve case
* and thus make references to the particular identifier work.
*
* @param string $identifier The identifier to quote.
*
* @return string The quoted identifier.
*/
private function getQuotedIdentifierName($identifier)
{
if (preg_match('/[a-z]/', $identifier)) {
return $this->_platform->quoteIdentifier($identifier);
}
return $identifier;
}
} }
...@@ -436,7 +436,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager ...@@ -436,7 +436,9 @@ class PostgreSqlSchemaManager extends AbstractSchemaManager
'fixed' => $fixed, 'fixed' => $fixed,
'unsigned' => false, 'unsigned' => false,
'autoincrement' => $autoincrement, 'autoincrement' => $autoincrement,
'comment' => $tableColumn['comment'], 'comment' => isset($tableColumn['comment']) && $tableColumn['comment'] !== ''
? $tableColumn['comment']
: null,
); );
$column = new Column($tableColumn['field'], Type::getType($type), $options); $column = new Column($tableColumn['field'], Type::getType($type), $options);
......
...@@ -144,7 +144,9 @@ class SQLAnywhereSchemaManager extends AbstractSchemaManager ...@@ -144,7 +144,9 @@ class SQLAnywhereSchemaManager extends AbstractSchemaManager
'notnull' => (bool) $tableColumn['notnull'], 'notnull' => (bool) $tableColumn['notnull'],
'default' => $default, 'default' => $default,
'autoincrement' => (bool) $tableColumn['autoincrement'], 'autoincrement' => (bool) $tableColumn['autoincrement'],
'comment' => $tableColumn['comment'] 'comment' => isset($tableColumn['comment']) && '' !== $tableColumn['comment']
? $tableColumn['comment']
: null,
)); ));
} }
......
...@@ -183,7 +183,7 @@ class Table extends AbstractAsset ...@@ -183,7 +183,7 @@ class Table extends AbstractAsset
*/ */
public function dropIndex($indexName) public function dropIndex($indexName)
{ {
$indexName = strtolower($indexName); $indexName = $this->normalizeIdentifier($indexName);
if ( ! $this->hasIndex($indexName)) { if ( ! $this->hasIndex($indexName)) {
throw SchemaException::indexDoesNotExist($indexName, $this->_name); throw SchemaException::indexDoesNotExist($indexName, $this->_name);
} }
...@@ -222,8 +222,8 @@ class Table extends AbstractAsset ...@@ -222,8 +222,8 @@ class Table extends AbstractAsset
*/ */
public function renameIndex($oldIndexName, $newIndexName = null) public function renameIndex($oldIndexName, $newIndexName = null)
{ {
$oldIndexName = strtolower($oldIndexName); $oldIndexName = $this->normalizeIdentifier($oldIndexName);
$normalizedNewIndexName = strtolower($newIndexName); $normalizedNewIndexName = $this->normalizeIdentifier($newIndexName);
if ($oldIndexName === $normalizedNewIndexName) { if ($oldIndexName === $normalizedNewIndexName) {
return $this; return $this;
...@@ -287,7 +287,7 @@ class Table extends AbstractAsset ...@@ -287,7 +287,7 @@ class Table extends AbstractAsset
*/ */
private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = array(), array $options = array()) private function _createIndex(array $columnNames, $indexName, $isUnique, $isPrimary, array $flags = array(), array $options = array())
{ {
if (preg_match('(([^a-zA-Z0-9_]+))', $indexName)) { if (preg_match('(([^a-zA-Z0-9_]+))', $this->normalizeIdentifier($indexName))) {
throw SchemaException::indexNameInvalid($indexName); throw SchemaException::indexNameInvalid($indexName);
} }
...@@ -362,7 +362,7 @@ class Table extends AbstractAsset ...@@ -362,7 +362,7 @@ class Table extends AbstractAsset
*/ */
public function dropColumn($columnName) public function dropColumn($columnName)
{ {
$columnName = strtolower($columnName); $columnName = $this->normalizeIdentifier($columnName);
unset($this->_columns[$columnName]); unset($this->_columns[$columnName]);
return $this; return $this;
...@@ -469,7 +469,7 @@ class Table extends AbstractAsset ...@@ -469,7 +469,7 @@ class Table extends AbstractAsset
protected function _addColumn(Column $column) protected function _addColumn(Column $column)
{ {
$columnName = $column->getName(); $columnName = $column->getName();
$columnName = strtolower($columnName); $columnName = $this->normalizeIdentifier($columnName);
if (isset($this->_columns[$columnName])) { if (isset($this->_columns[$columnName])) {
throw SchemaException::columnAlreadyExists($this->getName(), $columnName); throw SchemaException::columnAlreadyExists($this->getName(), $columnName);
...@@ -497,7 +497,7 @@ class Table extends AbstractAsset ...@@ -497,7 +497,7 @@ class Table extends AbstractAsset
} }
$indexName = $indexCandidate->getName(); $indexName = $indexCandidate->getName();
$indexName = strtolower($indexName); $indexName = $this->normalizeIdentifier($indexName);
if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $indexCandidate->isPrimary())) { if (isset($this->_indexes[$indexName]) || ($this->_primaryKeyName != false && $indexCandidate->isPrimary())) {
throw SchemaException::indexAlreadyExists($indexName, $this->_name); throw SchemaException::indexAlreadyExists($indexName, $this->_name);
...@@ -535,7 +535,7 @@ class Table extends AbstractAsset ...@@ -535,7 +535,7 @@ class Table extends AbstractAsset
array_merge((array)$this->getName(), $constraint->getLocalColumns()), "fk", $this->_getMaxIdentifierLength() array_merge((array)$this->getName(), $constraint->getLocalColumns()), "fk", $this->_getMaxIdentifierLength()
); );
} }
$name = strtolower($name); $name = $this->normalizeIdentifier($name);
$this->_fkConstraints[$name] = $constraint; $this->_fkConstraints[$name] = $constraint;
// add an explicit index on the foreign key columns. If there is already an index that fulfils this requirements drop the request. // add an explicit index on the foreign key columns. If there is already an index that fulfils this requirements drop the request.
...@@ -553,7 +553,7 @@ class Table extends AbstractAsset ...@@ -553,7 +553,7 @@ class Table extends AbstractAsset
*/ */
public function hasForeignKey($constraintName) public function hasForeignKey($constraintName)
{ {
$constraintName = strtolower($constraintName); $constraintName = $this->normalizeIdentifier($constraintName);
return isset($this->_fkConstraints[$constraintName]); return isset($this->_fkConstraints[$constraintName]);
} }
...@@ -569,7 +569,7 @@ class Table extends AbstractAsset ...@@ -569,7 +569,7 @@ class Table extends AbstractAsset
*/ */
public function getForeignKey($constraintName) public function getForeignKey($constraintName)
{ {
$constraintName = strtolower($constraintName); $constraintName = $this->normalizeIdentifier($constraintName);
if (!$this->hasForeignKey($constraintName)) { if (!$this->hasForeignKey($constraintName)) {
throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name); throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
} }
...@@ -588,7 +588,7 @@ class Table extends AbstractAsset ...@@ -588,7 +588,7 @@ class Table extends AbstractAsset
*/ */
public function removeForeignKey($constraintName) public function removeForeignKey($constraintName)
{ {
$constraintName = strtolower($constraintName); $constraintName = $this->normalizeIdentifier($constraintName);
if (!$this->hasForeignKey($constraintName)) { if (!$this->hasForeignKey($constraintName)) {
throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name); throw SchemaException::foreignKeyDoesNotExist($constraintName, $this->_name);
} }
...@@ -631,7 +631,7 @@ class Table extends AbstractAsset ...@@ -631,7 +631,7 @@ class Table extends AbstractAsset
*/ */
public function hasColumn($columnName) public function hasColumn($columnName)
{ {
$columnName = $this->trimQuotes(strtolower($columnName)); $columnName = $this->normalizeIdentifier($columnName);
return isset($this->_columns[$columnName]); return isset($this->_columns[$columnName]);
} }
...@@ -647,7 +647,7 @@ class Table extends AbstractAsset ...@@ -647,7 +647,7 @@ class Table extends AbstractAsset
*/ */
public function getColumn($columnName) public function getColumn($columnName)
{ {
$columnName = strtolower($this->trimQuotes($columnName)); $columnName = $this->normalizeIdentifier($columnName);
if ( ! $this->hasColumn($columnName)) { if ( ! $this->hasColumn($columnName)) {
throw SchemaException::columnDoesNotExist($columnName, $this->_name); throw SchemaException::columnDoesNotExist($columnName, $this->_name);
} }
...@@ -704,7 +704,7 @@ class Table extends AbstractAsset ...@@ -704,7 +704,7 @@ class Table extends AbstractAsset
*/ */
public function hasIndex($indexName) public function hasIndex($indexName)
{ {
$indexName = strtolower($indexName); $indexName = $this->normalizeIdentifier($indexName);
return (isset($this->_indexes[$indexName])); return (isset($this->_indexes[$indexName]));
} }
...@@ -720,7 +720,7 @@ class Table extends AbstractAsset ...@@ -720,7 +720,7 @@ class Table extends AbstractAsset
*/ */
public function getIndex($indexName) public function getIndex($indexName)
{ {
$indexName = strtolower($indexName); $indexName = $this->normalizeIdentifier($indexName);
if ( ! $this->hasIndex($indexName)) { if ( ! $this->hasIndex($indexName)) {
throw SchemaException::indexDoesNotExist($indexName, $this->_name); throw SchemaException::indexDoesNotExist($indexName, $this->_name);
} }
...@@ -814,4 +814,18 @@ class Table extends AbstractAsset ...@@ -814,4 +814,18 @@ class Table extends AbstractAsset
$this->_fkConstraints[$k]->setLocalTable($this); $this->_fkConstraints[$k]->setLocalTable($this);
} }
} }
/**
* Normalizes a given identifier.
*
* Trims quotes and lowercases the given identifier.
*
* @param string $identifier The identifier to normalize.
*
* @return string The normalized identifier.
*/
private function normalizeIdentifier($identifier)
{
return $this->trimQuotes(strtolower($identifier));
}
} }
...@@ -19,6 +19,8 @@ ...@@ -19,6 +19,8 @@
namespace Doctrine\DBAL\Schema; namespace Doctrine\DBAL\Schema;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/** /**
* Table Diff. * Table Diff.
* *
...@@ -147,18 +149,22 @@ class TableDiff ...@@ -147,18 +149,22 @@ class TableDiff
} }
/** /**
* @param AbstractPlatform $platform The platform to use for retrieving this table diff's name.
*
* @return \Doctrine\DBAL\Schema\Identifier * @return \Doctrine\DBAL\Schema\Identifier
*/ */
public function getName() public function getName(AbstractPlatform $platform)
{ {
return new Identifier($this->name); return new Identifier(
$this->fromTable instanceof Table ? $this->fromTable->getQuotedName($platform) : $this->name
);
} }
/** /**
* @return \Doctrine\DBAL\Schema\Identifier * @return \Doctrine\DBAL\Schema\Identifier|boolean
*/ */
public function getNewName() public function getNewName()
{ {
return new Identifier($this->newName); return $this->newName ? new Identifier($this->newName) : $this->newName;
} }
} }
...@@ -62,7 +62,7 @@ class TimeType extends Type ...@@ -62,7 +62,7 @@ class TimeType extends Type
return $value; return $value;
} }
$val = \DateTime::createFromFormat($platform->getTimeFormatString(), $value); $val = \DateTime::createFromFormat('!' . $platform->getTimeFormatString(), $value);
if ( ! $val) { if ( ! $val) {
throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getTimeFormatString()); throw ConversionException::conversionFailedFormat($value, $this->getName(), $platform->getTimeFormatString());
} }
......
...@@ -403,6 +403,15 @@ SQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\""); ...@@ -403,6 +403,15 @@ SQLSTATE[HY000]: General error: 1 near \"MUUHAAAAHAAAA\"");
$this->assertSame($result, $conn->fetchColumn($statement, $params, $column, $types)); $this->assertSame($result, $conn->fetchColumn($statement, $params, $column, $types));
} }
public function testConnectionIsClosed()
{
$this->_conn->close();
$this->setExpectedException('Doctrine\\DBAL\\Exception\\DriverException');
$this->_conn->quoteIdentifier('Bug');
}
public function testFetchAll() public function testFetchAll()
{ {
$statement = 'SELECT * FROM foo WHERE bar = ?'; $statement = 'SELECT * FROM foo WHERE bar = ?';
......
...@@ -24,7 +24,7 @@ class PDOConnectionTest extends DbalFunctionalTestCase ...@@ -24,7 +24,7 @@ class PDOConnectionTest extends DbalFunctionalTestCase
$this->driverConnection = $this->_conn->getWrappedConnection(); $this->driverConnection = $this->_conn->getWrappedConnection();
if ( ! $this->_conn->getWrappedConnection() instanceof PDOConnection) { if ( ! $this->driverConnection instanceof PDOConnection) {
$this->markTestSkipped('PDO connection only test.'); $this->markTestSkipped('PDO connection only test.');
} }
} }
...@@ -33,4 +33,54 @@ class PDOConnectionTest extends DbalFunctionalTestCase ...@@ -33,4 +33,54 @@ class PDOConnectionTest extends DbalFunctionalTestCase
{ {
$this->assertFalse($this->driverConnection->requiresQueryForServerVersion()); $this->assertFalse($this->driverConnection->requiresQueryForServerVersion());
} }
/**
* @expectedException \Doctrine\DBAL\Driver\PDOException
*/
public function testThrowsWrappedExceptionOnConstruct()
{
new PDOConnection('foo');
}
/**
* @group DBAL-1022
*
* @expectedException \Doctrine\DBAL\Driver\PDOException
*/
public function testThrowsWrappedExceptionOnExec()
{
$this->driverConnection->exec('foo');
}
/**
* @expectedException \Doctrine\DBAL\Driver\PDOException
*/
public function testThrowsWrappedExceptionOnPrepare()
{
// Emulated prepared statements have to be disabled for this test
// so that PDO actually communicates with the database server to check the query.
$this->driverConnection->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
$this->driverConnection->prepare('foo');
// Some PDO adapters like PostgreSQL do not check the query server-side
// even though emulated prepared statements are disabled,
// so an exception is thrown only eventually.
// Skip the test otherwise.
$this->markTestSkipped(
sprintf(
'The PDO adapter %s does not check the query to be prepared server-side, ' .
'so no assertions can be made.',
$this->_conn->getDriver()->getName()
)
);
}
/**
* @expectedException \Doctrine\DBAL\Driver\PDOException
*/
public function testThrowsWrappedExceptionOnQuery()
{
$this->driverConnection->query('foo');
}
} }
...@@ -61,6 +61,7 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -61,6 +61,7 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
/** /**
* @group DBAL-472 * @group DBAL-472
* @group DBAL-1001
*/ */
public function testAlterTableColumnNotNull() public function testAlterTableColumnNotNull()
{ {
...@@ -70,6 +71,7 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -70,6 +71,7 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
$table->addColumn('id', 'integer'); $table->addColumn('id', 'integer');
$table->addColumn('foo', 'integer'); $table->addColumn('foo', 'integer');
$table->addColumn('bar', 'string');
$table->setPrimaryKey(array('id')); $table->setPrimaryKey(array('id'));
$this->_sm->dropAndCreateTable($table); $this->_sm->dropAndCreateTable($table);
...@@ -78,9 +80,11 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -78,9 +80,11 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->assertTrue($columns['id']->getNotnull()); $this->assertTrue($columns['id']->getNotnull());
$this->assertTrue($columns['foo']->getNotnull()); $this->assertTrue($columns['foo']->getNotnull());
$this->assertTrue($columns['bar']->getNotnull());
$diffTable = clone $table; $diffTable = clone $table;
$diffTable->changeColumn('foo', array('notnull' => false)); $diffTable->changeColumn('foo', array('notnull' => false));
$diffTable->changeColumn('bar', array('length' => 1024));
$this->_sm->alterTable($comparator->diffTable($table, $diffTable)); $this->_sm->alterTable($comparator->diffTable($table, $diffTable));
...@@ -88,6 +92,7 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -88,6 +92,7 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->assertTrue($columns['id']->getNotnull()); $this->assertTrue($columns['id']->getNotnull());
$this->assertFalse($columns['foo']->getNotnull()); $this->assertFalse($columns['foo']->getNotnull());
$this->assertTrue($columns['bar']->getNotnull());
} }
public function testListDatabases() public function testListDatabases()
...@@ -102,4 +107,115 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase ...@@ -102,4 +107,115 @@ class OracleSchemaManagerTest extends SchemaManagerFunctionalTestCase
$this->assertContains('c##test_create_database', $databases); $this->assertContains('c##test_create_database', $databases);
} }
/**
* @group DBAL-831
*/
public function testListTableDetailsWithDifferentIdentifierQuotingRequirements()
{
$primaryTableName = '"Primary_Table"';
$offlinePrimaryTable = new Schema\Table($primaryTableName);
$offlinePrimaryTable->addColumn(
'"Id"',
'integer',
array('autoincrement' => true, 'comment' => 'Explicit casing.')
);
$offlinePrimaryTable->addColumn('select', 'integer', array('comment' => 'Reserved keyword.'));
$offlinePrimaryTable->addColumn('foo', 'integer', array('comment' => 'Implicit uppercasing.'));
$offlinePrimaryTable->addColumn('BAR', 'integer');
$offlinePrimaryTable->addColumn('"BAZ"', 'integer');
$offlinePrimaryTable->addIndex(array('select'), 'from');
$offlinePrimaryTable->addIndex(array('foo'), 'foo_index');
$offlinePrimaryTable->addIndex(array('BAR'), 'BAR_INDEX');
$offlinePrimaryTable->addIndex(array('"BAZ"'), 'BAZ_INDEX');
$offlinePrimaryTable->setPrimaryKey(array('"Id"'));
$foreignTableName = 'foreign';
$offlineForeignTable = new Schema\Table($foreignTableName);
$offlineForeignTable->addColumn('id', 'integer', array('autoincrement' => true));
$offlineForeignTable->addColumn('"Fk"', 'integer');
$offlineForeignTable->addIndex(array('"Fk"'), '"Fk_index"');
$offlineForeignTable->addForeignKeyConstraint(
$primaryTableName,
array('"Fk"'),
array('"Id"'),
array(),
'"Primary_Table_Fk"'
);
$offlineForeignTable->setPrimaryKey(array('id'));
$this->_sm->tryMethod('dropTable', $foreignTableName);
$this->_sm->tryMethod('dropTable', $primaryTableName);
$this->_sm->createTable($offlinePrimaryTable);
$this->_sm->createTable($offlineForeignTable);
$onlinePrimaryTable = $this->_sm->listTableDetails($primaryTableName);
$onlineForeignTable = $this->_sm->listTableDetails($foreignTableName);
$platform = $this->_sm->getDatabasePlatform();
// Primary table assertions
$this->assertSame($primaryTableName, $onlinePrimaryTable->getQuotedName($platform));
$this->assertTrue($onlinePrimaryTable->hasColumn('"Id"'));
$this->assertSame('"Id"', $onlinePrimaryTable->getColumn('"Id"')->getQuotedName($platform));
$this->assertTrue($onlinePrimaryTable->hasPrimaryKey());
$this->assertSame(array('"Id"'), $onlinePrimaryTable->getPrimaryKey()->getQuotedColumns($platform));
$this->assertTrue($onlinePrimaryTable->hasColumn('select'));
$this->assertSame('"select"', $onlinePrimaryTable->getColumn('select')->getQuotedName($platform));
$this->assertTrue($onlinePrimaryTable->hasColumn('foo'));
$this->assertSame('FOO', $onlinePrimaryTable->getColumn('foo')->getQuotedName($platform));
$this->assertTrue($onlinePrimaryTable->hasColumn('BAR'));
$this->assertSame('BAR', $onlinePrimaryTable->getColumn('BAR')->getQuotedName($platform));
$this->assertTrue($onlinePrimaryTable->hasColumn('"BAZ"'));
$this->assertSame('BAZ', $onlinePrimaryTable->getColumn('"BAZ"')->getQuotedName($platform));
$this->assertTrue($onlinePrimaryTable->hasIndex('from'));
$this->assertTrue($onlinePrimaryTable->getIndex('from')->hasColumnAtPosition('"select"'));
$this->assertSame(array('"select"'), $onlinePrimaryTable->getIndex('from')->getQuotedColumns($platform));
$this->assertTrue($onlinePrimaryTable->hasIndex('foo_index'));
$this->assertTrue($onlinePrimaryTable->getIndex('foo_index')->hasColumnAtPosition('foo'));
$this->assertSame(array('FOO'), $onlinePrimaryTable->getIndex('foo_index')->getQuotedColumns($platform));
$this->assertTrue($onlinePrimaryTable->hasIndex('BAR_INDEX'));
$this->assertTrue($onlinePrimaryTable->getIndex('BAR_INDEX')->hasColumnAtPosition('BAR'));
$this->assertSame(array('BAR'), $onlinePrimaryTable->getIndex('BAR_INDEX')->getQuotedColumns($platform));
$this->assertTrue($onlinePrimaryTable->hasIndex('BAZ_INDEX'));
$this->assertTrue($onlinePrimaryTable->getIndex('BAZ_INDEX')->hasColumnAtPosition('"BAZ"'));
$this->assertSame(array('BAZ'), $onlinePrimaryTable->getIndex('BAZ_INDEX')->getQuotedColumns($platform));
// Foreign table assertions
$this->assertTrue($onlineForeignTable->hasColumn('id'));
$this->assertSame('ID', $onlineForeignTable->getColumn('id')->getQuotedName($platform));
$this->assertTrue($onlineForeignTable->hasPrimaryKey());
$this->assertSame(array('ID'), $onlineForeignTable->getPrimaryKey()->getQuotedColumns($platform));
$this->assertTrue($onlineForeignTable->hasColumn('"Fk"'));
$this->assertSame('"Fk"', $onlineForeignTable->getColumn('"Fk"')->getQuotedName($platform));
$this->assertTrue($onlineForeignTable->hasIndex('"Fk_index"'));
$this->assertTrue($onlineForeignTable->getIndex('"Fk_index"')->hasColumnAtPosition('"Fk"'));
$this->assertSame(array('"Fk"'), $onlineForeignTable->getIndex('"Fk_index"')->getQuotedColumns($platform));
$this->assertTrue($onlineForeignTable->hasForeignKey('"Primary_Table_Fk"'));
$this->assertSame(
$primaryTableName,
$onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignTableName($platform)
);
$this->assertSame(
array('"Fk"'),
$onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedLocalColumns($platform)
);
$this->assertSame(
array('"Id"'),
$onlineForeignTable->getForeignKey('"Primary_Table_Fk"')->getQuotedForeignColumns($platform)
);
}
} }
...@@ -887,4 +887,71 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest ...@@ -887,4 +887,71 @@ class SchemaManagerFunctionalTestCase extends \Doctrine\Tests\DbalFunctionalTest
$columns = $this->_sm->listTableColumns("my_table"); $columns = $this->_sm->listTableColumns("my_table");
$this->assertEquals("It's a comment with a quote", $columns['id']->getComment()); $this->assertEquals("It's a comment with a quote", $columns['id']->getComment());
} }
/**
* @group DBAL-1009
*
* @dataProvider getAlterColumnComment
*/
public function testAlterColumnComment($comment1, $expectedComment1, $comment2, $expectedComment2)
{
if ( ! $this->_conn->getDatabasePlatform()->supportsInlineColumnComments() &&
! $this->_conn->getDatabasePlatform()->supportsCommentOnStatement() &&
$this->_conn->getDatabasePlatform()->getName() != 'mssql') {
$this->markTestSkipped('Database does not support column comments.');
}
$offlineTable = new Table('alter_column_comment_test');
$offlineTable->addColumn('comment1', 'integer', array('comment' => $comment1));
$offlineTable->addColumn('comment2', 'integer', array('comment' => $comment2));
$offlineTable->addColumn('no_comment1', 'integer');
$offlineTable->addColumn('no_comment2', 'integer');
$this->_sm->dropAndCreateTable($offlineTable);
$onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
$this->assertSame($expectedComment1, $onlineTable->getColumn('comment1')->getComment());
$this->assertSame($expectedComment2, $onlineTable->getColumn('comment2')->getComment());
$this->assertNull($onlineTable->getColumn('no_comment1')->getComment());
$this->assertNull($onlineTable->getColumn('no_comment2')->getComment());
$onlineTable->changeColumn('comment1', array('comment' => $comment2));
$onlineTable->changeColumn('comment2', array('comment' => $comment1));
$onlineTable->changeColumn('no_comment1', array('comment' => $comment1));
$onlineTable->changeColumn('no_comment2', array('comment' => $comment2));
$comparator = new Comparator();
$tableDiff = $comparator->diffTable($offlineTable, $onlineTable);
$this->assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
$this->_sm->alterTable($tableDiff);
$onlineTable = $this->_sm->listTableDetails("alter_column_comment_test");
$this->assertSame($expectedComment2, $onlineTable->getColumn('comment1')->getComment());
$this->assertSame($expectedComment1, $onlineTable->getColumn('comment2')->getComment());
$this->assertSame($expectedComment1, $onlineTable->getColumn('no_comment1')->getComment());
$this->assertSame($expectedComment2, $onlineTable->getColumn('no_comment2')->getComment());
}
public function getAlterColumnComment()
{
return array(
array(null, null, ' ', ' '),
array(null, null, '0', '0'),
array(null, null, 'foo', 'foo'),
array('', null, ' ', ' '),
array('', null, '0', '0'),
array('', null, 'foo', 'foo'),
array(' ', ' ', '0', '0'),
array(' ', ' ', 'foo', 'foo'),
array('0', '0', 'foo', 'foo'),
);
}
} }
...@@ -39,6 +39,8 @@ class DBAL421Test extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -39,6 +39,8 @@ class DBAL421Test extends \Doctrine\Tests\DbalFunctionalTestCase
$this->assertNotContains($guid, $guids, "Duplicate GUID detected"); $this->assertNotContains($guid, $guids, "Duplicate GUID detected");
$guids[] = $guid; $guids[] = $guid;
} }
$statement->closeCursor();
} }
private function getSelectGuidSql() private function getSelectGuidSql()
......
...@@ -59,7 +59,7 @@ class TypeConversionTest extends \Doctrine\Tests\DbalFunctionalTestCase ...@@ -59,7 +59,7 @@ class TypeConversionTest extends \Doctrine\Tests\DbalFunctionalTestCase
array('datetime', new \DateTime('2010-04-05 10:10:10'), 'DateTime'), array('datetime', new \DateTime('2010-04-05 10:10:10'), 'DateTime'),
array('datetimetz', new \DateTime('2010-04-05 10:10:10'), 'DateTime'), array('datetimetz', new \DateTime('2010-04-05 10:10:10'), 'DateTime'),
array('date', new \DateTime('2010-04-05'), 'DateTime'), array('date', new \DateTime('2010-04-05'), 'DateTime'),
array('time', new \DateTime('10:10:10'), 'DateTime'), array('time', new \DateTime('1970-01-01 10:10:10'), 'DateTime'),
array('text', str_repeat('foo ', 1000), 'string'), array('text', str_repeat('foo ', 1000), 'string'),
array('array', array('foo' => 'bar'), 'array'), array('array', array('foo' => 'bar'), 'array'),
array('json_array', array('foo' => 'bar'), 'array'), array('json_array', array('foo' => 'bar'), 'array'),
......
...@@ -604,4 +604,41 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase ...@@ -604,4 +604,41 @@ abstract class AbstractMySQLPlatformTestCase extends AbstractPlatformTestCase
{ {
$this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array())); $this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array()));
} }
/**
* {@inheritdoc}
*/
public function getAlterTableRenameColumnSQL()
{
return array(
"ALTER TABLE foo CHANGE bar baz INT DEFAULT 666 NOT NULL COMMENT 'rename test'",
);
}
/**
* {@inheritdoc}
*/
protected function getQuotesTableIdentifiersInAlterTableSQL()
{
return array(
'ALTER TABLE `foo` DROP FOREIGN KEY fk1',
'ALTER TABLE `foo` DROP FOREIGN KEY fk2',
'ALTER TABLE `foo` RENAME TO `table`, ADD bloo INT NOT NULL, DROP baz, CHANGE bar bar INT DEFAULT NULL, ' .
'CHANGE id war INT NOT NULL',
'ALTER TABLE `table` ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
'ALTER TABLE `table` ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
);
}
/**
* {@inheritdoc}
*/
protected function getCommentOnColumnSQL()
{
return array(
"COMMENT ON COLUMN foo.bar IS 'comment'",
"COMMENT ON COLUMN `Foo`.`BAR` IS 'comment'",
"COMMENT ON COLUMN `select`.`from` IS 'comment'",
);
}
} }
...@@ -5,6 +5,8 @@ namespace Doctrine\Tests\DBAL\Platforms; ...@@ -5,6 +5,8 @@ namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\Common\EventManager; use Doctrine\Common\EventManager;
use Doctrine\DBAL\Events; use Doctrine\DBAL\Events;
use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Index;
...@@ -914,6 +916,28 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase ...@@ -914,6 +916,28 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
); );
} }
/**
* @return array
*
* @see testGetCommentOnColumnSQL
*/
abstract protected function getCommentOnColumnSQL();
/**
* @group DBAL-1004
*/
public function testGetCommentOnColumnSQL()
{
$this->assertSame(
$this->getCommentOnColumnSQL(),
array(
$this->_platform->getCommentOnColumnSQL('foo', 'bar', 'comment'), // regular identifiers
$this->_platform->getCommentOnColumnSQL('`Foo`', '`BAR`', 'comment'), // explicitly quoted identifiers
$this->_platform->getCommentOnColumnSQL('select', 'from', 'comment'), // reserved keyword identifiers
)
);
}
protected function getQuotedStringLiteralWithoutQuoteCharacter() protected function getQuotedStringLiteralWithoutQuoteCharacter()
{ {
return "'No quote'"; return "'No quote'";
...@@ -956,4 +980,74 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase ...@@ -956,4 +980,74 @@ abstract class AbstractPlatformTestCase extends \Doctrine\Tests\DbalTestCase
{ {
$this->_platform->getGuidTypeDeclarationSQL(array()); $this->_platform->getGuidTypeDeclarationSQL(array());
} }
/**
* @group DBAL-1010
*/
public function testGeneratesAlterTableRenameColumnSQL()
{
$table = new Table('foo');
$table->addColumn(
'bar',
'integer',
array('notnull' => true, 'default' => 666, 'comment' => 'rename test')
);
$tableDiff = new TableDiff('foo');
$tableDiff->fromTable = $table;
$tableDiff->renamedColumns['bar'] = new Column(
'baz',
Type::getType('integer'),
array('notnull' => true, 'default' => 666, 'comment' => 'rename test')
);
$this->assertSame($this->getAlterTableRenameColumnSQL(), $this->_platform->getAlterTableSQL($tableDiff));
}
/**
* @return array
*/
abstract public function getAlterTableRenameColumnSQL();
/**
* @group DBAL-1016
*/
public function testQuotesTableIdentifiersInAlterTableSQL()
{
$table = new Table('"foo"');
$table->addColumn('id', 'integer');
$table->addColumn('fk', 'integer');
$table->addColumn('fk2', 'integer');
$table->addColumn('fk3', 'integer');
$table->addColumn('bar', 'integer');
$table->addColumn('baz', 'integer');
$table->addForeignKeyConstraint('fk_table', array('fk'), array('id'), array(), 'fk1');
$table->addForeignKeyConstraint('fk_table', array('fk2'), array('id'), array(), 'fk2');
$tableDiff = new TableDiff('"foo"');
$tableDiff->fromTable = $table;
$tableDiff->newName = 'table';
$tableDiff->addedColumns['bloo'] = new Column('bloo', Type::getType('integer'));
$tableDiff->changedColumns['bar'] = new ColumnDiff(
'bar',
new Column('bar', Type::getType('integer'), array('notnull' => false)),
array('notnull'),
$table->getColumn('bar')
);
$tableDiff->renamedColumns['id'] = new Column('war', Type::getType('integer'));
$tableDiff->removedColumns['baz'] = new Column('baz', Type::getType('integer'));
$tableDiff->addedForeignKeys[] = new ForeignKeyConstraint(array('fk3'), 'fk_table', array('id'), 'fk_add');
$tableDiff->changedForeignKeys[] = new ForeignKeyConstraint(array('fk2'), 'fk_table2', array('id'), 'fk2');
$tableDiff->removedForeignKeys[] = new ForeignKeyConstraint(array('fk'), 'fk_table', array('id'), 'fk1');
$this->assertSame(
$this->getQuotesTableIdentifiersInAlterTableSQL(),
$this->_platform->getAlterTableSQL($tableDiff)
);
}
/**
* @return array
*/
abstract protected function getQuotesTableIdentifiersInAlterTableSQL();
} }
...@@ -2,9 +2,11 @@ ...@@ -2,9 +2,11 @@
namespace Doctrine\Tests\DBAL\Platforms; namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Schema\TableDiff; use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\DBAL\Types\Type;
abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCase abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCase
{ {
...@@ -674,4 +676,67 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa ...@@ -674,4 +676,67 @@ abstract class AbstractPostgreSqlPlatformTestCase extends AbstractPlatformTestCa
{ {
$this->assertSame('UUID', $this->_platform->getGuidTypeDeclarationSQL(array())); $this->assertSame('UUID', $this->_platform->getGuidTypeDeclarationSQL(array()));
} }
/**
* {@inheritdoc}
*/
public function getAlterTableRenameColumnSQL()
{
return array(
'ALTER TABLE foo RENAME COLUMN bar TO baz',
);
}
/**
* {@inheritdoc}
*/
protected function getQuotesTableIdentifiersInAlterTableSQL()
{
return array(
'ALTER TABLE "foo" DROP CONSTRAINT fk1',
'ALTER TABLE "foo" DROP CONSTRAINT fk2',
'ALTER TABLE "foo" ADD bloo INT NOT NULL',
'ALTER TABLE "foo" DROP baz',
'ALTER TABLE "foo" ALTER bar DROP NOT NULL',
'ALTER TABLE "foo" RENAME COLUMN id TO war',
'ALTER TABLE "foo" RENAME TO "table"',
'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id) NOT DEFERRABLE ' .
'INITIALLY IMMEDIATE',
'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id) NOT DEFERRABLE ' .
'INITIALLY IMMEDIATE',
);
}
/**
* {@inheritdoc}
*/
protected function getCommentOnColumnSQL()
{
return array(
'COMMENT ON COLUMN foo.bar IS \'comment\'',
'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
'COMMENT ON COLUMN "select"."from" IS \'comment\'',
);
}
/**
* @group DBAL-1004
*/
public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers()
{
$table1 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'))));
$table2 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'), array('comment' => 'baz'))));
$comparator = new Comparator();
$tableDiff = $comparator->diffTable($table1, $table2);
$this->assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
$this->assertSame(
array(
'COMMENT ON COLUMN "foo"."bar" IS \'baz\'',
),
$this->_platform->getAlterTableSQL($tableDiff)
);
}
} }
...@@ -166,13 +166,13 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -166,13 +166,13 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
public function testModifyLimitQuery() public function testModifyLimitQuery()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 0); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10, 0);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithEmptyOffset() public function testModifyLimitQueryWithEmptyOffset()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithOffset() public function testModifyLimitQueryWithOffset()
...@@ -182,46 +182,46 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -182,46 +182,46 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
} }
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC', 10, 5); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC', 10, 5);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username DESC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username DESC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithAscOrderBy() public function testModifyLimitQueryWithAscOrderBy()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username ASC', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username ASC', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username ASC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username ASC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithLowercaseOrderBy() public function testModifyLimitQueryWithLowercaseOrderBy()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user order by username', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user order by username', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithDescOrderBy() public function testModifyLimitQueryWithDescOrderBy()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username DESC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username DESC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithMultipleOrderBy() public function testModifyLimitQueryWithMultipleOrderBy()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC, usereamil ASC', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM user ORDER BY username DESC, usereamil ASC', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username DESC, usereamil ASC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY username DESC, usereamil ASC) AS doctrine_rownum FROM user) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithSubSelect() public function testModifyLimitQueryWithSubSelect()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname) dctrn_result', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname) dctrn_result', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM (SELECT u.id as uid, u.name as uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM (SELECT u.id as uid, u.name as uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithSubSelectAndOrder() public function testModifyLimitQueryWithSubSelectAndOrder()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname ORDER BY u.name DESC) dctrn_result', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname ORDER BY u.name DESC) dctrn_result', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY u.name DESC) AS doctrine_rownum FROM (SELECT u.id as uid, u.name as uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY u.name DESC) AS doctrine_rownum FROM (SELECT u.id as uid, u.name as uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id, u.name ORDER BY u.name DESC) dctrn_result', 10); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id, u.name ORDER BY u.name DESC) dctrn_result', 10);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY name DESC) AS doctrine_rownum FROM (SELECT u.id, u.name) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY name DESC) AS doctrine_rownum FROM (SELECT u.id, u.name) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithSubSelectAndMultipleOrder() public function testModifyLimitQueryWithSubSelectAndMultipleOrder()
...@@ -231,19 +231,19 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -231,19 +231,19 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
} }
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname ORDER BY u.name DESC, id ASC) dctrn_result', 10, 5); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id as uid, u.name as uname ORDER BY u.name DESC, id ASC) dctrn_result', 10, 5);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY u.name DESC, id ASC) AS doctrine_rownum FROM (SELECT u.id as uid, u.name as uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY u.name DESC, id ASC) AS doctrine_rownum FROM (SELECT u.id as uid, u.name as uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15 ORDER BY doctrine_rownum', $sql);
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id uid, u.name uname ORDER BY u.name DESC, id ASC) dctrn_result', 10, 5); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id uid, u.name uname ORDER BY u.name DESC, id ASC) dctrn_result', 10, 5);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY u.name DESC, id ASC) AS doctrine_rownum FROM (SELECT u.id uid, u.name uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY u.name DESC, id ASC) AS doctrine_rownum FROM (SELECT u.id uid, u.name uname) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15 ORDER BY doctrine_rownum', $sql);
$sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id, u.name ORDER BY u.name DESC, id ASC) dctrn_result', 10, 5); $sql = $this->_platform->modifyLimitQuery('SELECT * FROM (SELECT u.id, u.name ORDER BY u.name DESC, id ASC) dctrn_result', 10, 5);
$this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY name DESC, id ASC) AS doctrine_rownum FROM (SELECT u.id, u.name) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15', $sql); $this->assertEquals('SELECT * FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY name DESC, id ASC) AS doctrine_rownum FROM (SELECT u.id, u.name) dctrn_result) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15 ORDER BY doctrine_rownum', $sql);
} }
public function testModifyLimitQueryWithFromColumnNames() public function testModifyLimitQueryWithFromColumnNames()
{ {
$sql = $this->_platform->modifyLimitQuery('SELECT a.fromFoo, fromBar FROM foo', 10); $sql = $this->_platform->modifyLimitQuery('SELECT a.fromFoo, fromBar FROM foo', 10);
$this->assertEquals('SELECT * FROM (SELECT a.fromFoo, fromBar, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM foo) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10', $sql); $this->assertEquals('SELECT * FROM (SELECT a.fromFoo, fromBar, ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum FROM foo) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum', $sql);
} }
/** /**
...@@ -263,7 +263,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -263,7 +263,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
$expected.= 'WHERE (table1.column1 = table2.column2) AND (table1.column1 = table3.column3) AND (table1.column1 = table4.column4) AND (table1.column1 = table5.column5) AND (table1.column1 = table6.column6) AND (table1.column1 = table7.column7) AND (table1.column1 = table8.column8) AND (table2.column2 = table3.column3) AND (table2.column2 = table4.column4) '; $expected.= 'WHERE (table1.column1 = table2.column2) AND (table1.column1 = table3.column3) AND (table1.column1 = table4.column4) AND (table1.column1 = table5.column5) AND (table1.column1 = table6.column6) AND (table1.column1 = table7.column7) AND (table1.column1 = table8.column8) AND (table2.column2 = table3.column3) AND (table2.column2 = table4.column4) ';
$expected.= 'AND (table2.column2 = table5.column5) AND (table2.column2 = table6.column6) AND (table2.column2 = table7.column7) AND (table2.column2 = table8.column8) AND (table3.column3 = table4.column4) AND (table3.column3 = table5.column5) AND (table3.column3 = table6.column6) AND (table3.column3 = table7.column7) AND (table3.column3 = table8.column8) AND (table4.column4 = table5.column5) AND (table4.column4 = table6.column6) '; $expected.= 'AND (table2.column2 = table5.column5) AND (table2.column2 = table6.column6) AND (table2.column2 = table7.column7) AND (table2.column2 = table8.column8) AND (table3.column3 = table4.column4) AND (table3.column3 = table5.column5) AND (table3.column3 = table6.column6) AND (table3.column3 = table7.column7) AND (table3.column3 = table8.column8) AND (table4.column4 = table5.column5) AND (table4.column4 = table6.column6) ';
$expected.= 'AND (table4.column4 = table7.column7) AND (table4.column4 = table8.column8) AND (table5.column5 = table6.column6) AND (table5.column5 = table7.column7) AND (table5.column5 = table8.column8) AND (table6.column6 = table7.column7) AND (table6.column6 = table8.column8) AND (table7.column7 = table8.column8)) '; $expected.= 'AND (table4.column4 = table7.column7) AND (table4.column4 = table8.column8) AND (table5.column5 = table6.column6) AND (table5.column5 = table7.column7) AND (table5.column5 = table8.column8) AND (table6.column6 = table7.column7) AND (table6.column6 = table8.column8) AND (table7.column7 = table8.column8)) ';
$expected.= 'AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10'; $expected.= 'AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum';
$this->assertEquals($expected, $sql); $this->assertEquals($expected, $sql);
} }
...@@ -278,7 +278,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -278,7 +278,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
} }
$sql = 'SELECT m0_.NOMBRE AS NOMBRE0, m0_.FECHAINICIO AS FECHAINICIO1, m0_.FECHAFIN AS FECHAFIN2 FROM MEDICION m0_ WITH (NOLOCK) INNER JOIN ESTUDIO e1_ ON m0_.ESTUDIO_ID = e1_.ID INNER JOIN CLIENTE c2_ ON e1_.CLIENTE_ID = c2_.ID INNER JOIN USUARIO u3_ ON c2_.ID = u3_.CLIENTE_ID WHERE u3_.ID = ? ORDER BY m0_.FECHAINICIO DESC'; $sql = 'SELECT m0_.NOMBRE AS NOMBRE0, m0_.FECHAINICIO AS FECHAINICIO1, m0_.FECHAFIN AS FECHAFIN2 FROM MEDICION m0_ WITH (NOLOCK) INNER JOIN ESTUDIO e1_ ON m0_.ESTUDIO_ID = e1_.ID INNER JOIN CLIENTE c2_ ON e1_.CLIENTE_ID = c2_.ID INNER JOIN USUARIO u3_ ON c2_.ID = u3_.CLIENTE_ID WHERE u3_.ID = ? ORDER BY m0_.FECHAINICIO DESC';
$expected = 'SELECT * FROM (SELECT m0_.NOMBRE AS NOMBRE0, m0_.FECHAINICIO AS FECHAINICIO1, m0_.FECHAFIN AS FECHAFIN2, ROW_NUMBER() OVER (ORDER BY m0_.FECHAINICIO DESC) AS doctrine_rownum FROM MEDICION m0_ WITH (NOLOCK) INNER JOIN ESTUDIO e1_ ON m0_.ESTUDIO_ID = e1_.ID INNER JOIN CLIENTE c2_ ON e1_.CLIENTE_ID = c2_.ID INNER JOIN USUARIO u3_ ON c2_.ID = u3_.CLIENTE_ID WHERE u3_.ID = ?) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15'; $expected = 'SELECT * FROM (SELECT m0_.NOMBRE AS NOMBRE0, m0_.FECHAINICIO AS FECHAINICIO1, m0_.FECHAFIN AS FECHAFIN2, ROW_NUMBER() OVER (ORDER BY m0_.FECHAINICIO DESC) AS doctrine_rownum FROM MEDICION m0_ WITH (NOLOCK) INNER JOIN ESTUDIO e1_ ON m0_.ESTUDIO_ID = e1_.ID INNER JOIN CLIENTE c2_ ON e1_.CLIENTE_ID = c2_.ID INNER JOIN USUARIO u3_ ON c2_.ID = u3_.CLIENTE_ID WHERE u3_.ID = ?) AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15 ORDER BY doctrine_rownum';
$actual = $this->_platform->modifyLimitQuery($sql, 10, 5); $actual = $this->_platform->modifyLimitQuery($sql, 10, 5);
$this->assertEquals($expected, $actual); $this->assertEquals($expected, $actual);
...@@ -310,7 +310,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -310,7 +310,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
"ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum " . "ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS doctrine_rownum " .
"FROM user u " . "FROM user u " .
"WHERE u.status = 'disabled'" . "WHERE u.status = 'disabled'" .
") AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10", ") AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 10 ORDER BY doctrine_rownum",
$sql $sql
); );
} }
...@@ -347,7 +347,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -347,7 +347,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
"ROW_NUMBER() OVER (ORDER BY username DESC) AS doctrine_rownum " . "ROW_NUMBER() OVER (ORDER BY username DESC) AS doctrine_rownum " .
"FROM user u " . "FROM user u " .
"WHERE u.status = 'disabled'" . "WHERE u.status = 'disabled'" .
") AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15", ") AS doctrine_tbl WHERE doctrine_rownum BETWEEN 6 AND 15 ORDER BY doctrine_rownum",
$sql $sql
); );
} }
...@@ -376,7 +376,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -376,7 +376,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
"ROW_NUMBER() OVER (ORDER BY MAX(heading_id) DESC) AS doctrine_rownum " . "ROW_NUMBER() OVER (ORDER BY MAX(heading_id) DESC) AS doctrine_rownum " .
"FROM operator_model_operator " . "FROM operator_model_operator " .
"GROUP BY code" . "GROUP BY code" .
") AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 1", ") AS doctrine_tbl WHERE doctrine_rownum BETWEEN 1 AND 1 ORDER BY doctrine_rownum",
$sql $sql
); );
} }
...@@ -525,11 +525,12 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -525,11 +525,12 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
$table->addColumn('create', 'integer', array('comment' => 'Doctrine 0wnz comments for reserved keyword columns!')); $table->addColumn('create', 'integer', array('comment' => 'Doctrine 0wnz comments for reserved keyword columns!'));
$table->addColumn('commented_type', 'object'); $table->addColumn('commented_type', 'object');
$table->addColumn('commented_type_with_comment', 'array', array('comment' => 'Doctrine array type.')); $table->addColumn('commented_type_with_comment', 'array', array('comment' => 'Doctrine array type.'));
$table->addColumn('comment_with_string_literal_char', 'string', array('comment' => "O'Reilly"));
$table->setPrimaryKey(array('id')); $table->setPrimaryKey(array('id'));
$this->assertEquals( $this->assertEquals(
array( array(
"CREATE TABLE mytable (id INT IDENTITY NOT NULL, comment_null INT NOT NULL, comment_false INT NOT NULL, comment_empty_string INT NOT NULL, comment_integer_0 INT NOT NULL, comment_float_0 INT NOT NULL, comment_string_0 INT NOT NULL, comment INT NOT NULL, [comment_quoted] INT NOT NULL, [create] INT NOT NULL, commented_type VARCHAR(MAX) NOT NULL, commented_type_with_comment VARCHAR(MAX) NOT NULL, PRIMARY KEY (id))", "CREATE TABLE mytable (id INT IDENTITY NOT NULL, comment_null INT NOT NULL, comment_false INT NOT NULL, comment_empty_string INT NOT NULL, comment_integer_0 INT NOT NULL, comment_float_0 INT NOT NULL, comment_string_0 INT NOT NULL, comment INT NOT NULL, [comment_quoted] INT NOT NULL, [create] INT NOT NULL, commented_type VARCHAR(MAX) NOT NULL, commented_type_with_comment VARCHAR(MAX) NOT NULL, comment_with_string_literal_char NVARCHAR(255) NOT NULL, PRIMARY KEY (id))",
"EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_integer_0", "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_integer_0",
"EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_float_0", "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_float_0",
"EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_string_0", "EXEC sp_addextendedproperty N'MS_Description', N'0', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_string_0",
...@@ -538,6 +539,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -538,6 +539,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
"EXEC sp_addextendedproperty N'MS_Description', N'Doctrine 0wnz comments for reserved keyword columns!', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [create]", "EXEC sp_addextendedproperty N'MS_Description', N'Doctrine 0wnz comments for reserved keyword columns!', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [create]",
"EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type", "EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type",
"EXEC sp_addextendedproperty N'MS_Description', N'Doctrine array type.(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type_with_comment", "EXEC sp_addextendedproperty N'MS_Description', N'Doctrine array type.(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type_with_comment",
"EXEC sp_addextendedproperty N'MS_Description', N'O''Reilly', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_with_string_literal_char",
), ),
$this->_platform->getCreateTableSQL($table) $this->_platform->getCreateTableSQL($table)
); );
...@@ -545,6 +547,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -545,6 +547,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
/** /**
* @group DBAL-543 * @group DBAL-543
* @group DBAL-1011
*/ */
public function testGeneratesAlterTableSQLWithColumnComments() public function testGeneratesAlterTableSQLWithColumnComments()
{ {
...@@ -561,6 +564,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -561,6 +564,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
$table->addColumn('create', 'integer', array('comment' => 'Doctrine 0wnz comments for reserved keyword columns!')); $table->addColumn('create', 'integer', array('comment' => 'Doctrine 0wnz comments for reserved keyword columns!'));
$table->addColumn('commented_type', 'object'); $table->addColumn('commented_type', 'object');
$table->addColumn('commented_type_with_comment', 'array', array('comment' => 'Doctrine array type.')); $table->addColumn('commented_type_with_comment', 'array', array('comment' => 'Doctrine array type.'));
$table->addColumn('comment_with_string_literal_quote_char', 'array', array('comment' => "O'Reilly"));
$table->setPrimaryKey(array('id')); $table->setPrimaryKey(array('id'));
$tableDiff = new TableDiff('mytable'); $tableDiff = new TableDiff('mytable');
...@@ -577,6 +581,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -577,6 +581,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
$tableDiff->addedColumns['select'] = new Column('select', Type::getType('integer'), array('comment' => '666')); $tableDiff->addedColumns['select'] = new Column('select', Type::getType('integer'), array('comment' => '666'));
$tableDiff->addedColumns['added_commented_type'] = new Column('added_commented_type', Type::getType('object')); $tableDiff->addedColumns['added_commented_type'] = new Column('added_commented_type', Type::getType('object'));
$tableDiff->addedColumns['added_commented_type_with_comment'] = new Column('added_commented_type_with_comment', Type::getType('array'), array('comment' => '666')); $tableDiff->addedColumns['added_commented_type_with_comment'] = new Column('added_commented_type_with_comment', Type::getType('array'), array('comment' => '666'));
$tableDiff->addedColumns['added_comment_with_string_literal_char'] = new Column('added_comment_with_string_literal_char', Type::getType('string'), array('comment' => "''"));
$tableDiff->renamedColumns['comment_float_0'] = new Column('comment_double_0', Type::getType('decimal'), array('comment' => 'Double for real!')); $tableDiff->renamedColumns['comment_float_0'] = new Column('comment_double_0', Type::getType('decimal'), array('comment' => 'Double for real!'));
...@@ -660,6 +665,14 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -660,6 +665,14 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
new Column('commented_type_with_comment', Type::getType('array'), array('comment' => 'Doctrine array type.')) new Column('commented_type_with_comment', Type::getType('array'), array('comment' => 'Doctrine array type.'))
); );
// Change comment from comment with string literal char column.
$tableDiff->changedColumns['comment_with_string_literal_char'] = new ColumnDiff(
'comment_with_string_literal_char',
new Column('comment_with_string_literal_char', Type::getType('string'), array('comment' => "'")),
array('comment'),
new Column('comment_with_string_literal_char', Type::getType('array'), array('comment' => "O'Reilly"))
);
$tableDiff->removedColumns['comment_integer_0'] = new Column('comment_integer_0', Type::getType('integer'), array('comment' => 0)); $tableDiff->removedColumns['comment_integer_0'] = new Column('comment_integer_0', Type::getType('integer'), array('comment' => 0));
$this->assertEquals( $this->assertEquals(
...@@ -680,6 +693,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -680,6 +693,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
"ALTER TABLE mytable ADD [select] INT NOT NULL", "ALTER TABLE mytable ADD [select] INT NOT NULL",
"ALTER TABLE mytable ADD added_commented_type VARCHAR(MAX) NOT NULL", "ALTER TABLE mytable ADD added_commented_type VARCHAR(MAX) NOT NULL",
"ALTER TABLE mytable ADD added_commented_type_with_comment VARCHAR(MAX) NOT NULL", "ALTER TABLE mytable ADD added_commented_type_with_comment VARCHAR(MAX) NOT NULL",
"ALTER TABLE mytable ADD added_comment_with_string_literal_char NVARCHAR(255) NOT NULL",
"ALTER TABLE mytable DROP COLUMN comment_integer_0", "ALTER TABLE mytable DROP COLUMN comment_integer_0",
"ALTER TABLE mytable ALTER COLUMN comment_null NVARCHAR(255) NOT NULL", "ALTER TABLE mytable ALTER COLUMN comment_null NVARCHAR(255) NOT NULL",
"ALTER TABLE mytable ALTER COLUMN comment_empty_string VARCHAR(MAX) NOT NULL", "ALTER TABLE mytable ALTER COLUMN comment_empty_string VARCHAR(MAX) NOT NULL",
...@@ -696,6 +710,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -696,6 +710,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
"EXEC sp_addextendedproperty N'MS_Description', N'666', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [select]", "EXEC sp_addextendedproperty N'MS_Description', N'666', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [select]",
"EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_commented_type", "EXEC sp_addextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_commented_type",
"EXEC sp_addextendedproperty N'MS_Description', N'666(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_commented_type_with_comment", "EXEC sp_addextendedproperty N'MS_Description', N'666(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_commented_type_with_comment",
"EXEC sp_addextendedproperty N'MS_Description', N'''''', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', added_comment_with_string_literal_char",
// Changed columns. // Changed columns.
"EXEC sp_addextendedproperty N'MS_Description', N'primary', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', id", "EXEC sp_addextendedproperty N'MS_Description', N'primary', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', id",
...@@ -707,6 +722,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -707,6 +722,7 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
"EXEC sp_updateextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [create]", "EXEC sp_updateextendedproperty N'MS_Description', N'(DC2Type:object)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', [create]",
"EXEC sp_updateextendedproperty N'MS_Description', N'foo', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type", "EXEC sp_updateextendedproperty N'MS_Description', N'foo', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type",
"EXEC sp_updateextendedproperty N'MS_Description', N'(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type_with_comment", "EXEC sp_updateextendedproperty N'MS_Description', N'(DC2Type:array)', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', commented_type_with_comment",
"EXEC sp_updateextendedproperty N'MS_Description', N'''', N'SCHEMA', dbo, N'TABLE', mytable, N'COLUMN', comment_with_string_literal_char",
), ),
$this->_platform->getAlterTableSQL($tableDiff) $this->_platform->getAlterTableSQL($tableDiff)
); );
...@@ -1109,4 +1125,50 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas ...@@ -1109,4 +1125,50 @@ abstract class AbstractSQLServerPlatformTestCase extends AbstractPlatformTestCas
{ {
$this->assertSame('UNIQUEIDENTIFIER', $this->_platform->getGuidTypeDeclarationSQL(array())); $this->assertSame('UNIQUEIDENTIFIER', $this->_platform->getGuidTypeDeclarationSQL(array()));
} }
/**
* {@inheritdoc}
*/
public function getAlterTableRenameColumnSQL()
{
return array(
"sp_RENAME 'foo.bar', 'baz', 'COLUMN'",
'ALTER TABLE foo DROP CONSTRAINT DF_8C736521_76FF8CAA',
'ALTER TABLE foo ADD CONSTRAINT DF_8C736521_78240498 DEFAULT 666 FOR baz',
);
}
/**
* {@inheritdoc}
*/
protected function getQuotesTableIdentifiersInAlterTableSQL()
{
return array(
'ALTER TABLE [foo] DROP CONSTRAINT fk1',
'ALTER TABLE [foo] DROP CONSTRAINT fk2',
"sp_RENAME '[foo].id', 'war', 'COLUMN'",
'ALTER TABLE [foo] ADD bloo INT NOT NULL',
'ALTER TABLE [foo] DROP COLUMN baz',
'ALTER TABLE [foo] ALTER COLUMN bar INT',
"sp_RENAME '[foo]', 'table'",
"DECLARE @sql NVARCHAR(MAX) = N''; " .
"SELECT @sql += N'EXEC sp_rename N''' + dc.name + ''', N''' + REPLACE(dc.name, '8C736521', 'F6298F46') + ''', " .
"''OBJECT'';' FROM sys.default_constraints dc JOIN sys.tables tbl ON dc.parent_object_id = tbl.object_id " .
"WHERE tbl.name = 'table';EXEC sp_executesql @sql",
'ALTER TABLE [table] ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
'ALTER TABLE [table] ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
);
}
/**
* {@inheritdoc}
*/
protected function getCommentOnColumnSQL()
{
return array(
"COMMENT ON COLUMN foo.bar IS 'comment'",
"COMMENT ON COLUMN [Foo].[BAR] IS 'comment'",
"COMMENT ON COLUMN [select].[from] IS 'comment'",
);
}
} }
...@@ -471,4 +471,43 @@ class DB2PlatformTest extends AbstractPlatformTestCase ...@@ -471,4 +471,43 @@ class DB2PlatformTest extends AbstractPlatformTestCase
{ {
$this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array())); $this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array()));
} }
/**
* {@inheritdoc}
*/
public function getAlterTableRenameColumnSQL()
{
return array(
'ALTER TABLE foo RENAME COLUMN bar TO baz',
);
}
/**
* {@inheritdoc}
*/
protected function getQuotesTableIdentifiersInAlterTableSQL()
{
return array(
'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
'ALTER TABLE "foo" ADD COLUMN bloo INTEGER NOT NULL WITH DEFAULT DROP COLUMN baz ' .
'ALTER bar bar INTEGER DEFAULT NULL RENAME COLUMN id TO war',
'CALL SYSPROC.ADMIN_CMD (\'REORG TABLE "foo"\')',
'RENAME TABLE "foo" TO "table"',
'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
);
}
/**
* {@inheritdoc}
*/
protected function getCommentOnColumnSQL()
{
return array(
'COMMENT ON COLUMN foo.bar IS \'comment\'',
'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
'COMMENT ON COLUMN "select"."from" IS \'comment\'',
);
}
} }
...@@ -3,8 +3,10 @@ ...@@ -3,8 +3,10 @@
namespace Doctrine\Tests\DBAL\Platforms; namespace Doctrine\Tests\DBAL\Platforms;
use Doctrine\DBAL\Platforms\OraclePlatform; use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\Comparator; use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
use Doctrine\DBAL\Types\Type;
require_once __DIR__ . '/../../TestInit.php'; require_once __DIR__ . '/../../TestInit.php';
...@@ -235,8 +237,8 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -235,8 +237,8 @@ class OraclePlatformTest extends AbstractPlatformTestCase
$targets = array( $targets = array(
"CREATE TABLE {$tableName} ({$columnName} NUMBER(10) NOT NULL)", "CREATE TABLE {$tableName} ({$columnName} NUMBER(10) NOT NULL)",
"DECLARE constraints_Count NUMBER; BEGIN SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = '{$tableName}' AND CONSTRAINT_TYPE = 'P'; IF constraints_Count = 0 OR constraints_Count = '' THEN EXECUTE IMMEDIATE 'ALTER TABLE {$tableName} ADD CONSTRAINT {$tableName}_AI_PK PRIMARY KEY ({$columnName})'; END IF; END;", "DECLARE constraints_Count NUMBER; BEGIN SELECT COUNT(CONSTRAINT_NAME) INTO constraints_Count FROM USER_CONSTRAINTS WHERE TABLE_NAME = '{$tableName}' AND CONSTRAINT_TYPE = 'P'; IF constraints_Count = 0 OR constraints_Count = '' THEN EXECUTE IMMEDIATE 'ALTER TABLE {$tableName} ADD CONSTRAINT {$tableName}_AI_PK PRIMARY KEY ({$columnName})'; END IF; END;",
"CREATE SEQUENCE {$tableName}_{$columnName}_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1", "CREATE SEQUENCE {$tableName}_SEQ START WITH 1 MINVALUE 1 INCREMENT BY 1",
"CREATE TRIGGER {$tableName}_AI_PK BEFORE INSERT ON {$tableName} FOR EACH ROW DECLARE last_Sequence NUMBER; last_InsertID NUMBER; BEGIN SELECT {$tableName}_{$columnName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; IF (:NEW.{$columnName} IS NULL OR :NEW.{$columnName} = 0) THEN SELECT {$tableName}_{$columnName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence FROM User_Sequences WHERE Sequence_Name = '{$tableName}_{$columnName}_SEQ'; SELECT :NEW.{$columnName} INTO last_InsertID FROM DUAL; WHILE (last_InsertID > last_Sequence) LOOP SELECT {$tableName}_{$columnName}_SEQ.NEXTVAL INTO last_Sequence FROM DUAL; END LOOP; END IF; END;" "CREATE TRIGGER {$tableName}_AI_PK BEFORE INSERT ON {$tableName} FOR EACH ROW DECLARE last_Sequence NUMBER; last_InsertID NUMBER; BEGIN SELECT {$tableName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; IF (:NEW.{$columnName} IS NULL OR :NEW.{$columnName} = 0) THEN SELECT {$tableName}_SEQ.NEXTVAL INTO :NEW.{$columnName} FROM DUAL; ELSE SELECT NVL(Last_Number, 0) INTO last_Sequence FROM User_Sequences WHERE Sequence_Name = '{$tableName}_SEQ'; SELECT :NEW.{$columnName} INTO last_InsertID FROM DUAL; WHILE (last_InsertID > last_Sequence) LOOP SELECT {$tableName}_SEQ.NEXTVAL INTO last_Sequence FROM DUAL; END LOOP; END IF; END;"
); );
$statements = $this->_platform->getCreateTableSQL($table); $statements = $this->_platform->getCreateTableSQL($table);
//strip all the whitespace from the statements //strip all the whitespace from the statements
...@@ -310,6 +312,10 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -310,6 +312,10 @@ class OraclePlatformTest extends AbstractPlatformTestCase
); );
} }
/**
* @group DBAL-472
* @group DBAL-1001
*/
public function testAlterTableNotNULL() public function testAlterTableNotNULL()
{ {
$tableDiff = new \Doctrine\DBAL\Schema\TableDiff('mytable'); $tableDiff = new \Doctrine\DBAL\Schema\TableDiff('mytable');
...@@ -333,7 +339,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -333,7 +339,7 @@ class OraclePlatformTest extends AbstractPlatformTestCase
); );
$expectedSql = array( $expectedSql = array(
"ALTER TABLE mytable MODIFY (foo VARCHAR2(255) DEFAULT 'bla' NULL, baz VARCHAR2(255) DEFAULT 'bla' NOT NULL, metar VARCHAR2(2000) DEFAULT NULL NULL)", "ALTER TABLE mytable MODIFY (foo VARCHAR2(255) DEFAULT 'bla', baz VARCHAR2(255) DEFAULT 'bla' NOT NULL, metar VARCHAR2(2000) DEFAULT NULL NULL)",
); );
$this->assertEquals($expectedSql, $this->_platform->getAlterTableSQL($tableDiff)); $this->assertEquals($expectedSql, $this->_platform->getAlterTableSQL($tableDiff));
} }
...@@ -392,10 +398,14 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -392,10 +398,14 @@ class OraclePlatformTest extends AbstractPlatformTestCase
/** /**
* @group DBAL-563 * @group DBAL-563
* @group DBAL-831
*/ */
public function testReturnsIdentitySequenceName() public function testReturnsIdentitySequenceName()
{ {
$this->assertSame('mytable_mycolumn_SEQ', $this->_platform->getIdentitySequenceName('mytable', 'mycolumn')); $this->assertSame('MYTABLE_SEQ', $this->_platform->getIdentitySequenceName('mytable', 'mycolumn'));
$this->assertSame('"mytable_SEQ"', $this->_platform->getIdentitySequenceName('"mytable"', 'mycolumn'));
$this->assertSame('MYTABLE_SEQ', $this->_platform->getIdentitySequenceName('mytable', '"mycolumn"'));
$this->assertSame('"mytable_SEQ"', $this->_platform->getIdentitySequenceName('"mytable"', '"mycolumn"'));
} }
/** /**
...@@ -492,4 +502,144 @@ class OraclePlatformTest extends AbstractPlatformTestCase ...@@ -492,4 +502,144 @@ class OraclePlatformTest extends AbstractPlatformTestCase
{ {
$this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array())); $this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array()));
} }
/**
* {@inheritdoc}
*/
public function getAlterTableRenameColumnSQL()
{
return array(
'ALTER TABLE foo RENAME COLUMN bar TO baz',
);
}
/**
* @dataProvider getReturnsDropAutoincrementSQL
* @group DBAL-831
*/
public function testReturnsDropAutoincrementSQL($table, $expectedSql)
{
$this->assertSame($expectedSql, $this->_platform->getDropAutoincrementSql($table));
}
public function getReturnsDropAutoincrementSQL()
{
return array(
array(
'myTable',
array(
'DROP TRIGGER MYTABLE_AI_PK',
'DROP SEQUENCE MYTABLE_SEQ',
'ALTER TABLE MYTABLE DROP CONSTRAINT MYTABLE_AI_PK',
)
),
array(
'"myTable"',
array(
'DROP TRIGGER "myTable_AI_PK"',
'DROP SEQUENCE "myTable_SEQ"',
'ALTER TABLE "myTable" DROP CONSTRAINT "myTable_AI_PK"',
)
),
array(
'table',
array(
'DROP TRIGGER TABLE_AI_PK',
'DROP SEQUENCE TABLE_SEQ',
'ALTER TABLE "TABLE" DROP CONSTRAINT TABLE_AI_PK',
)
),
);
}
/**
* {@inheritdoc}
*/
protected function getQuotesTableIdentifiersInAlterTableSQL()
{
return array(
'ALTER TABLE "foo" DROP CONSTRAINT fk1',
'ALTER TABLE "foo" DROP CONSTRAINT fk2',
'ALTER TABLE "foo" ADD (bloo NUMBER(10) NOT NULL)',
'ALTER TABLE "foo" MODIFY (bar NUMBER(10) DEFAULT NULL NULL)',
'ALTER TABLE "foo" RENAME COLUMN id TO war',
'ALTER TABLE "foo" DROP (baz)',
'ALTER TABLE "foo" RENAME TO "table"',
'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
);
}
/**
* {@inheritdoc}
*/
protected function getCommentOnColumnSQL()
{
return array(
'COMMENT ON COLUMN foo.bar IS \'comment\'',
'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
'COMMENT ON COLUMN "select"."from" IS \'comment\'',
);
}
/**
* @group DBAL-1004
*/
public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers()
{
$table1 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'))));
$table2 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'), array('comment' => 'baz'))));
$comparator = new Comparator();
$tableDiff = $comparator->diffTable($table1, $table2);
$this->assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
$this->assertSame(
array(
'COMMENT ON COLUMN "foo"."bar" IS \'baz\'',
),
$this->_platform->getAlterTableSQL($tableDiff)
);
}
public function testQuotedTableNames()
{
$table = new Table('"test"');
$table->addColumn('"id"', 'integer', array('autoincrement' => true));
// assert tabel
$this->assertTrue($table->isQuoted());
$this->assertEquals('test', $table->getName());
$this->assertEquals('"test"', $table->getQuotedName($this->_platform));
$sql = $this->_platform->getCreateTableSQL($table);
$this->assertEquals('CREATE TABLE "test" ("id" NUMBER(10) NOT NULL)', $sql[0]);
$this->assertEquals('CREATE SEQUENCE "test_SEQ" START WITH 1 MINVALUE 1 INCREMENT BY 1', $sql[2]);
$createTriggerStatement = <<<EOD
CREATE TRIGGER "test_AI_PK"
BEFORE INSERT
ON "test"
FOR EACH ROW
DECLARE
last_Sequence NUMBER;
last_InsertID NUMBER;
BEGIN
SELECT "test_SEQ".NEXTVAL INTO :NEW."id" FROM DUAL;
IF (:NEW."id" IS NULL OR :NEW."id" = 0) THEN
SELECT "test_SEQ".NEXTVAL INTO :NEW."id" FROM DUAL;
ELSE
SELECT NVL(Last_Number, 0) INTO last_Sequence
FROM User_Sequences
WHERE Sequence_Name = 'test_SEQ';
SELECT :NEW."id" INTO last_InsertID FROM DUAL;
WHILE (last_InsertID > last_Sequence) LOOP
SELECT "test_SEQ".NEXTVAL INTO last_Sequence FROM DUAL;
END LOOP;
END IF;
END;
EOD;
$this->assertEquals($createTriggerStatement, $sql[3]);
}
} }
...@@ -8,6 +8,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform; ...@@ -8,6 +8,7 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\SQLAnywherePlatform; use Doctrine\DBAL\Platforms\SQLAnywherePlatform;
use Doctrine\DBAL\Schema\Column; use Doctrine\DBAL\Schema\Column;
use Doctrine\DBAL\Schema\ColumnDiff; use Doctrine\DBAL\Schema\ColumnDiff;
use Doctrine\DBAL\Schema\Comparator;
use Doctrine\DBAL\Schema\ForeignKeyConstraint; use Doctrine\DBAL\Schema\ForeignKeyConstraint;
use Doctrine\DBAL\Schema\Index; use Doctrine\DBAL\Schema\Index;
use Doctrine\DBAL\Schema\Table; use Doctrine\DBAL\Schema\Table;
...@@ -863,4 +864,63 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase ...@@ -863,4 +864,63 @@ class SQLAnywherePlatformTest extends AbstractPlatformTestCase
{ {
$this->assertSame('UNIQUEIDENTIFIER', $this->_platform->getGuidTypeDeclarationSQL(array())); $this->assertSame('UNIQUEIDENTIFIER', $this->_platform->getGuidTypeDeclarationSQL(array()));
} }
/**
* {@inheritdoc}
*/
public function getAlterTableRenameColumnSQL()
{
return array(
'ALTER TABLE foo RENAME bar TO baz',
);
}
/**
* {@inheritdoc}
*/
protected function getQuotesTableIdentifiersInAlterTableSQL()
{
return array(
'ALTER TABLE "foo" DROP FOREIGN KEY fk1',
'ALTER TABLE "foo" DROP FOREIGN KEY fk2',
'ALTER TABLE "foo" RENAME id TO war',
'ALTER TABLE "foo" ADD bloo INT NOT NULL, DROP baz, ALTER bar INT DEFAULT NULL',
'ALTER TABLE "foo" RENAME "table"',
'ALTER TABLE "table" ADD CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id)',
'ALTER TABLE "table" ADD CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id)',
);
}
/**
* {@inheritdoc}
*/
protected function getCommentOnColumnSQL()
{
return array(
'COMMENT ON COLUMN foo.bar IS \'comment\'',
'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
'COMMENT ON COLUMN "select"."from" IS \'comment\'',
);
}
/**
* @group DBAL-1004
*/
public function testAltersTableColumnCommentWithExplicitlyQuotedIdentifiers()
{
$table1 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'))));
$table2 = new Table('"foo"', array(new Column('"bar"', Type::getType('integer'), array('comment' => 'baz'))));
$comparator = new Comparator();
$tableDiff = $comparator->diffTable($table1, $table2);
$this->assertInstanceOf('Doctrine\DBAL\Schema\TableDiff', $tableDiff);
$this->assertSame(
array(
'COMMENT ON COLUMN "foo"."bar" IS \'baz\'',
),
$this->_platform->getAlterTableSQL($tableDiff)
);
}
} }
...@@ -498,8 +498,8 @@ class SqlitePlatformTest extends AbstractPlatformTestCase ...@@ -498,8 +498,8 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
'CREATE TABLE "table" (id INTEGER NOT NULL, PRIMARY KEY(id))', 'CREATE TABLE "table" (id INTEGER NOT NULL, PRIMARY KEY(id))',
'INSERT INTO "table" (id) SELECT id FROM __temp__table', 'INSERT INTO "table" (id) SELECT id FROM __temp__table',
'DROP TABLE __temp__table', 'DROP TABLE __temp__table',
'CREATE INDEX "select" ON table (id)', 'CREATE INDEX "select" ON "table" (id)',
'CREATE INDEX "bar" ON table (id)', 'CREATE INDEX "bar" ON "table" (id)',
); );
} }
...@@ -560,4 +560,52 @@ class SqlitePlatformTest extends AbstractPlatformTestCase ...@@ -560,4 +560,52 @@ class SqlitePlatformTest extends AbstractPlatformTestCase
{ {
$this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array())); $this->assertSame('CHAR(36)', $this->_platform->getGuidTypeDeclarationSQL(array()));
} }
/**
* {@inheritdoc}
*/
public function getAlterTableRenameColumnSQL()
{
return array(
'CREATE TEMPORARY TABLE __temp__foo AS SELECT bar FROM foo',
'DROP TABLE foo',
'CREATE TABLE foo (baz INTEGER DEFAULT 666 NOT NULL)',
'INSERT INTO foo (baz) SELECT bar FROM __temp__foo',
'DROP TABLE __temp__foo',
);
}
/**
* {@inheritdoc}
*/
protected function getQuotesTableIdentifiersInAlterTableSQL()
{
return array(
'DROP INDEX IDX_8C736521A81E660E',
'DROP INDEX IDX_8C736521FDC58D6C',
'CREATE TEMPORARY TABLE __temp__foo AS SELECT fk, fk2, id, fk3, bar FROM "foo"',
'DROP TABLE "foo"',
'CREATE TABLE "foo" (fk2 INTEGER NOT NULL, fk3 INTEGER NOT NULL, fk INTEGER NOT NULL, war INTEGER NOT NULL, ' .
'bar INTEGER DEFAULT NULL, bloo INTEGER NOT NULL, ' .
'CONSTRAINT fk2 FOREIGN KEY (fk2) REFERENCES fk_table2 (id) NOT DEFERRABLE INITIALLY IMMEDIATE, ' .
'CONSTRAINT fk_add FOREIGN KEY (fk3) REFERENCES fk_table (id) NOT DEFERRABLE INITIALLY IMMEDIATE)',
'INSERT INTO "foo" (fk, fk2, war, fk3, bar) SELECT fk, fk2, id, fk3, bar FROM __temp__foo',
'DROP TABLE __temp__foo',
'ALTER TABLE "foo" RENAME TO "table"',
'CREATE INDEX IDX_8C736521A81E660E ON "table" (fk)',
'CREATE INDEX IDX_8C736521FDC58D6C ON "table" (fk2)',
);
}
/**
* {@inheritdoc}
*/
protected function getCommentOnColumnSQL()
{
return array(
'COMMENT ON COLUMN foo.bar IS \'comment\'',
'COMMENT ON COLUMN "Foo"."BAR" IS \'comment\'',
'COMMENT ON COLUMN "select"."from" IS \'comment\'',
);
}
} }
...@@ -204,8 +204,18 @@ class ExpressionBuilderTest extends \Doctrine\Tests\DbalTestCase ...@@ -204,8 +204,18 @@ class ExpressionBuilderTest extends \Doctrine\Tests\DbalTestCase
$this->assertEquals('u.groups IN (1, 3, 4, 7)', $this->expr->in('u.groups', array(1,3,4,7))); $this->assertEquals('u.groups IN (1, 3, 4, 7)', $this->expr->in('u.groups', array(1,3,4,7)));
} }
public function testInWithPlaceholder()
{
$this->assertEquals('u.groups IN (?)', $this->expr->in('u.groups', '?'));
}
public function testNotIn() public function testNotIn()
{ {
$this->assertEquals('u.groups NOT IN (1, 3, 4, 7)', $this->expr->notIn('u.groups', array(1,3,4,7))); $this->assertEquals('u.groups NOT IN (1, 3, 4, 7)', $this->expr->notIn('u.groups', array(1,3,4,7)));
} }
public function testNotInWithPlaceholder()
{
$this->assertEquals('u.groups NOT IN (:values)', $this->expr->notIn('u.groups', ':values'));
}
} }
...@@ -13,7 +13,7 @@ require_once __DIR__ . '/../TestInit.php'; ...@@ -13,7 +13,7 @@ require_once __DIR__ . '/../TestInit.php';
*/ */
class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase class SQLParserUtilsTest extends \Doctrine\Tests\DbalTestCase
{ {
static public function dataGetPlaceholderPositions() public function dataGetPlaceholderPositions()
{ {
return array( return array(
// none // none
...@@ -73,7 +73,7 @@ SQLDATA ...@@ -73,7 +73,7 @@ SQLDATA
$this->assertEquals($expectedParamPos, $actualParamPos); $this->assertEquals($expectedParamPos, $actualParamPos);
} }
static public function dataExpandListParameters() public function dataExpandListParameters()
{ {
return array( return array(
// Positional: Very simple with one needle // Positional: Very simple with one needle
...@@ -148,6 +148,24 @@ SQLDATA ...@@ -148,6 +148,24 @@ SQLDATA
array(1 => 'bar', 0 => 1, 2 => 'baz'), array(1 => 'bar', 0 => 1, 2 => 'baz'),
array(1 => \PDO::PARAM_STR, 2 => \PDO::PARAM_STR) array(1 => \PDO::PARAM_STR, 2 => \PDO::PARAM_STR)
), ),
// Positional: explicit keys for array params and array types
array(
"SELECT * FROM Foo WHERE foo IN (?) AND bar IN (?) AND baz = ?",
array(1 => array('bar1', 'bar2'), 2 => true, 0 => array(1, 2, 3)),
array(2 => \PDO::PARAM_BOOL, 1 => Connection::PARAM_STR_ARRAY, 0 => Connection::PARAM_INT_ARRAY),
'SELECT * FROM Foo WHERE foo IN (?, ?, ?) AND bar IN (?, ?) AND baz = ?',
array(1, 2, 3, 'bar1', 'bar2', true),
array(\PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_STR, \PDO::PARAM_STR, \PDO::PARAM_BOOL)
),
// Positional starts from 1: One non-list before and one after list-needle
array(
"SELECT * FROM Foo WHERE foo = ? AND bar IN (?) AND baz = ? AND foo IN (?)",
array(1 => 1, 2 => array(1, 2, 3), 3 => 4, 4 => array(5, 6)),
array(1 => \PDO::PARAM_INT, 2 => Connection::PARAM_INT_ARRAY, 3 => \PDO::PARAM_INT, 4 => Connection::PARAM_INT_ARRAY),
'SELECT * FROM Foo WHERE foo = ? AND bar IN (?, ?, ?) AND baz = ? AND foo IN (?, ?)',
array(1, 1, 2, 3, 4, 5, 6),
array(\PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT, \PDO::PARAM_INT)
),
// Named parameters : Very simple with param int // Named parameters : Very simple with param int
array( array(
"SELECT * FROM Foo WHERE foo = :foo", "SELECT * FROM Foo WHERE foo = :foo",
...@@ -339,7 +357,7 @@ SQLDATA ...@@ -339,7 +357,7 @@ SQLDATA
$this->assertEquals($expectedTypes, $types, "Types dont match"); $this->assertEquals($expectedTypes, $types, "Types dont match");
} }
public static function dataQueryWithMissingParameters() public function dataQueryWithMissingParameters()
{ {
return array( return array(
array( array(
......
...@@ -1122,4 +1122,52 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase ...@@ -1122,4 +1122,52 @@ class ComparatorTest extends \PHPUnit_Framework_TestCase
$this->assertEquals(array('notnull', 'default', 'comment'), $comparator->diffColumn($column1, $column2)); $this->assertEquals(array('notnull', 'default', 'comment'), $comparator->diffColumn($column1, $column2));
$this->assertEquals(array('notnull', 'default', 'comment'), $comparator->diffColumn($column2, $column1)); $this->assertEquals(array('notnull', 'default', 'comment'), $comparator->diffColumn($column2, $column1));
} }
/**
* @group DBAL-1009
*
* @dataProvider getCompareColumnComments
*/
public function testCompareColumnComments($comment1, $comment2, $equals)
{
$column1 = new Column('foo', Type::getType('integer'), array('comment' => $comment1));
$column2 = new Column('foo', Type::getType('integer'), array('comment' => $comment2));
$comparator = new Comparator();
$expectedDiff = $equals ? array() : array('comment');
$actualDiff = $comparator->diffColumn($column1, $column2);
$this->assertSame($expectedDiff, $actualDiff);
$actualDiff = $comparator->diffColumn($column2, $column1);
$this->assertSame($expectedDiff, $actualDiff);
}
public function getCompareColumnComments()
{
return array(
array(null, null, true),
array('', '', true),
array(' ', ' ', true),
array('0', '0', true),
array('foo', 'foo', true),
array(null, '', true),
array(null, ' ', false),
array(null, '0', false),
array(null, 'foo', false),
array('', ' ', false),
array('', '0', false),
array('', 'foo', false),
array(' ', '0', false),
array(' ', 'foo', false),
array('0', 'foo', false),
);
}
} }
<?php
namespace Doctrine\Tests\DBAL\Schema;
use Doctrine\DBAL\Schema\Identifier;
use Doctrine\DBAL\Schema\TableDiff;
use Doctrine\Tests\DBAL\Mocks\MockPlatform;
class TableDiffTest extends \PHPUnit_Framework_TestCase
{
/**
* @group DBAL-1013
*/
public function testReturnsName()
{
$tableDiff = new TableDiff('foo');
$this->assertEquals(new Identifier('foo'), $tableDiff->getName(new MockPlatform()));
}
/**
* @group DBAL-1016
*/
public function testPrefersNameFromTableObject()
{
$platformMock = new MockPlatform();
$tableMock = $this->getMockBuilder('Doctrine\DBAL\Schema\Table')
->disableOriginalConstructor()
->getMock();
$tableDiff = new TableDiff('foo');
$tableDiff->fromTable = $tableMock;
$tableMock->expects($this->once())
->method('getQuotedName')
->with($platformMock)
->will($this->returnValue('foo'));
$this->assertEquals(new Identifier('foo'), $tableDiff->getName($platformMock));
}
/**
* @group DBAL-1013
*/
public function testReturnsNewName()
{
$tableDiff = new TableDiff('foo');
$this->assertFalse($tableDiff->getNewName());
$tableDiff->newName = 'bar';
$this->assertEquals(new Identifier('bar'), $tableDiff->getNewName());
}
}
...@@ -623,4 +623,76 @@ class TableTest extends \Doctrine\Tests\DbalTestCase ...@@ -623,4 +623,76 @@ class TableTest extends \Doctrine\Tests\DbalTestCase
$table->renameIndex('idx_id', 'idx_foo'); $table->renameIndex('idx_id', 'idx_foo');
} }
/**
* @dataProvider getNormalizesAssetNames
* @group DBAL-831
*/
public function testNormalizesColumnNames($assetName)
{
$table = new Table('test');
$table->addColumn($assetName, 'integer');
$table->addIndex(array($assetName), $assetName);
$table->addForeignKeyConstraint('test', array($assetName), array($assetName), array(), $assetName);
$this->assertTrue($table->hasColumn($assetName));
$this->assertTrue($table->hasColumn('foo'));
$this->assertInstanceOf('Doctrine\DBAL\Schema\Column', $table->getColumn($assetName));
$this->assertInstanceOf('Doctrine\DBAL\Schema\Column', $table->getColumn('foo'));
$this->assertTrue($table->hasIndex($assetName));
$this->assertTrue($table->hasIndex('foo'));
$this->assertInstanceOf('Doctrine\DBAL\Schema\Index', $table->getIndex($assetName));
$this->assertInstanceOf('Doctrine\DBAL\Schema\Index', $table->getIndex('foo'));
$this->assertTrue($table->hasForeignKey($assetName));
$this->assertTrue($table->hasForeignKey('foo'));
$this->assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $table->getForeignKey($assetName));
$this->assertInstanceOf('Doctrine\DBAL\Schema\ForeignKeyConstraint', $table->getForeignKey('foo'));
$table->renameIndex($assetName, $assetName);
$this->assertTrue($table->hasIndex($assetName));
$this->assertTrue($table->hasIndex('foo'));
$table->renameIndex($assetName, 'foo');
$this->assertTrue($table->hasIndex($assetName));
$this->assertTrue($table->hasIndex('foo'));
$table->renameIndex('foo', $assetName);
$this->assertTrue($table->hasIndex($assetName));
$this->assertTrue($table->hasIndex('foo'));
$table->renameIndex($assetName, 'bar');
$this->assertFalse($table->hasIndex($assetName));
$this->assertFalse($table->hasIndex('foo'));
$this->assertTrue($table->hasIndex('bar'));
$table->renameIndex('bar', $assetName);
$table->dropColumn($assetName);
$table->dropIndex($assetName);
$table->removeForeignKey($assetName);
$this->assertFalse($table->hasColumn($assetName));
$this->assertFalse($table->hasColumn('foo'));
$this->assertFalse($table->hasIndex($assetName));
$this->assertFalse($table->hasIndex('foo'));
$this->assertFalse($table->hasForeignKey($assetName));
$this->assertFalse($table->hasForeignKey('foo'));
}
public function getNormalizesAssetNames()
{
return array(
array('foo'),
array('FOO'),
array('`foo`'),
array('`FOO`'),
array('"foo"'),
array('"FOO"'),
array('"foo"'),
array('"FOO"'),
);
}
} }
...@@ -34,6 +34,13 @@ class TimeTest extends \Doctrine\Tests\DbalTestCase ...@@ -34,6 +34,13 @@ class TimeTest extends \Doctrine\Tests\DbalTestCase
); );
} }
public function testDateFieldResetInPHPValue()
{
$time = $this->_type->convertToPHPValue('01:23:34', $this->_platform);
$this->assertEquals('01:23:34', $time->format('H:i:s'));
$this->assertEquals('1970-01-01', $time->format('Y-m-d'));
}
public function testInvalidTimeFormatConversion() public function testInvalidTimeFormatConversion()
{ {
$this->setExpectedException('Doctrine\DBAL\Types\ConversionException'); $this->setExpectedException('Doctrine\DBAL\Types\ConversionException');
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
error_reporting(E_ALL | E_STRICT); error_reporting(E_ALL | E_STRICT);
date_default_timezone_set('UTC');
if (file_exists(__DIR__ . '/../../../vendor/autoload.php')) { if (file_exists(__DIR__ . '/../../../vendor/autoload.php')) {
// dependencies were installed via composer - this is the main project // dependencies were installed via composer - this is the main project
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment