summaryrefslogtreecommitdiff
path: root/vendor/doctrine/dbal/src/Driver/Mysqli/Driver.php
blob: 9855e565da8c605a1316069039cf44fba7722d85 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Driver\Mysqli;

use Doctrine\DBAL\Driver\AbstractMySQLDriver;
use Doctrine\DBAL\Driver\Mysqli\Exception\ConnectionFailed;
use Doctrine\DBAL\Driver\Mysqli\Exception\HostRequired;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Charset;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Options;
use Doctrine\DBAL\Driver\Mysqli\Initializer\Secure;
use Generator;
use mysqli;
use mysqli_sql_exception;
use SensitiveParameter;

final class Driver extends AbstractMySQLDriver
{
    /**
     * {@inheritDoc}
     */
    public function connect(
        #[SensitiveParameter]
        array $params,
    ): Connection {
        if (! empty($params['persistent'])) {
            if (! isset($params['host'])) {
                throw HostRequired::forPersistentConnection();
            }

            $host = 'p:' . $params['host'];
        } else {
            $host = $params['host'] ?? '';
        }

        $connection = new mysqli();

        foreach ($this->compilePreInitializers($params) as $initializer) {
            $initializer->initialize($connection);
        }

        try {
            $success = @$connection->real_connect(
                $host,
                $params['user'] ?? '',
                $params['password'] ?? '',
                $params['dbname'] ?? '',
                $params['port'] ?? 0,
                $params['unix_socket'] ?? '',
                $params['driverOptions'][Connection::OPTION_FLAGS] ?? 0,
            );
        } catch (mysqli_sql_exception $e) {
            throw ConnectionFailed::upcast($e);
        }

        if (! $success) {
            throw ConnectionFailed::new($connection);
        }

        foreach ($this->compilePostInitializers($params) as $initializer) {
            $initializer->initialize($connection);
        }

        return new Connection($connection);
    }

    /**
     * @param array<string, mixed> $params
     *
     * @return Generator<int, Initializer>
     */
    private function compilePreInitializers(
        #[SensitiveParameter]
        array $params,
    ): Generator {
        unset($params['driverOptions'][Connection::OPTION_FLAGS]);

        if (isset($params['driverOptions']) && $params['driverOptions'] !== []) {
            yield new Options($params['driverOptions']);
        }

        if (
            ! isset($params['ssl_key']) &&
            ! isset($params['ssl_cert']) &&
            ! isset($params['ssl_ca']) &&
            ! isset($params['ssl_capath']) &&
            ! isset($params['ssl_cipher'])
        ) {
            return;
        }

        yield new Secure(
            $params['ssl_key']    ?? '',
            $params['ssl_cert']   ?? '',
            $params['ssl_ca']     ?? '',
            $params['ssl_capath'] ?? '',
            $params['ssl_cipher'] ?? '',
        );
    }

    /**
     * @param array<string, mixed> $params
     *
     * @return Generator<int, Initializer>
     */
    private function compilePostInitializers(
        #[SensitiveParameter]
        array $params,
    ): Generator {
        if (! isset($params['charset'])) {
            return;
        }

        yield new Charset($params['charset']);
    }
}