Permalink
Browse files

[2.0] Work on datetime dbal type and date portability

  • Loading branch information...
1 parent f281276 commit ada2c5c5a7b4fa54046ed6f5ac071dda48383150 jwage committed Jun 20, 2009
View
43 lib/Doctrine/DBAL/Platforms/AbstractPlatform.php
@@ -1237,6 +1237,28 @@ public function getSetCharsetSql($charset)
}
/**
+ * Gets the SQL specific for the platform to get the current date.
+ *
+ * @return string
+ */
+ public function getCurrentDateSql()
+ {
+ return 'CURRENT_DATE';
+ }
+
+ /**
+ * Gets the SQL specific for the platform to get the current time.
+ *
+ * @return string
+ */
+ public function getCurrentTimeSql()
+ {
+ return 'CURRENT_TIME';
+ }
+
+
+
+ /**
* Get sql for transaction isolation level Connection constant
*
* @param integer $level
@@ -1361,6 +1383,18 @@ public function getCharsetFieldDeclaration($charset)
}
/**
+ * Obtain DBMS specific SQL to be used to create datetime fields in
+ * statements like CREATE TABLE
+ *
+ * @param array $fieldDeclaration
+ * @return string
+ */
+ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
+ {
+ throw DoctrineException::updateMe('Get datetime type declaration not supported by this platform.');
+ }
+
+ /**
* Gets the default transaction isolation level of the platform.
*
* @return integer The default isolation level.
@@ -1462,6 +1496,15 @@ public function getIdentityColumnNullInsertSql()
}
/**
+ * TODO: We need to get the specific format for each dbms and override this
+ * function for each platform
+ */
+ public function getDateTimeFormatString()
+ {
+ return 'Y-m-d H:i:s';
+ }
+
+ /**
* Gets the SQL snippet used to declare a VARCHAR column type.
*
* @param array $field
View
18 lib/Doctrine/DBAL/Platforms/MockPlatform.php
@@ -1,18 +0,0 @@
-<?php
-namespace Doctrine\DBAL\Platforms;
-
-class MockPlatform extends AbstractPlatform
-{
- public function getNativeDeclaration(array $field) {}
- public function getPortableDeclaration(array $field) {}
-
- /**
- * Get the platform name for this instance
- *
- * @return string
- */
- public function getName()
- {
- return 'mock';
- }
-}
View
8 lib/Doctrine/DBAL/Platforms/MsSqlPlatform.php
@@ -401,6 +401,14 @@ public function getCharsetFieldDeclaration($charset)
}
/**
+ * @override
+ */
+ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
+ {
+ return 'CHAR(' . strlen('YYYY-MM-DD HH:MM:SS') . ')';
+ }
+
+ /**
* Get the platform name for this instance
*
* @return string
View
8 lib/Doctrine/DBAL/Platforms/MySqlPlatform.php
@@ -259,6 +259,14 @@ public function getCharsetFieldDeclaration($charset)
}
/**
+ * @override
+ */
+ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
+ {
+ return 'DATETIME';
+ }
+
+ /**
* Obtain DBMS specific SQL code portion needed to set the COLLATION
* of a field declaration to be used in statements like CREATE TABLE.
*
View
8 lib/Doctrine/DBAL/Platforms/OraclePlatform.php
@@ -179,6 +179,14 @@ public function getSmallIntTypeDeclarationSql(array $field)
/**
* @override
*/
+ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
+ {
+ return 'DATE';
+ }
+
+ /**
+ * @override
+ */
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)
{
return '';
View
8 lib/Doctrine/DBAL/Platforms/PostgreSqlPlatform.php
@@ -693,6 +693,14 @@ public function getSmallIntTypeDeclarationSql(array $field)
/**
* @override
*/
+ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
+ {
+ return 'TIMESTAMP without time zone';
+ }
+
+ /**
+ * @override
+ */
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)
{
return '';
View
8 lib/Doctrine/DBAL/Platforms/SqlitePlatform.php
@@ -230,12 +230,18 @@ public function getMediumIntTypeDeclarationSql(array $field)
}
/** @override */
+ public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
+ {
+ return 'DATETIME';
+ }
+
+ /** @override */
protected function _getCommonIntegerTypeDeclarationSql(array $columnDef)
{
$autoinc = ! empty($columnDef['autoincrement']) ? ' AUTOINCREMENT' : '';
$pk = ! empty($columnDef['primary']) && ! empty($autoinc) ? ' PRIMARY KEY' : '';
- return "INTEGER" . $pk . $autoinc;
+ return 'INTEGER' . $pk . $autoinc;
}
/**
View
2 lib/Doctrine/DBAL/Types/BooleanType.php
@@ -24,7 +24,7 @@ public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\Abstract
*
* @override
*/
- public function convertToPHPValue($value)
+ public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
{
return (bool) $value;
}
View
12 lib/Doctrine/DBAL/Types/DateTimeType.php
@@ -9,6 +9,11 @@
*/
class DateTimeType extends Type
{
+ public function getName()
+ {
+ return 'DateTime';
+ }
+
/**
* {@inheritdoc}
*/
@@ -24,17 +29,16 @@ public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platfo
*/
public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
{
- //TODO: howto? dbms specific? delegate to platform?
- return $value;
+ return $value->format($platform->getDateTimeFormatString());
}
/**
* {@inheritdoc}
*
* @override
*/
- public function convertToObjectValue($value)
+ public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
{
- return new \DateTime($value);
+ return \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);
}
}
View
2 lib/Doctrine/DBAL/Types/DecimalType.php
@@ -19,7 +19,7 @@ public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platfo
return $platform->getDecimalTypeDeclarationSql($fieldDeclaration);
}
- public function convertToPHPValue($value)
+ public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
{
return (double) $value;
}
View
2 lib/Doctrine/DBAL/Types/IntegerType.php
@@ -18,7 +18,7 @@ public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platfo
return $platform->getIntegerTypeDeclarationSql($fieldDeclaration);
}
- public function convertToPHPValue($value)
+ public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
{
return (int) $value;
}
View
2 lib/Doctrine/DBAL/Types/SmallIntType.php
@@ -19,7 +19,7 @@ public function getSqlDeclaration(array $fieldDeclaration, \Doctrine\DBAL\Platfo
return $platform->getSmallIntTypeDeclarationSql($fieldDeclaration);
}
- public function convertToPHPValue($value)
+ public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
{
return (int) $value;
}
View
2 lib/Doctrine/DBAL/Types/Type.php
@@ -45,7 +45,7 @@ public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\Abstract
return $value;
}
- public function convertToPHPValue($value)
+ public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
{
return $value;
}
View
7 lib/Doctrine/ORM/Internal/Hydration/AbstractHydrator.php
@@ -61,6 +61,7 @@
public function __construct(\Doctrine\ORM\EntityManager $em)
{
$this->_em = $em;
+ $this->_platform = $em->getConnection()->getDatabasePlatform();
$this->_uow = $em->getUnitOfWork();
}
@@ -213,15 +214,15 @@ protected function _gatherRowData(&$data, &$cache, &$id, &$nonemptyComponents)
$id[$dqlAlias] .= '|' . $value;
}
- $rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value);
+ $rowData[$dqlAlias][$cache[$key]['fieldName']] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
if ( ! isset($nonemptyComponents[$dqlAlias]) && $value !== null) {
$nonemptyComponents[$dqlAlias] = true;
}
/* TODO: Consider this instead of the above 4 lines. */
/*if ($value !== null) {
- $rowData[$dqlAlias][$fieldName] = $cache[$key]['type']->convertToPHPValue($value);
+ $rowData[$dqlAlias][$fieldName] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
}*/
}
@@ -268,7 +269,7 @@ protected function _gatherScalarRowData(&$data, &$cache)
$rowData[/*$dqlAlias . '_' . */$fieldName] = $value;
} else {
$dqlAlias = $cache[$key]['dqlAlias'];
- $rowData[$dqlAlias . '_' . $fieldName] = $cache[$key]['type']->convertToPHPValue($value);
+ $rowData[$dqlAlias . '_' . $fieldName] = $cache[$key]['type']->convertToPHPValue($value, $this->_platform);
}
}
View
3 lib/Doctrine/ORM/Persisters/StandardEntityPersister.php
@@ -90,6 +90,7 @@ class StandardEntityPersister
public function __construct(EntityManager $em, ClassMetadata $class)
{
$this->_em = $em;
+ $this->_platform = $em->getConnection()->getDatabasePlatform();
$this->_evm = $em->getEventManager();
$this->_entityName = $class->name;
$this->_conn = $em->getConnection();
@@ -343,7 +344,7 @@ public function load(array $criteria, $entity = null)
foreach ($stmt->fetch(Connection::FETCH_ASSOC) as $column => $value) {
$fieldName = $this->_class->fieldNames[$column];
$data[$fieldName] = Type::getType($this->_class->getTypeOfField($fieldName))
- ->convertToPHPValue($value);
+ ->convertToPHPValue($value, $this->_platform);
}
$stmt->closeCursor();
View
12 lib/Doctrine/ORM/Query/AST/Functions/CurrentDateFunction.php
@@ -1,8 +1,4 @@
<?php
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
namespace Doctrine\ORM\Query\AST\Functions;
@@ -18,8 +14,7 @@ class CurrentDateFunction extends FunctionNode
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
- //TODO: Use platform to get SQL
- return 'CURRENT_DATE';
+ return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentDateSql();
}
/**
@@ -29,6 +24,7 @@ public function parse(\Doctrine\ORM\Query\Parser $parser)
{
$lexer = $parser->getLexer();
$parser->match($lexer->lookahead['value']);
+ $parser->match('(');
+ $parser->match(')');
}
-}
-
+}
View
3 lib/Doctrine/ORM/Query/AST/Functions/CurrentTimeFunction.php
@@ -18,8 +18,7 @@ class CurrentTimeFunction extends FunctionNode
*/
public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
{
- //TODO: Use platform to get SQL
- return 'CURRENT_TIME';
+ return $sqlWalker->getConnection()->getDatabasePlatform()->getCurrentTimeSql();
}
/**
View
2 tests/Doctrine/Tests/DBAL/AllTests.php
@@ -28,6 +28,8 @@ public static function suite()
$suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\PostgreSqlPlatformTest');
$suite->addTestSuite('Doctrine\Tests\DBAL\Platforms\MsSqlPlatformTest');
+ $suite->addTestSuite('Doctrine\Tests\DBAL\Types\DateTimeTest');
+
$suite->addTest(Functional\AllTests::suite());
return $suite;
View
18 tests/Doctrine/Tests/DBAL/Mocks/MockPlatform.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Doctrine\Tests\DBAL\Mocks;
+
+use Doctrine\DBAL\Platforms;
+
+class MockPlatform extends \Doctrine\DBAL\Platforms\AbstractPlatform
+{
+ public function getIntegerTypeDeclarationSql(array $columnDef) {}
+ public function getBigIntTypeDeclarationSql(array $columnDef) {}
+ public function getSmallIntTypeDeclarationSql(array $columnDef) {}
+ public function _getCommonIntegerTypeDeclarationSql(array $columnDef) {}
+ public function getVarcharTypeDeclarationSql(array $field) {}
+ public function getName()
+ {
+ return 'mock';
+ }
+}
View
37 tests/Doctrine/Tests/DBAL/Types/DateTimeTest.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Doctrine\Tests\DBAL\Types;
+
+use Doctrine\DBAL\Types\Type;
+use Doctrine\Tests\DBAL\Mocks;
+
+require_once __DIR__ . '/../../TestInit.php';
+
+class DateTimeTest extends \Doctrine\Tests\DbalTestCase
+{
+ protected
+ $_platform,
+ $_type;
+
+ protected function setUp()
+ {
+ $this->_platform = new \Doctrine\Tests\DBAL\Mocks\MockPlatform();
+ $this->_type = Type::getType('datetime');
+ }
+
+ public function testDateTimeConvertsToDatabaseValue()
+ {
+ $this->assertTrue(
+ is_string($this->_type->convertToDatabaseValue(new \DateTime(), $this->_platform))
+ );
+ }
+
+ public function testDateTimeConvertsToPHPValue()
+ {
+ // Birthday of jwage and also birthday of Doctrine. Send him a present ;)
+ $this->assertTrue(
+ $this->_type->convertToPHPValue('1985-09-01 00:00:00', $this->_platform)
+ instanceof \DateTime
+ );
+ }
+}
View
20 tests/Doctrine/Tests/Models/Generic/DateTimeModel.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Doctrine\Tests\Models\Generic;
+
+/**
+ * @Entity
+ * @Table(name="date_time_model")
+ */
+class DateTimeModel
+{
+ /**
+ * @Id @Column(type="integer")
+ * @GeneratedValue(strategy="AUTO")
+ */
+ public $id;
+ /**
+ * @Column(type="datetime")
+ */
+ public $datetime;
+}
View
6 tests/Doctrine/Tests/ORM/Query/SelectSqlGenerationTest.php
@@ -281,6 +281,12 @@ public function testMemberOfExpression()
);
}
+ public function testCurrentDateFunction()
+ {
+ $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_date()');
+ $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.datetime > CURRENT_DATE', $q->getSql());
+ }
+
/*public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition()
{
$this->assertSqlGeneration(
View
9 tests/Doctrine/Tests/OrmFunctionalTestCase.php
@@ -44,7 +44,10 @@ class OrmFunctionalTestCase extends OrmTestCase
'Doctrine\Tests\Models\Company\CompanyEmployee',
'Doctrine\Tests\Models\Company\CompanyManager'
),
- 'ecommerce' => array()
+ 'ecommerce' => array(),
+ 'generic' => array(
+ 'Doctrine\Tests\Models\Generic\DateTimeModel'
+ )
);
protected function useModelSet($setName)
@@ -72,7 +75,9 @@ protected function tearDown()
$conn->exec('DELETE FROM company_employees');
$conn->exec('DELETE FROM company_persons');
}
-
+ if (isset($this->_usedModelSets['generic'])) {
+ $conn->exec('DELETE FROM date_time_model');
+ }
$this->_em->clear();
}

0 comments on commit ada2c5c

Please sign in to comment.