Skip to content

Instantly share code, notes, and snippets.

@phpfour
Created October 14, 2017 10:22
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save phpfour/4290cc1f0892dda4ef94a492d6b3f81e to your computer and use it in GitHub Desktop.
Save phpfour/4290cc1f0892dda4ef94a492d6b3f81e to your computer and use it in GitHub Desktop.
Doctrine2 Oracle
services:
app.doctrine.dbal.events.oracle_session_init.listener:
class: AppBundle\EventListener\OracleSessionInitListener
tags:
- { name: doctrine.event_listener, event: postConnect }
app.doctrine.dbal.oracle_platform.type_mapping.listener:
class: AppBundle\EventListener\OracleDoctrineTypeMappingListener
tags:
- { name: doctrine.event_listener, event: postConnect }
<?php
namespace AppBundle\EventListener;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Events;
use Doctrine\Common\EventSubscriber;
/**
* Changes Doctrine's default Oracle-specific column type mapping to Doctrine
* mapping types. This listener modifies doctrine type mapping for
* OraclePlatform.
*
* See:
* Doctrine Field Mapping: https://doctrine-orm.readthedocs.org/en/latest/reference/basic-mapping.html#doctrine-mapping-types
* Relevant Bug Report: http://www.doctrine-project.org/jira/browse/DBAL-434
* Oracle DATE docs: http://docs.oracle.com/cd/B28359_01/server.111/b28318/datatype.htm#i1847
*/
class OracleDoctrineTypeMappingListener implements EventSubscriber
{
public function getSubscribedEvents()
{
return array(Events::postConnect);
}
/**
* Doctrine defines its primary database abstraction information in what it
* calls "Platform" classes (e.g. Doctrine\DBAL\Platforms\AbstractPlatform).
* Each database Doctrine supports implements a Platform file
* (e.g. OraclePlatform or MySqlPlatform).
*
* \Doctrine\DBAL\Platforms\OraclePlatform maps "DATE" fields to Doctrine's
* own "datetime" type, which returns it as \DateTime. The problem is that
* internally, Oracle DOES store time data as part of its "DATE" field (even
* if it's not visible in its default representation DD-MON-RR ==
* "30-JUL-13"). Thus the Doctrine core devs thought it best to map the
* database tyep "DATE" to Doctrine's "datetime" type.
*
* But if in your case you will never require time data with your DATE
* fields this will change Oracle's "DATE" fields to be mapped
* to Doctrine's "date" mapping type. This is the same behavior as almost
* every other DBAL driver (except SQLServer, which does its own crazy
* stuff).
*
* @param ConnectionEventArgs $args
* @return void
*/
public function postConnect(ConnectionEventArgs $args)
{
if ($args->getConnection()->getDatabasePlatform()->getName() == 'oracle') {
$args
->getConnection()
->getDatabasePlatform()
->registerDoctrineTypeMapping('date', 'date');
}
}
}
<?php
namespace AppBundle\EventListener;
use Doctrine\DBAL\Event\ConnectionEventArgs;
use Doctrine\DBAL\Event\Listeners\OracleSessionInit;
/**
* Should be used when Oracle Server default environment does not match the Doctrine requirements.
*
* The following environment variables are required for the Doctrine default date format:
*
* NLS_TIME_FORMAT="HH24:MI:SS"
* NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"
* NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS"
* NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS TZH:TZM"
*
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @link www.doctrine-project.com
* @since 2.0
* @author Benjamin Eberlei <kontakt@beberlei.de>
*/
class OracleSessionInitListener extends OracleSessionInit
{
/**
* @param ConnectionEventArgs $args
*
* @return void
*/
public function postConnect(ConnectionEventArgs $args)
{
if ($args->getConnection()->getDatabasePlatform()->getName() == 'oracle') {
parent::postConnect($args);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment