Completed
Push — 1.x ( 980d56...edf1de )
by Akihito
14s queued 12s
created

EnvConnection::__invoke()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 10
c 2
b 0
f 0
nc 2
nop 0
dl 0
loc 16
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Ray\AuraSqlModule;
6
7
use Aura\Sql\ExtendedPdo;
8
9
use function array_rand;
10
use function explode;
11
use function getenv;
12
use function preg_match;
13
use function sprintf;
14
15
final class EnvConnection
16
{
17
    private string $dsn;
18
    private string $username;
19
    private string $password;
20
21
    /** @var array<string> */
22
    private array $options;
23
24
    /** @var array<string> */
25
    private array $queries;
26
27
    /** @var array<ExtendedPdo> */
28
    private static array $pdo = [];
29
    private ?string $slave;
30
31
    /**
32
     * @phpstan-param array<string> $options
33
     * @phpstan-param array<string> $queries
34
     */
35
    public function __construct(
36
        string $dsn,
37
        ?string $slave,
38
        string $username = '',
39
        string $password = '',
40
        array $options = [],
41
        array $queries = []
42
    ) {
43
        $this->dsn = $dsn;
44
        $this->slave = $slave;
45
        $this->username = $username;
46
        $this->password = $password;
47
        $this->options = $options;
48
        $this->queries = $queries;
49
    }
50
51
    public function __invoke(): ExtendedPdo
52
    {
53
        $dsn = $this->getDsn();
54
        if (isset(self::$pdo[$dsn])) {
55
            return self::$pdo[$dsn];
56
        }
57
58
        self::$pdo[$dsn] = new ExtendedPdo(
59
            $dsn,
60
            (string) getenv($this->username),
61
            (string) getenv($this->password),
62
            $this->options,
63
            $this->queries
64
        );
65
66
        return self::$pdo[$dsn];
67
    }
68
69
    private function getDsn(): string
70
    {
71
        // write
72
        if ($this->slave === null) {
73
            return (string) getenv($this->dsn);
74
        }
75
76
        // random read
77
        $slaveList = explode(',', (string) getenv($this->slave));
78
        $slave = $slaveList[array_rand($slaveList)];
79
80
        return $this->changeHost((string) getenv($this->dsn), $slave);
81
    }
82
83
    /**
84
     * @psalm-pure
85
     */
86
    private function changeHost(string $dsn, string $host): string
87
    {
88
        preg_match(AuraSqlModule::PARSE_PDO_DSN_REGEX, $dsn, $parts);
89
        if (! $parts) {
90
            // @codeCoverageIgnoreStart
91
            return $dsn;
92
            // @codeCoverageIgnoreEnd
93
        }
94
95
        return sprintf('%s:%s=%s;%s', $parts[1], $parts[2], $host, $parts[3]);
96
    }
97
}
98