Commit ada2c5c5 authored by jwage's avatar jwage

[2.0] Work on datetime dbal type and date portability

parent f2812766
......@@ -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.
*
......
<?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';
}
}
\ No newline at end of file
......@@ -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);
}
}
\ No newline at end of file
......@@ -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();
......
<?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(')');
}
}
}
\ No newline at end of file
......@@ -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;
......
<?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';
}
}
\ No newline at end of file
<?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
);
}
}
\ No newline at end of file
<?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;
}
\ No newline at end of file
......@@ -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();
}
......
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