Browse Source

[DoctrineBundle] Add support to configure DBAL Types through the dbal configuration section.

Benjamin Eberlei 14 năm trước cách đây
mục cha
commit
3c9c43d592

+ 63 - 0
src/Symfony/Bundle/DoctrineBundle/ConnectionFactory.php

@@ -0,0 +1,63 @@
+<?php
+
+/*
+ * This file is part of the Symfony framework.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * This source file is subject to the MIT license that is bundled
+ * with this source code in the file LICENSE.
+ */
+
+namespace Symfony\Bundle\DoctrineBundle;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Doctrine\Common\EventManager;
+use Doctrine\DBAL\Configuration;
+use Doctrine\DBAL\DriverManager;
+use Doctrine\DBAL\Types\Type;
+
+/**
+ * Connection
+ */
+class ConnectionFactory
+{
+    private $typesConfig = array();
+    private $initialized = false;
+
+    /**
+     * @param ContainerInterface $container
+     * @param array $typesConfig
+     */
+    public function __construct(array $typesConfig)
+    {
+        $this->typesConfig = $typesConfig;
+    }
+
+    /**
+     * Create a connection by name.
+     * 
+     * @param  string $connectionName
+     * @return Doctrine\DBAL\Connection
+     */
+    public function createConnection(array $params, Configuration $config = null, EventManager $eventManager = null)
+    {
+        if (!$this->initialized) {
+            $this->initializeTypes();
+            $this->initialized = true;
+        }
+
+        return DriverManager::getConnection($params, $config, $eventManager);
+    }
+
+    private function initializeTypes()
+    {
+        foreach ($this->typesConfig AS $type => $className) {
+            if (Type::hasType($type)) {
+                Type::overrideType($type, $className);
+            } else {
+                Type::addType($type, $className);
+            }
+        }
+    }
+}

+ 19 - 2
src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php

@@ -48,6 +48,7 @@ class DoctrineExtension extends AbstractDoctrineExtension
 
         $container->setAlias('database_connection', sprintf('doctrine.dbal.%s_connection', $config['default_connection']));
         $container->setParameter('doctrine.dbal.default_connection', $config['default_connection']);
+        $container->setParameter('doctrine.dbal.types', $config['types']);
 
         foreach ($config['connections'] as $name => $connection) {
             $this->loadDbalConnection($connection, $container);
@@ -91,6 +92,7 @@ class DoctrineExtension extends AbstractDoctrineExtension
         );
         $mergedConfig = array(
             'default_connection'  => 'default',
+            'types' => array(),
         );
         $connectionDefaults = array(
             'driver' => array(
@@ -112,6 +114,20 @@ class DoctrineExtension extends AbstractDoctrineExtension
             } else if (isset($config['default_connection'])) {
                 $mergedConfig['default_connection'] = $config['default_connection'];
             }
+
+            // Handle DBAL Types
+            if (isset($config['types'])) {
+                if (isset($config['types']['type'][0])) {
+                    $config['types'] = $config['types']['type'];
+                }
+                foreach ($config['types'] AS $name => $type) {
+                    if (is_array($type) && isset($type['name']) && isset($type['class'])) { // xml case
+                        $mergedConfig['types'][$type['name']] = $type['class'];
+                    } else { // yml case
+                        $mergedConfig['types'][$name] = $type;
+                    }
+                }
+            }
         }
 
         foreach ($configs as $config) {
@@ -161,8 +177,9 @@ class DoctrineExtension extends AbstractDoctrineExtension
 
         $driverOptions = $connection['driver'];
 
-        $driverDef = new Definition('Doctrine\DBAL\DriverManager');
-        $driverDef->setFactoryMethod('getConnection');
+        $driverDef = new Definition('Doctrine\DBAL\Connection');
+        $driverDef->setFactoryService('doctrine.dbal.connection_factory');
+        $driverDef->setFactoryMethod('createConnection');
         $container->setDefinition(sprintf('doctrine.dbal.%s_connection', $connection['name']), $driverDef);
 
         // event manager

+ 5 - 0
src/Symfony/Bundle/DoctrineBundle/Resources/config/dbal.xml

@@ -11,6 +11,7 @@
         <parameter key="doctrine.dbal.configuration_class">Doctrine\DBAL\Configuration</parameter>
         <parameter key="doctrine.data_collector.class">Symfony\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector</parameter>
         <parameter key="doctrine.dbal.event_manager_class">Doctrine\Common\EventManager</parameter>
+        <parameter key="doctrine.dbal.connection_factory_class">Symfony\Bundle\DoctrineBundle\ConnectionFactory</parameter>
         <parameter key="doctrine.dbal.events.mysql_session_init.class">Doctrine\DBAL\Event\Listeners\MysqlSessionInit</parameter>
         <parameter key="doctrine.dbal.events.oracle_session_init.class">Doctrine\DBAL\Event\Listeners\OracleSessionInit</parameter>
         <parameter key="doctrine.dbal.logging">0</parameter>
@@ -27,5 +28,9 @@
             <tag name="data_collector" template="DoctrineBundle:Collector:db" id="db" />
             <argument type="service" id="doctrine.dbal.logger" />
         </service>
+
+        <service id="doctrine.dbal.connection_factory" class="%doctrine.dbal.connection_factory_class%">
+            <argument>%doctrine.dbal.types%</argument>
+        </service>
     </services>
 </container>

+ 12 - 0
src/Symfony/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd

@@ -10,6 +10,7 @@
     <xsd:complexType name="dbal">
         <xsd:all>
             <xsd:element name="connections" type="connections" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="types" type="types" minOccurs="0" maxOccurs="1" />
         </xsd:all>
 
         <xsd:attribute name="default-connection" type="xsd:string" />
@@ -36,6 +37,17 @@
         </xsd:choice>
     </xsd:complexType>
 
+    <xsd:complexType name="types">
+        <xsd:choice minOccurs="1" maxOccurs="unbounded">
+            <xsd:element name="type" type="type" />
+        </xsd:choice>
+    </xsd:complexType>
+
+    <xsd:complexType name="type">
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+        <xsd:attribute name="class" type="xsd:string" use="required" />
+    </xsd:complexType>
+
     <xsd:complexType name="connection">
         <xsd:attribute name="name" type="xsd:string" use="required" />
         <xsd:attribute name="dbname" type="xsd:string" use="required" />

+ 4 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/ContainerTest.php

@@ -11,6 +11,8 @@
 
 namespace Symfony\Bundle\DoctrineBundle\Tests;
 
+use Doctrine\DBAL\Types\Type;
+
 class ContainerTest extends TestCase
 {
     public function testContainer()
@@ -37,5 +39,7 @@ class ContainerTest extends TestCase
         $this->assertInstanceOf('Symfony\Bundle\DoctrineBundle\CacheWarmer\ProxyCacheWarmer', $container->get('doctrine.orm.proxy_cache_warmer'));
 
         $this->assertSame($container->get('my.platform'), $container->get('doctrine.dbal.default_connection')->getDatabasePlatform());
+
+        $this->assertTrue(Type::hasType('test'));
     }
 }

+ 23 - 6
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php

@@ -146,7 +146,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $loader->ormLoad(array($config), $container);
 
         $definition = $container->getDefinition('doctrine.dbal.default_connection');
-        $this->assertEquals('Doctrine\DBAL\DriverManager', $definition->getClass());
+        $this->assertEquals('Doctrine\DBAL\Connection', $definition->getClass());
 
         $args = $definition->getArguments();
         $this->assertEquals('pdo_mysql', $args[0]['driver']);
@@ -194,7 +194,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $loader->ormLoad(array(array()), $container);
 
         $definition = $container->getDefinition('doctrine.dbal.default_connection');
-        $this->assertEquals('Doctrine\DBAL\DriverManager', $definition->getClass());
+        $this->assertEquals('Doctrine\DBAL\Connection', $definition->getClass());
 
         $definition = $container->getDefinition('doctrine.orm.default_entity_manager');
         $this->assertEquals('%doctrine.orm.entity_manager_class%', $definition->getClass());
@@ -222,7 +222,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $container->compile();
 
         $definition = $container->getDefinition('doctrine.dbal.default_connection');
-        $this->assertEquals('Doctrine\DBAL\DriverManager', $definition->getClass());
+        $this->assertEquals('Doctrine\DBAL\Connection', $definition->getClass());
 
         $this->assertDICConstructorArguments($definition, array(
             array(
@@ -260,7 +260,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $container->compile();
 
         $definition = $container->getDefinition('doctrine.dbal.default_connection');
-        $this->assertEquals('Doctrine\DBAL\DriverManager', $definition->getClass());
+        $this->assertEquals('Doctrine\DBAL\Connection', $definition->getClass());
 
         $this->assertDICConstructorArguments($definition, array(
             array(
@@ -300,7 +300,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $container->compile();
 
         $definition = $container->getDefinition('doctrine.dbal.conn1_connection');
-        $this->assertEquals('Doctrine\DBAL\DriverManager', $definition->getClass());
+        $this->assertEquals('Doctrine\DBAL\Connection', $definition->getClass());
 
         $args = $definition->getArguments();
         $this->assertEquals('pdo_sqlite', $args[0]['driver']);
@@ -323,7 +323,7 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $this->assertEquals('doctrine.orm.dm1_configuration', (string) $arguments[1]);
 
         $definition = $container->getDefinition('doctrine.dbal.conn2_connection');
-        $this->assertEquals('Doctrine\DBAL\DriverManager', $definition->getClass());
+        $this->assertEquals('Doctrine\DBAL\Connection', $definition->getClass());
 
         $args = $definition->getArguments();
         $this->assertEquals('pdo_sqlite', $args[0]['driver']);
@@ -626,6 +626,23 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         $this->assertEquals('DoctrineBundle\Tests\DependencyInjection\Fixtures\Bundles\Vendor\AnnotationsBundle\Entity', $calls[0][1][1]);
     }
 
+    public function testSetTypes()
+    {
+        $container = $this->getContainer(array('YamlBundle'));
+
+        $loader = new DoctrineExtension();
+        $container->registerExtension($loader);
+        $this->loadFromFile($container, 'dbal_types');
+        $container->getCompilerPassConfig()->setOptimizationPasses(array());
+        $container->getCompilerPassConfig()->setRemovingPasses(array());
+        $container->compile();
+
+        $this->assertEquals(
+            array('test' => 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType'),
+            $container->getParameter('doctrine.dbal.types')
+        );
+    }
+
     protected function getContainer($bundles = 'YamlBundle', $vendor = null)
     {
         if (!is_array($bundles)) {

+ 14 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/dbal_types.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+
+<container xmlns="http://www.symfony-project.org/schema/dic/services"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:doctrine="http://www.symfony-project.org/schema/dic/doctrine"
+    xsi:schemaLocation="http://www.symfony-project.org/schema/dic/services http://www.symfony-project.org/schema/dic/services/services-1.0.xsd
+                        http://www.symfony-project.org/schema/dic/doctrine http://www.symfony-project.org/schema/dic/doctrine/doctrine-1.0.xsd">
+
+    <doctrine:dbal>
+        <doctrine:types>
+            <doctrine:type name="test" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType" />
+        </doctrine:types>
+    </doctrine:dbal>
+</container>

+ 3 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/dbal_types.yml

@@ -0,0 +1,3 @@
+doctrine.dbal:
+  types:
+    test: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType

+ 27 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/TestType.php

@@ -0,0 +1,27 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection;
+
+use Doctrine\DBAL\Platforms\AbstractPlatform;
+
+class TestType extends \Doctrine\DBAL\Types\Type
+{
+    public function getName()
+    {
+        return 'test';
+    }
+
+    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
+    {
+        return '';
+    }
+}

+ 4 - 1
src/Symfony/Bundle/DoctrineBundle/Tests/TestCase.php

@@ -63,7 +63,10 @@ class TestCase extends \PHPUnit_Framework_TestCase
                     'charset' => 'UTF-8',
                     'platform-service' => 'my.platform',
                 )
-            )
+            ),
+            'types' => array(
+                'test' => 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestType',
+            ),
         )), $container);
         $loader->ormLoad(array(
             array(