Skip to content

Instantly share code, notes, and snippets.

@phpfour
Created October 14, 2017 10:22
Show Gist options
  • Select an option

  • Save phpfour/4290cc1f0892dda4ef94a492d6b3f81e to your computer and use it in GitHub Desktop.

Select an option

Save phpfour/4290cc1f0892dda4ef94a492d6b3f81e to your computer and use it in GitHub Desktop.

Revisions

  1. phpfour created this gist Oct 14, 2017.
    57 changes: 57 additions & 0 deletions OracleDoctrineTypeMappingListener.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    <?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');
    }
    }
    }
    36 changes: 36 additions & 0 deletions OracleSessionInitListener.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    <?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 <[email protected]>
    */
    class OracleSessionInitListener extends OracleSessionInit
    {
    /**
    * @param ConnectionEventArgs $args
    *
    * @return void
    */
    public function postConnect(ConnectionEventArgs $args)
    {
    if ($args->getConnection()->getDatabasePlatform()->getName() == 'oracle') {
    parent::postConnect($args);
    }
    }
    }
    11 changes: 11 additions & 0 deletions oracle_services.yml
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,11 @@
    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 }