From ab2b3999c07dd4a1457a89db32d341279939b0c2 Mon Sep 17 00:00:00 2001 From: jwage Date: Sat, 20 Jun 2009 14:24:21 +0000 Subject: [PATCH] [2.0] Adding date and time types. Fixing CURRENT_DATE, CURRENT_TIMESTAMP and CURRENT_TIME functions --- .../DBAL/Platforms/AbstractPlatform.php | 20 ++++++++- lib/Doctrine/DBAL/Types/DateType.php | 44 +++++++++++++++++++ lib/Doctrine/DBAL/Types/TimeType.php | 44 +++++++++++++++++++ lib/Doctrine/DBAL/Types/Type.php | 2 + .../AST/Functions/CurrentTimeFunction.php | 5 ++- .../Functions/CurrentTimestampFunction.php | 8 ++-- tests/Doctrine/Tests/DBAL/AllTests.php | 4 ++ tests/Doctrine/Tests/DBAL/Types/DateTest.php | 37 ++++++++++++++++ tests/Doctrine/Tests/DBAL/Types/TimeTest.php | 36 +++++++++++++++ .../Tests/Models/Generic/DateTimeModel.php | 8 ++++ .../ORM/Query/SelectSqlGenerationTest.php | 12 +++++ 11 files changed, 213 insertions(+), 7 deletions(-) create mode 100644 lib/Doctrine/DBAL/Types/DateType.php create mode 100644 lib/Doctrine/DBAL/Types/TimeType.php create mode 100644 tests/Doctrine/Tests/DBAL/Types/DateTest.php create mode 100644 tests/Doctrine/Tests/DBAL/Types/TimeTest.php diff --git a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php index 627d66655..a2448a699 100644 --- a/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php +++ b/lib/Doctrine/DBAL/Platforms/AbstractPlatform.php @@ -1256,7 +1256,15 @@ abstract class AbstractPlatform return 'CURRENT_TIME'; } - + /** + * Gets the SQL specific for the platform to get the current timestamp + * + * @return string + */ + public function getCurrentTimestampSql() + { + return 'CURRENT_TIMESTAMP'; + } /** * Get sql for transaction isolation level Connection constant @@ -1504,6 +1512,16 @@ abstract class AbstractPlatform return 'Y-m-d H:i:s'; } + public function getDateFormatString() + { + return 'Y-m-d'; + } + + public function getTimeFormatString() + { + return 'H:i:s'; + } + /** * Gets the SQL snippet used to declare a VARCHAR column type. * diff --git a/lib/Doctrine/DBAL/Types/DateType.php b/lib/Doctrine/DBAL/Types/DateType.php new file mode 100644 index 000000000..616a68772 --- /dev/null +++ b/lib/Doctrine/DBAL/Types/DateType.php @@ -0,0 +1,44 @@ +getDateTypeDeclarationSql($fieldDeclaration); + } + + /** + * {@inheritdoc} + * + * @override + */ + public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return $value->format($platform->getDateFormatString()); + } + + /** + * {@inheritdoc} + * + * @override + */ + public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return \DateTime::createFromFormat($platform->getDateFormatString(), $value); + } +} \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Types/TimeType.php b/lib/Doctrine/DBAL/Types/TimeType.php new file mode 100644 index 000000000..ceba1975b --- /dev/null +++ b/lib/Doctrine/DBAL/Types/TimeType.php @@ -0,0 +1,44 @@ +getTimeTypeDeclarationSql($fieldDeclaration); + } + + /** + * {@inheritdoc} + * + * @override + */ + public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return $value->format($platform->getTimeFormatString()); + } + + /** + * {@inheritdoc} + * + * @override + */ + public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform) + { + return \DateTime::createFromFormat($platform->getTimeFormatString(), $value); + } +} \ No newline at end of file diff --git a/lib/Doctrine/DBAL/Types/Type.php b/lib/Doctrine/DBAL/Types/Type.php index 8c89ca708..f38dccebd 100644 --- a/lib/Doctrine/DBAL/Types/Type.php +++ b/lib/Doctrine/DBAL/Types/Type.php @@ -33,6 +33,8 @@ abstract class Type 'string' => 'Doctrine\DBAL\Types\StringType', 'text' => 'Doctrine\DBAL\Types\TextType', 'datetime' => 'Doctrine\DBAL\Types\DateTimeType', + 'date' => 'Doctrine\DBAL\Types\DateType', + 'time' => 'Doctrine\DBAL\Types\TimeType', 'decimal' => 'Doctrine\DBAL\Types\DecimalType', 'double' => 'Doctrine\DBAL\Types\DoubleType' ); diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php index 8141f49cd..e7a732ce2 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php @@ -28,6 +28,7 @@ class CurrentTimeFunction extends FunctionNode { $lexer = $parser->getLexer(); $parser->match($lexer->lookahead['value']); + $parser->match('('); + $parser->match(')'); } -} - +} \ No newline at end of file diff --git a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php index edbb9b37c..1443e657c 100644 --- a/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php +++ b/lib/Doctrine/ORM/Query/AST/Functions/CurrentTimestampFunction.php @@ -18,8 +18,7 @@ class CurrentTimestampFunction extends FunctionNode */ public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker) { - //TODO: Use platform to get SQL - return 'CURRENT_TIMESTAMP'; + return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentTimestampSql(); } /** @@ -29,6 +28,7 @@ class CurrentTimestampFunction extends FunctionNode { $lexer = $parser->getLexer(); $parser->match($lexer->lookahead['value']); + $parser->match('('); + $parser->match(')'); } -} - +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/AllTests.php b/tests/Doctrine/Tests/DBAL/AllTests.php index 5e5db3d1c..a6577040d 100644 --- a/tests/Doctrine/Tests/DBAL/AllTests.php +++ b/tests/Doctrine/Tests/DBAL/AllTests.php @@ -23,12 +23,16 @@ class AllTests { $suite = new \Doctrine\Tests\DbalTestSuite('Doctrine DBAL'); + // Platform tests $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\SqlitePlatformTest'); $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\MySqlPlatformTest'); $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\PostgreSqlPlatformTest'); $suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\MsSqlPlatformTest'); + // Type tests $suite->addTestSuite('Doctrine\Tests\DBAL\Types\DateTimeTest'); + $suite->addTestSuite('Doctrine\Tests\DBAL\Types\DateTest'); + $suite->addTestSuite('Doctrine\Tests\DBAL\Types\TimeTest'); $suite->addTest(Functional\AllTests::suite()); diff --git a/tests/Doctrine/Tests/DBAL/Types/DateTest.php b/tests/Doctrine/Tests/DBAL/Types/DateTest.php new file mode 100644 index 000000000..93313bc82 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Types/DateTest.php @@ -0,0 +1,37 @@ +_platform = new \Doctrine\Tests\DBAL\Mocks\MockPlatform(); + $this->_type = Type::getType('date'); + } + + public function testDateConvertsToDatabaseValue() + { + $this->assertTrue( + is_string($this->_type->convertToDatabaseValue(new \DateTime(), $this->_platform)) + ); + } + + public function testDateConvertsToPHPValue() + { + // Birthday of jwage and also birthday of Doctrine. Send him a present ;) + $this->assertTrue( + $this->_type->convertToPHPValue('1985-09-01', $this->_platform) + instanceof \DateTime + ); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/DBAL/Types/TimeTest.php b/tests/Doctrine/Tests/DBAL/Types/TimeTest.php new file mode 100644 index 000000000..eb272ed59 --- /dev/null +++ b/tests/Doctrine/Tests/DBAL/Types/TimeTest.php @@ -0,0 +1,36 @@ +_platform = new \Doctrine\Tests\DBAL\Mocks\MockPlatform(); + $this->_type = Type::getType('time'); + } + + public function testTimeConvertsToDatabaseValue() + { + $this->assertTrue( + is_string($this->_type->convertToDatabaseValue(new \DateTime(), $this->_platform)) + ); + } + + public function testTimeConvertsToPHPValue() + { + $this->assertTrue( + $this->_type->convertToPHPValue('5:30:55', $this->_platform) + instanceof \DateTime + ); + } +} \ No newline at end of file diff --git a/tests/Doctrine/Tests/Models/Generic/DateTimeModel.php b/tests/Doctrine/Tests/Models/Generic/DateTimeModel.php index 68e7992eb..e26f3a3d5 100644 --- a/tests/Doctrine/Tests/Models/Generic/DateTimeModel.php +++ b/tests/Doctrine/Tests/Models/Generic/DateTimeModel.php @@ -17,4 +17,12 @@ class DateTimeModel * @Column(type="datetime") */ public $datetime; + /** + * @Column(type="date") + */ + public $date; + /** + * @Column(type="time") + */ + public $time; } \ No newline at end of file diff --git a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php index b87436bfd..1d53b1992 100644 --- a/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -287,6 +287,18 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.datetime > CURRENT_DATE', $q->getSql()); } + public function testCurrentTimeFunction() + { + $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.time > current_time()'); + $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.time > CURRENT_TIME', $q->getSql()); + } + + public function testCurrentTimestampFunction() + { + $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_timestamp()'); + $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.datetime > CURRENT_TIMESTAMP', $q->getSql()); + } + /*public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition() { $this->assertSqlGeneration(