Passed
Branch php71 (acb31d)
by Eugene
02:53
created

Dsn::isTcp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Tarantool Client package.
7
 *
8
 * (c) Eugene Leonovich <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Tarantool\Client;
15
16
final class Dsn
17
{
18
    private $host;
19
    private $port;
20
    private $path;
21
    private $connectionUri;
22
    private $username;
23
    private $password;
24
    private $isTcp = false;
25
    private $options;
26
27 128
    private function __construct(string $connectionUri)
28
    {
29 128
        $this->connectionUri = $connectionUri;
30 128
    }
31
32 150
    public static function parse(string $dsn) : self
33
    {
34 150
        if (0 === \strpos($dsn, 'unix://') && isset($dsn[7])) {
35 58
            return self::parseUds($dsn);
36
        }
37
38 92
        if (false === $parsed = \parse_url($dsn)) {
39 4
            self::throwParseError($dsn);
40
        }
41 88
        if (!isset($parsed['scheme'], $parsed['host']) || 'tcp' !== $parsed['scheme']) {
42 16
            self::throwParseError($dsn);
43
        }
44 72
        if (isset($parsed['path']) && '/' !== $parsed['path']) {
45
            self::throwParseError($dsn);
46
        }
47
48 72
        $self = new self('tcp://'.$parsed['host'].':'.($parsed['port'] ?? '3301'));
49 72
        $self->host = $parsed['host'];
50 72
        $self->port = $parsed['port'] ?? 3301;
51 72
        $self->isTcp = true;
52
53 72
        if (isset($parsed['user'])) {
54 6
            $self->username = rawurldecode($parsed['user']);
55 6
            $self->password = isset($parsed['pass']) ? rawurldecode($parsed['pass']) : '';
56
        }
57
58 72
        if (isset($parsed['query'])) {
59 48
            \parse_str($parsed['query'], $self->options);
60
        }
61
62 72
        return $self;
63
    }
64
65 58
    private static function parseUds(string $dsn) : self
66
    {
67 58
        $parts = explode('@', substr($dsn, 7), 2);
68 58
        if (isset($parts[1])) {
69 8
            $parsed = \parse_url($parts[1]);
70 8
            $authority = explode(':', $parts[0]);
71
        } else {
72 50
            $parsed = \parse_url($parts[0]);
73
        }
74
75 58
        if (false === $parsed) {
76
            self::throwParseError($dsn);
77
        }
78 58
        if (isset($parsed['host'])) {
79 2
            self::throwParseError($dsn);
80
        }
81
82 56
        $self = new self('unix://'.$parsed['path']);
83 56
        $self->path = rawurldecode($parsed['path']);
84
85 56
        if (isset($authority)) {
86 8
            $self->username = rawurldecode($authority[0]);
87 8
            $self->password = isset($authority[1]) ? rawurldecode($authority[1]) : '';
88
        }
89 56
        if (isset($parsed['query'])) {
90 42
            \parse_str($parsed['query'], $self->options);
91
        }
92
93 56
        return $self;
94
    }
95
96 34
    public function getConnectionUri() : string
97
    {
98 34
        return $this->connectionUri;
99
    }
100
101 34
    public function getHost() : ?string
102
    {
103 34
        return $this->host;
104
    }
105
106 34
    public function getPort() : ?int
107
    {
108 34
        return $this->port;
109
    }
110
111 34
    public function getPath() : ?string
112
    {
113 34
        return $this->path;
114
    }
115
116 14
    public function getUsername() : ?string
117
    {
118 14
        return $this->username;
119
    }
120
121 14
    public function getPassword() : ?string
122
    {
123 14
        return $this->password;
124
    }
125
126
    public function isTcp() : bool
127
    {
128
        return $this->isTcp;
129
    }
130
131 22
    public function getString(string $name, ?string $default = null) : ?string
132
    {
133 22
        return $this->options[$name] ?? $default;
134
    }
135
136 42
    public function getBool(string $name, ?bool $default = null) : ?bool
137
    {
138 42
        if (!isset($this->options[$name])) {
139 6
            return $default;
140
        }
141
142 36
        if (null === $value = \filter_var($this->options[$name], \FILTER_VALIDATE_BOOLEAN, \FILTER_NULL_ON_FAILURE)) {
143 8
            throw new \TypeError(sprintf('DSN option "%s" must be of the type bool.', $name));
144
        }
145
146 28
        return $value;
147
    }
148
149 30
    public function getInt(string $name, ?int $default = null) : ?int
150
    {
151 30
        if (!isset($this->options[$name])) {
152 6
            return $default;
153
        }
154
155 24
        if (null === $value = \filter_var($this->options[$name], \FILTER_VALIDATE_INT, \FILTER_NULL_ON_FAILURE)) {
156 16
            throw new \TypeError(sprintf('DSN option "%s" must be of the type int.', $name));
157
        }
158
159 8
        return $value;
160
    }
161
162 22
    private static function throwParseError(string $dsn) : void
163
    {
164 22
        throw new \InvalidArgumentException(\sprintf('Unable to parse DSN "%s".', $dsn));
165
    }
166
}
167