PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Symfony/Doctrine:Como fazer o Doctrine funcionar com socket Unix?


Depois de depurar o driver do Doctrine, criei uma solução não tão elegante, mas mesmo assim está funcionando e pode ser melhorada.

Não gosto de acessar a variável de ambiente no próprio driver, mas possivelmente isso pode ser melhorado.

doctrine.yaml
doctrine:
    dbal:
        #driver:   %database_driver%
        driver_class: App\Infrastructure\Common\Service\PostgreSQLDoctrineDriver
        host:     %database_host%
        port:     %database_port%
        dbname:   %database_name%
        user:     %database_user%
        password: %database_password%
        #charset:  UTF8

    orm:
        auto_generate_proxy_classes: %kernel.debug%
        auto_mapping: true

PostgreSQLDoctrineDriver.php
<?php declare(strict_types=1);

namespace App\Infrastructure\Common\Service;

use Doctrine\DBAL\DBALException;
use Doctrine\DBAL\Driver\PDOConnection;
use Doctrine\DBAL\Driver\PDOPgSql\Driver;
use \PDO;
use \PDOException;
use function defined;

/**
 * Driver that connects through pdo_pgsql
 *
 * Forked original PostgreSQL driver, extended to have a possibility to pass raw PDO DSN to be
 * able to connect via Unix socket
 */
class PostgreSQLDoctrineDriver extends Driver
{
    /**
     * {@inheritdoc}
     */
    public function connect(array $params, $username = null, $password = null, array $driverOptions = [])
    {
        try {
            $pdo = new PDOConnection(
                $_SERVER['POSTGRES_DB_PDO_DSN'] ?? '',
                $username,
                $password,
                $driverOptions
            );

            if (defined('PDO::PGSQL_ATTR_DISABLE_PREPARES')
                && (! isset($driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES])
                    || $driverOptions[PDO::PGSQL_ATTR_DISABLE_PREPARES] === true
                )
            ) {
                $pdo->setAttribute(PDO::PGSQL_ATTR_DISABLE_PREPARES, true);
            }

            /* defining client_encoding via SET NAMES to avoid inconsistent DSN support
             * - the 'client_encoding' connection param only works with postgres >= 9.1
             * - passing client_encoding via the 'options' param breaks pgbouncer support
             */
            if (isset($params['charset'])) {
                $pdo->exec('SET NAMES \'' . $params['charset'] . '\'');
            }

            return $pdo;
        } catch (PDOException $e) {
            throw DBALException::driverException($this, $e);
        }
    }

    /**
     * {@inheritdoc}
     */
    public function getName()
    {
        return 'pdo_pgsql';
    }
}