From 733c3c24f744ede3889ecf2322cd14c1106dc992 Mon Sep 17 00:00:00 2001 From: romanb Date: Fri, 28 Aug 2009 17:25:28 +0000 Subject: [PATCH] [2.0] Various necessary fixes and adjustments for oracle as well as fixes for better handling of temporal types. Closed #2452. --- .../DBAL/Platforms/AbstractPlatform.php | 29 +++++++++++++++++++ lib/Doctrine/DBAL/Platforms/MySqlPlatform.php | 8 +++++ .../DBAL/Platforms/OraclePlatform.php | 23 +++++++++++++-- .../DBAL/Platforms/PostgreSqlPlatform.php | 22 +++++++------- .../DBAL/Platforms/SqlitePlatform.php | 8 +++++ .../DBAL/Schema/OracleSchemaManager.php | 6 ++-- lib/Doctrine/DBAL/Types/DateType.php | 2 +- .../ORM/Mapping/ClassMetadataFactory.php | 3 +- .../Query/Exec/MultiTableDeleteExecutor.php | 2 +- .../Query/Exec/MultiTableUpdateExecutor.php | 4 +-- .../ORM/Functional/LifecycleCallbackTest.php | 2 +- .../ORM/Functional/Locking/OptimisticTest.php | 3 +- .../Tests/ORM/Functional/NativeQueryTest.php | 2 +- 13 files changed, 91 insertions(+), 23 deletions(-) diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 463bbc8a5..c3d53621d 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -520,6 +520,11 @@ abstract class AbstractPlatform return $sql; } + + public function getCreateTemporaryTableSnippetSql() + { + return "CREATE TEMPORARY TABLE"; + } /** * Gets the SQL to create a sequence on this platform. @@ -1339,6 +1344,18 @@ abstract class AbstractPlatform { throw DoctrineException::getDateTimeTypeDeclarationNotSupported($this); } + + /** + * Obtain DBMS specific SQL to be used to create date fields in statements + * like CREATE TABLE. + * + * @param array $fieldDeclaration + * @return string + */ + public function getDateTypeDeclarationSql(array $fieldDeclaration) + { + throw DoctrineException::getDateTypeDeclarationNotSupported($this); + } /** * Gets the default transaction isolation level of the platform. @@ -1529,4 +1546,16 @@ abstract class AbstractPlatform { return $column; } + + /** + * Makes any fixes to a name of a schema element (table, sequence, ...) that are required + * by restrictions of the platform, like a maximum length. + * + * @param string $schemaName + * @return string + */ + public function fixSchemaElementName($schemaElementName) + { + return $schemaElementName; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php index 1012a5416..20b3e07e4 100644 --- a/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/MySqlPlatform.php @@ -266,6 +266,14 @@ class MySqlPlatform extends AbstractPlatform { return 'DATETIME'; } + + /** + * @override + */ + public function getDateTypeDeclarationSql(array $fieldDeclaration) + { + return 'DATE'; + } /** * @override diff --git a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php index 638d555a5..5d0b27704 100644 --- a/lib/Doctrine/DBAL/Platforms/OraclePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/OraclePlatform.php @@ -182,7 +182,7 @@ class OraclePlatform extends AbstractPlatform */ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration) { - return 'DATE'; + return 'TIMESTAMP(0) WITH TIME ZONE'; } /** @@ -247,7 +247,7 @@ class OraclePlatform extends AbstractPlatform foreach ($columns as $name => $column) { if (isset($column['sequence'])) { - $sql[] = $this->getCreateSequenceSql($column['sequence'], 1); + $sql[] = $this->getCreateSequenceSql($column['sequence'], 1); } if (isset($column['autoincrement']) && $column['autoincrement'] || @@ -513,4 +513,23 @@ END;'; { return strtoupper($column); } + + public function getCreateTemporaryTableSnippetSql() + { + return "CREATE GLOBAL TEMPORARY TABLE"; + } + + public function getDateTimeFormatString() + { + return 'Y-m-d H:i:sP'; + } + + public function fixSchemaElementName($schemaElementName) + { + if (strlen($schemaElementName) > 30) { + // Trim it + return substr($schemaElementName, 0, 30); + } + return $schemaElementName; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php index cad4440a1..aab0e0117 100644 --- a/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php @@ -692,7 +692,15 @@ class PostgreSqlPlatform extends AbstractPlatform */ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration) { - return 'TIMESTAMP without time zone'; + return 'TIMESTAMP(0) WITH TIME ZONE'; + } + + /** + * @override + */ + public function getDateTypeDeclarationSql(array $fieldDeclaration) + { + return 'DATE'; } /** @@ -757,14 +765,8 @@ class PostgreSqlPlatform extends AbstractPlatform return strtolower($column); } - /** - * Gets the format string, as accepted by the date() function, that describes - * the format of a stored datetime value of this platform. - * - * @return string The format string. - */ - /*public function getDateTimeFormatString() + public function getDateTimeFormatString() { - return 'Y-m-d H:i:s.u'; - }*/ + return 'Y-m-d H:i:sO'; + } } \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php index 6e1594125..c2b98894a 100644 --- a/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php +++ b/lib/Doctrine/DBAL/Platforms/SqlitePlatform.php @@ -234,6 +234,14 @@ class SqlitePlatform extends AbstractPlatform { return 'DATETIME'; } + + /** + * @override + */ + public function getDateTypeDeclarationSql(array $fieldDeclaration) + { + return 'DATE'; + } /** @override */ protected function _getCommonIntegerTypeDeclarationSql(array $columnDef) diff --git a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php index e8a098602..5941e488c 100644 --- a/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php +++ b/lib/Doctrine/DBAL/Schema/OracleSchemaManager.php @@ -187,10 +187,10 @@ class OracleSchemaManager extends AbstractSchemaManager $password = $params['password']; $query = 'CREATE USER ' . $username . ' IDENTIFIED BY ' . $password; - $result = $this->_conn->exec($query); + $result = $this->_conn->executeUpdate($query); $query = 'GRANT CREATE SESSION, CREATE TABLE, UNLIMITED TABLESPACE, CREATE SEQUENCE, CREATE TRIGGER TO ' . $username; - $result = $this->_conn->exec($query); + $result = $this->_conn->executeUpdate($query); return true; } @@ -199,7 +199,7 @@ class OracleSchemaManager extends AbstractSchemaManager { $sql = $this->_platform->getDropAutoincrementSql($table); foreach ($sql as $query) { - $this->_conn->exec($query); + $this->_conn->executeUpdate($query); } return true; diff --git a/lib/Doctrine/DBAL/Types/DateType.php b/lib/Doctrine/DBAL/Types/DateType.php index aa3b93301..58cf54b26 100644 --- a/lib/Doctrine/DBAL/Types/DateType.php +++ b/lib/Doctrine/DBAL/Types/DateType.php @@ -5,7 +5,7 @@ namespace Doctrine\DBAL\Types; use Doctrine\DBAL\Platforms\AbstractPlatform; /** - * Type that maps an SQL DATETIME to a PHP Date object. + * Type that maps an SQL DATE to a PHP Date object. * * @since 2.0 */ diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php index cb17434b8..49e8ad307 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php @@ -398,7 +398,8 @@ class ClassMetadataFactory // If there is no sequence definition yet, create a default definition $definition = $class->getSequenceGeneratorDefinition(); if ( ! $definition) { - $definition['sequenceName'] = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq'; + $sequenceName = $class->getTableName() . '_' . $class->getSingleIdentifierColumnName() . '_seq'; + $definition['sequenceName'] = $this->_targetPlatform->fixSchemaElementName($sequenceName); $definition['allocationSize'] = 20; $definition['initialValue'] = 1; $class->setSequenceGeneratorDefinition($definition); diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php index e8627135c..40b7f0e3c 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableDeleteExecutor.php @@ -95,7 +95,7 @@ class MultiTableDeleteExecutor extends AbstractSqlExecutor 'type' => \Doctrine\DBAL\Types\Type::getType($rootClass->getTypeOfColumn($idColumnName)) ); } - $this->_createTempTableSql = 'CREATE TEMPORARY TABLE ' . $tempTable . ' (' + $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSql() . ' ' . $tempTable . ' (' . $conn->getDatabasePlatform()->getColumnDeclarationListSql($columnDefinitions) . ', PRIMARY KEY(' . $idColumnList . '))'; $this->_dropTempTableSql = 'DROP TABLE ' . $tempTable; diff --git a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php index 0167175b0..342aa5f61 100644 --- a/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php +++ b/lib/Doctrine/ORM/Query/Exec/MultiTableUpdateExecutor.php @@ -127,8 +127,8 @@ class MultiTableUpdateExecutor extends AbstractSqlExecutor 'type' => \Doctrine\DBAL\Types\Type::getType($rootClass->getTypeOfColumn($idColumnName)) ); } - $this->_createTempTableSql = 'CREATE TEMPORARY TABLE ' . $tempTable . ' (' - . $conn->getDatabasePlatform()->getColumnDeclarationListSql($columnDefinitions) + $this->_createTempTableSql = $platform->getCreateTemporaryTableSnippetSql() . ' ' . $tempTable . ' (' + . $platform->getColumnDeclarationListSql($columnDefinitions) . ', PRIMARY KEY(' . $idColumnList . '))'; $this->_dropTempTableSql = 'DROP TABLE ' . $tempTable; } diff --git a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php index 196ed4ba2..d37cdb367 100644 --- a/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/LifecycleCallbackTest.php @@ -44,7 +44,7 @@ class LifecycleCallbackTest extends \Doctrine\Tests\OrmFunctionalTestCase /** * @Entity * @HasLifecycleCallbacks - * @Table(name="lifecycle_callback_test_entity") + * @Table(name="lc_cb_test_entity") */ class LifecycleCallbackTestEntity { diff --git a/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php b/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php index 432dae391..e4be96772 100644 --- a/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/Locking/OptimisticTest.php @@ -136,7 +136,8 @@ class OptimisticTest extends \Doctrine\Tests\OrmFunctionalTestCase $test = $q->getSingleResult(); // Manually increment the version datetime column - $this->_conn->execute('UPDATE optimistic_timestamp SET version = ? WHERE id = ?', array(date('Y-m-d H:i:s', strtotime($test->version->format('Y-m-d H:i:s')) + 3600), $test->id)); + $format = $this->_em->getConnection()->getDatabasePlatform()->getDateTimeFormatString(); + $this->_conn->execute('UPDATE optimistic_timestamp SET version = ? WHERE id = ?', array(date($format, strtotime($test->version->format($format)) + 3600), $test->id)); // Try and update the record and it should throw an exception $test->name = 'Testing again'; diff --git a/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php b/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php index abb929c65..e20545861 100644 --- a/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php +++ b/tests/Doctrine/Tests/ORM/Functional/NativeQueryTest.php @@ -20,7 +20,7 @@ class NativeQueryTest extends \Doctrine\Tests\OrmFunctionalTestCase parent::setUp(); if ($this->_em->getConnection()->getDatabasePlatform()->getName() == 'oracle') { - $this->markTestSkipped('The ' . $testClass .' does not work with Oracle due to character casing.'); + $this->markTestSkipped('The ' . __CLASS__ .' does not work with Oracle due to character casing.'); } }