Skip to content

Commit 8915c05

Browse files
committed
[dsn] Cluster DSN
1 parent 5754ae3 commit 8915c05

File tree

3 files changed

+439
-145
lines changed

3 files changed

+439
-145
lines changed

Dsn.php

Lines changed: 134 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,17 @@ class Dsn
99
/**
1010
* @var string
1111
*/
12-
private $dsn;
12+
private $scheme;
1313

1414
/**
1515
* @var string
1616
*/
17-
private $scheme;
17+
private $schemeProtocol;
18+
19+
/**
20+
* @var string[]
21+
*/
22+
private $schemeExtensions;
1823

1924
/**
2025
* @var string|null
@@ -47,37 +52,43 @@ class Dsn
4752
private $queryString;
4853

4954
/**
50-
* @var array
51-
*/
52-
private $query;
53-
54-
/**
55-
* @var string
55+
* @var QueryBag
5656
*/
57-
private $schemeProtocol;
58-
59-
/**
60-
* @var string[]
61-
*/
62-
private $schemeExtensions;
63-
64-
public function __construct(string $dsn)
65-
{
66-
$this->dsn = $dsn;
67-
$this->query = [];
68-
69-
$this->parse($dsn);
70-
}
71-
72-
public function __toString(): string
73-
{
74-
return $this->dsn;
57+
private $queryBag;
58+
59+
public function __construct(
60+
string $scheme,
61+
string $schemeProtocol,
62+
array $schemeExtensions,
63+
?string $user,
64+
?string $password,
65+
?string $host,
66+
?int $port,
67+
?string $path,
68+
?string $queryString,
69+
array $query
70+
) {
71+
$this->scheme = $scheme;
72+
$this->schemeProtocol = $schemeProtocol;
73+
$this->schemeExtensions = $schemeExtensions;
74+
$this->user = $user;
75+
$this->password = $password;
76+
$this->host = $host;
77+
$this->port = $port;
78+
$this->path = $path;
79+
$this->queryString = $queryString;
80+
$this->queryBag = new QueryBag($query);
7581
}
7682

77-
public function getDsn(): string
78-
{
79-
return $this->dsn;
80-
}
83+
// public function __toString(): string
84+
// {
85+
// return $this->dsn;
86+
// }
87+
//
88+
// public function getDsn(): string
89+
// {
90+
// return $this->dsn;
91+
// }
8192

8293
public function getScheme(): string
8394
{
@@ -99,33 +110,21 @@ public function hasSchemeExtension(string $extension): bool
99110
return in_array($extension, $this->schemeExtensions, true);
100111
}
101112

102-
/**
103-
* @return null|string
104-
*/
105113
public function getUser(): ?string
106114
{
107115
return $this->user;
108116
}
109117

110-
/**
111-
* @return null|string
112-
*/
113118
public function getPassword(): ?string
114119
{
115120
return $this->password;
116121
}
117122

118-
/**
119-
* @return null|string
120-
*/
121123
public function getHost(): ?string
122124
{
123125
return $this->host;
124126
}
125127

126-
/**
127-
* @return int|null
128-
*/
129128
public function getPort(): ?int
130129
{
131130
return $this->port;
@@ -141,74 +140,44 @@ public function getQueryString(): ?string
141140
return $this->queryString;
142141
}
143142

144-
public function getQuery(): array
143+
public function getQueryBag(): QueryBag
145144
{
146-
return $this->query;
145+
return $this->queryBag;
147146
}
148147

149-
public function getQueryParameter(string $name, string $default = null): ?string
148+
public function getQuery(): array
150149
{
151-
return array_key_exists($name, $this->query) ? $this->query[$name] : $default;
150+
return $this->queryBag->toArray();
152151
}
153152

154-
public function getInt(string $name, int $default = null): ?int
153+
public function getString(string $name, string $default = null): ?string
155154
{
156-
$value = $this->getQueryParameter($name);
157-
if (null === $value) {
158-
return $default;
159-
}
160-
161-
if (false == preg_match('/^[\+\-]?[0-9]*$/', $value)) {
162-
throw InvalidQueryParameterTypeException::create($name, 'integer');
163-
}
155+
return $this->queryBag->getString($name, $default);
156+
}
164157

165-
return (int) $value;
158+
public function getDecimal(string $name, int $default = null): ?int
159+
{
160+
return $this->queryBag->getDecimal($name, $default);
166161
}
167162

168163
public function getOctal(string $name, int $default = null): ?int
169164
{
170-
$value = $this->getQueryParameter($name);
171-
if (null === $value) {
172-
return $default;
173-
}
174-
175-
if (false == preg_match('/^0[\+\-]?[0-7]*$/', $value)) {
176-
throw InvalidQueryParameterTypeException::create($name, 'integer');
177-
}
178-
179-
return intval($value, 8);
165+
return $this->queryBag->getOctal($name, $default);
180166
}
181167

182168
public function getFloat(string $name, float $default = null): ?float
183169
{
184-
$value = $this->getQueryParameter($name);
185-
if (null === $value) {
186-
return $default;
187-
}
188-
189-
if (false == is_numeric($value)) {
190-
throw InvalidQueryParameterTypeException::create($name, 'float');
191-
}
192-
193-
return (float) $value;
170+
return $this->queryBag->getFloat($name, $default);
194171
}
195172

196173
public function getBool(string $name, bool $default = null): ?bool
197174
{
198-
$value = $this->getQueryParameter($name);
199-
if (null === $value) {
200-
return $default;
201-
}
202-
203-
if (in_array($value, ['', '0', 'false'], true)) {
204-
return false;
205-
}
206-
207-
if (in_array($value, ['1', 'true'], true)) {
208-
return true;
209-
}
175+
return $this->queryBag->getBool($name, $default);
176+
}
210177

211-
throw InvalidQueryParameterTypeException::create($name, 'bool');
178+
public function getArray(string $name, bool $default = null): QueryBag
179+
{
180+
return $this->queryBag->getArray($name, $default);
212181
}
213182

214183
public function toArray()
@@ -223,11 +192,21 @@ public function toArray()
223192
'port' => $this->port,
224193
'path' => $this->path,
225194
'queryString' => $this->queryString,
226-
'query' => $this->query,
195+
'query' => $this->queryBag->toArray(),
227196
];
228197
}
229198

230-
private function parse(string $dsn): void
199+
public static function parseFirst(string $dsn): ?self
200+
{
201+
return self::parse($dsn)[0];
202+
}
203+
204+
/**
205+
* @param string $dsn
206+
*
207+
* @return Dsn[]
208+
*/
209+
public static function parse(string $dsn): array
231210
{
232211
if (false === strpos($dsn, ':')) {
233212
throw new \LogicException(sprintf('The DSN is invalid. It does not have scheme separator ":".'));
@@ -241,43 +220,87 @@ private function parse(string $dsn): void
241220
}
242221

243222
$schemeParts = explode('+', $scheme);
244-
$this->scheme = $scheme;
245-
$this->schemeProtocol = $schemeParts[0];
223+
$schemeProtocol = $schemeParts[0];
246224

247225
unset($schemeParts[0]);
248-
$this->schemeExtensions = array_values($schemeParts);
226+
$schemeExtensions = array_values($schemeParts);
249227

250-
if ($host = parse_url($dsn, PHP_URL_HOST)) {
251-
$this->host = $host;
252-
}
228+
$user = parse_url($dsn, PHP_URL_USER) ?: null;
229+
$password = parse_url($dsn, PHP_URL_PASS) ?: null;
253230

254-
if ($port = parse_url($dsn, PHP_URL_PORT)) {
255-
$this->port = (int) $port;
231+
$path = parse_url($dsn, PHP_URL_PATH) ?: null;
232+
if ($path) {
233+
$path = rawurldecode($path);
256234
}
257235

258-
if ($user = parse_url($dsn, PHP_URL_USER)) {
259-
$this->user = $user;
236+
$query = [];
237+
$queryString = parse_url($dsn, PHP_URL_QUERY) ?: null;
238+
if (is_string($queryString)) {
239+
$query = self::httpParseQuery($queryString, '&', PHP_QUERY_RFC3986);
260240
}
261-
262-
if ($password = parse_url($dsn, PHP_URL_PASS)) {
263-
$this->password = $password;
241+
$hostsPorts = '';
242+
if (0 === strpos($dsnWithoutScheme, '//')) {
243+
$dsnWithoutScheme = substr($dsnWithoutScheme, 2);
244+
$dsnWithoutUserPassword = explode('@', $dsnWithoutScheme, 2);
245+
$dsnWithoutUserPassword = 2 === count($dsnWithoutUserPassword) ?
246+
$dsnWithoutUserPassword[1] :
247+
$dsnWithoutUserPassword[0]
248+
;
249+
250+
list($hostsPorts) = explode('#', $dsnWithoutUserPassword, 2);
251+
list($hostsPorts) = explode('?', $hostsPorts, 2);
252+
list($hostsPorts) = explode('/', $hostsPorts, 2);
253+
} else {
254+
return [
255+
new self(
256+
$scheme,
257+
$schemeProtocol,
258+
$schemeExtensions,
259+
null,
260+
null,
261+
null,
262+
null,
263+
$path,
264+
$queryString,
265+
$query
266+
),
267+
];
264268
}
265269

266-
if ($path = parse_url($dsn, PHP_URL_PATH)) {
267-
$this->path = rawurldecode($path);
268-
}
270+
$dsns = [];
271+
$hostParts = explode(',', $hostsPorts);
272+
foreach ($hostParts as $key => $hostPart) {
273+
unset($hostParts[$key]);
274+
275+
$parts = explode(':', $hostPart, 2);
276+
$host = $parts[0];
269277

270-
if ($queryString = parse_url($dsn, PHP_URL_QUERY)) {
271-
$this->queryString = $queryString;
278+
$port = null;
279+
if (isset($parts[1])) {
280+
$port = (int) $parts[1];
281+
}
272282

273-
$this->query = $this->httpParseQuery($queryString, '&', PHP_QUERY_RFC3986);
283+
$dsns[] = new self(
284+
$scheme,
285+
$schemeProtocol,
286+
$schemeExtensions,
287+
$user,
288+
$password,
289+
$host,
290+
$port,
291+
$path,
292+
$queryString,
293+
$query
294+
);
274295
}
296+
297+
return $dsns;
275298
}
276299

277300
/**
278301
* based on http://php.net/manual/en/function.parse-str.php#119484 with some slight modifications.
279302
*/
280-
private function httpParseQuery(string $queryString, string $argSeparator = '&', int $decType = PHP_QUERY_RFC1738): array
303+
private static function httpParseQuery(string $queryString, string $argSeparator = '&', int $decType = PHP_QUERY_RFC1738): array
281304
{
282305
$result = [];
283306
$parts = explode($argSeparator, $queryString);

0 commit comments

Comments
 (0)