cycle / database

Database Abstraction Layer, Schema Introspection, Schema Generation, Query Builders
MIT License
54 stars 23 forks source link

💡 Get already configured \PDO connection from `Database` instance. #115

Closed gam6itko closed 1 year ago

gam6itko commented 1 year ago

I have an idea!

Hello! Some legacy classes in my project required \PDO instance. At the moment I am not able to get it from Database instance.

In doctrine we have this opportunity.

/* @var \Doctrine\DBAL\Driver\PDOConnection $pdo */
$pdo = $entityManager->getConnection()->getWrappedConnection();

I need some similar method in cycle.

roxblnfk commented 1 year ago

You can get PDO instance using closure:

$pdo = (fn () => $this->getPDO())->call($driver);

But it doesn't guarantie that PDO connection hasn't got a timeout error. If you want to just get a PDO connection that mustn't depend on DBAL then use

$pdo = (fn () => $this->createPDO())->call($driver);
gam6itko commented 1 year ago

Some variants for me


```php
// creates new Pdo connectino
class PdoFactory
{
    protected function __construct(
        protected DriverConfig $config
    ) {}

    /**
     * Create instance of configured PDO class.
     */
    public function createPDO(): PDO|PDOInterface
    {
        $connection = $this->config->connection;

        if (!$connection instanceof PDOConnectionConfig) {
            throw new \InvalidArgumentException(
                'Could not establish PDO connection using non-PDO configuration'
            );
        }

        return new PDO(
            dsn: $connection->getDsn(),
            username: $connection->getUsername(),
            password: $connection->getPassword(),
            options: $connection->getOptions(),
        );
    }
}
AnrDaemon commented 1 year ago

But it doesn't guarantee that PDO connection hasn't got a timeout error.

Many drivers support automatic recovery for such case. F.e. PDO::MYSQL_ATTR_INIT_COMMAND.