[2.0] Work on datetime dbal type and date portability
This commit is contained in:
parent
f28127664c
commit
ada2c5c5a7
@ -1236,6 +1236,28 @@ abstract class AbstractPlatform
|
||||
return 'SET NAMES ' . $this->quote($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
|
||||
*
|
||||
@ -1360,6 +1382,18 @@ abstract class AbstractPlatform
|
||||
throw DoctrineException::updateMe('Get charset field declaration not supported by this platform.');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@ -1461,6 +1495,15 @@ abstract class AbstractPlatform
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
|
@ -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';
|
||||
}
|
||||
}
|
@ -400,6 +400,14 @@ class MsSqlPlatform extends AbstractPlatform
|
||||
return 'CHARACTER SET ' . $charset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
|
||||
{
|
||||
return 'CHAR(' . strlen('YYYY-MM-DD HH:MM:SS') . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the platform name for this instance
|
||||
*
|
||||
|
@ -258,6 +258,14 @@ class MySqlPlatform extends AbstractPlatform
|
||||
return 'CHARACTER SET ' . $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.
|
||||
|
@ -176,6 +176,14 @@ class OraclePlatform extends AbstractPlatform
|
||||
return 'NUMBER(5)';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
|
||||
{
|
||||
return 'DATE';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
|
@ -690,6 +690,14 @@ class PostgreSqlPlatform extends AbstractPlatform
|
||||
return 'SMALLINT';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
public function getDateTimeTypeDeclarationSql(array $fieldDeclaration)
|
||||
{
|
||||
return 'TIMESTAMP without time zone';
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
|
@ -229,13 +229,19 @@ class SqlitePlatform extends AbstractPlatform
|
||||
return $this->_getCommonIntegerTypeDeclarationSql($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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@ class BooleanType extends Type
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public function convertToPHPValue($value)
|
||||
public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
return (bool) $value;
|
||||
}
|
||||
|
@ -9,6 +9,11 @@ namespace Doctrine\DBAL\Types;
|
||||
*/
|
||||
class DateTimeType extends Type
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'DateTime';
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -24,8 +29,7 @@ class DateTimeType extends Type
|
||||
*/
|
||||
public function convertToDatabaseValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
//TODO: howto? dbms specific? delegate to platform?
|
||||
return $value;
|
||||
return $value->format($platform->getDateTimeFormatString());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -33,8 +37,8 @@ class DateTimeType extends Type
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
public function convertToObjectValue($value)
|
||||
public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
return new \DateTime($value);
|
||||
return \DateTime::createFromFormat($platform->getDateTimeFormatString(), $value);
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ class DecimalType extends Type
|
||||
return $platform->getDecimalTypeDeclarationSql($fieldDeclaration);
|
||||
}
|
||||
|
||||
public function convertToPHPValue($value)
|
||||
public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
return (double) $value;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ class IntegerType extends Type
|
||||
return $platform->getIntegerTypeDeclarationSql($fieldDeclaration);
|
||||
}
|
||||
|
||||
public function convertToPHPValue($value)
|
||||
public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
return (int) $value;
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ class SmallIntType
|
||||
return $platform->getSmallIntTypeDeclarationSql($fieldDeclaration);
|
||||
}
|
||||
|
||||
public function convertToPHPValue($value)
|
||||
public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
return (int) $value;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ abstract class Type
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function convertToPHPValue($value)
|
||||
public function convertToPHPValue($value, \Doctrine\DBAL\Platforms\AbstractPlatform $platform)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ abstract class AbstractHydrator
|
||||
public function __construct(\Doctrine\ORM\EntityManager $em)
|
||||
{
|
||||
$this->_em = $em;
|
||||
$this->_platform = $em->getConnection()->getDatabasePlatform();
|
||||
$this->_uow = $em->getUnitOfWork();
|
||||
}
|
||||
|
||||
@ -213,7 +214,7 @@ abstract class AbstractHydrator
|
||||
$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;
|
||||
@ -221,7 +222,7 @@ abstract class AbstractHydrator
|
||||
|
||||
/* 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 @@ abstract class AbstractHydrator
|
||||
$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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 @@ class StandardEntityPersister
|
||||
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();
|
||||
|
||||
|
@ -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 @@ class CurrentDateFunction extends FunctionNode
|
||||
{
|
||||
$lexer = $parser->getLexer();
|
||||
$parser->match($lexer->lookahead['value']);
|
||||
$parser->match('(');
|
||||
$parser->match(')');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -28,6 +28,8 @@ class AllTests
|
||||
$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;
|
||||
|
18
tests/Doctrine/Tests/DBAL/Mocks/MockPlatform.php
Normal file
18
tests/Doctrine/Tests/DBAL/Mocks/MockPlatform.php
Normal file
@ -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';
|
||||
}
|
||||
}
|
37
tests/Doctrine/Tests/DBAL/Types/DateTimeTest.php
Normal file
37
tests/Doctrine/Tests/DBAL/Types/DateTimeTest.php
Normal file
@ -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
|
||||
);
|
||||
}
|
||||
}
|
20
tests/Doctrine/Tests/Models/Generic/DateTimeModel.php
Normal file
20
tests/Doctrine/Tests/Models/Generic/DateTimeModel.php
Normal file
@ -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;
|
||||
}
|
@ -281,6 +281,12 @@ class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
|
||||
);
|
||||
}
|
||||
|
||||
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(
|
||||
|
@ -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 @@ class OrmFunctionalTestCase extends OrmTestCase
|
||||
$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();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user