Skip to content

Commit c44b7c0

Browse files
committed
[fs] Use enqueue/dsn to parse DSN
1 parent 7ae7fc3 commit c44b7c0

File tree

6 files changed

+76
-41
lines changed

6 files changed

+76
-41
lines changed

docs/transport/filesystem.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ $connectionFactory = new FsConnectionFactory('file:');
3535
$connectionFactory = new FsConnectionFactory('/path/to/queue/dir');
3636

3737
// same as above
38-
$connectionFactory = new FsConnectionFactory('file://path/to/queue/dir');
38+
$connectionFactory = new FsConnectionFactory('file:///path/to/queue/dir');
3939

4040
// with options
41-
$connectionFactory = new FsConnectionFactory('file://path/to/queue/dir?pre_fetch_count=1');
41+
$connectionFactory = new FsConnectionFactory('file:///path/to/queue/dir?pre_fetch_count=1');
4242

4343
// as an array
4444
$connectionFactory = new FsConnectionFactory([

pkg/dsn/Dsn.php

+14
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,20 @@ public function getInt(string $name, int $default = null): ?int
165165
return (int) $value;
166166
}
167167

168+
public function getOctal(string $name, int $default = null): ?int
169+
{
170+
$value = $this->getQueryParameter($name);
171+
if (null === $value) {
172+
return $default;
173+
}
174+
175+
if (false == preg_match('/^[\+\-]?[0-9]*$/', $value)) {
176+
throw InvalidQueryParameterTypeException::create($name, 'integer');
177+
}
178+
179+
return intval($value, 8);
180+
}
181+
168182
public function getFloat(string $name, float $default = null): ?float
169183
{
170184
$value = $this->getQueryParameter($name);

pkg/dsn/Tests/DsnTest.php

+17
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ public function testShouldParseQueryParameterAsInt(string $parameter, int $expec
107107
$this->assertSame($expected, $dsn->getInt('aName'));
108108
}
109109

110+
/**
111+
* @dataProvider provideOctalQueryParameters
112+
*/
113+
public function testShouldParseQueryParameterAsOctalInt(string $parameter, int $expected)
114+
{
115+
$dsn = new Dsn('foo:?aName='.$parameter);
116+
117+
$this->assertSame($expected, $dsn->getOctal('aName'));
118+
}
119+
110120
public function testShouldReturnDefaultIntIfNotSet()
111121
{
112122
$dsn = new Dsn('foo:');
@@ -204,6 +214,13 @@ public static function provideIntQueryParameters()
204214
yield ['+123', 123];
205215

206216
yield ['-123', -123];
217+
218+
yield ['010', 10];
219+
}
220+
221+
public static function provideOctalQueryParameters()
222+
{
223+
yield ['010', 8];
207224
}
208225

209226
public static function provideFloatQueryParameters()

pkg/fs/FsConnectionFactory.php

+28-35
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
namespace Enqueue\Fs;
66

7+
use Enqueue\Dsn\Dsn;
78
use Interop\Queue\ConnectionFactory;
89
use Interop\Queue\Context;
910

@@ -27,23 +28,31 @@ class FsConnectionFactory implements ConnectionFactory
2728
* or
2829
*
2930
* file: - create queue files in tmp dir.
30-
* file://home/foo/enqueue
31-
* file://home/foo/enqueue?pre_fetch_count=20&chmod=0777
31+
* file:///home/foo/enqueue
32+
* file:///home/foo/enqueue?pre_fetch_count=20&chmod=0777
3233
*
3334
* @param array|string|null $config
3435
*/
3536
public function __construct($config = 'file:')
3637
{
3738
if (empty($config) || 'file:' === $config) {
38-
$config = ['path' => sys_get_temp_dir().'/enqueue'];
39+
$config = $this->parseDsn('file://'.sys_get_temp_dir().'/enqueue');
3940
} elseif (is_string($config)) {
40-
$config = $this->parseDsn($config);
41+
if ('/' === $config[0]) {
42+
$config = $this->parseDsn('file://'.$config);
43+
} else {
44+
$config = $this->parseDsn($config);
45+
}
4146
} elseif (is_array($config)) {
4247
} else {
4348
throw new \LogicException('The config must be either an array of options, a DSN string or null');
4449
}
4550

4651
$this->config = array_replace($this->defaultConfig(), $config);
52+
53+
if (empty($this->config['path'])) {
54+
throw new \LogicException('The path option must be set.');
55+
}
4756
}
4857

4958
/**
@@ -61,39 +70,23 @@ public function createContext(): Context
6170

6271
private function parseDsn(string $dsn): array
6372
{
64-
if ($dsn && '/' === $dsn[0]) {
65-
return ['path' => $dsn];
66-
}
67-
68-
if (false === strpos($dsn, 'file:')) {
69-
throw new \LogicException(sprintf('The given DSN "%s" is not supported. Must start with "file:".', $dsn));
70-
}
71-
72-
$dsn = substr($dsn, 7);
73-
74-
$path = parse_url($dsn, PHP_URL_PATH);
75-
$query = parse_url($dsn, PHP_URL_QUERY);
76-
77-
if ('/' != $path[0]) {
78-
throw new \LogicException(sprintf('Failed to parse DSN path "%s". The path must start with "/"', $path));
73+
$dsn = new Dsn($dsn);
74+
75+
$supportedSchemes = ['file'];
76+
if (false == in_array($dsn->getSchemeProtocol(), $supportedSchemes, true)) {
77+
throw new \LogicException(sprintf(
78+
'The given scheme protocol "%s" is not supported. It must be one of "%s"',
79+
$dsn->getSchemeProtocol(),
80+
implode('", "', $supportedSchemes)
81+
));
7982
}
8083

81-
if ($query) {
82-
$config = [];
83-
parse_str($query, $config);
84-
}
85-
86-
if (isset($config['pre_fetch_count'])) {
87-
$config['pre_fetch_count'] = (int) $config['pre_fetch_count'];
88-
}
89-
90-
if (isset($config['chmod'])) {
91-
$config['chmod'] = intval($config['chmod'], 8);
92-
}
93-
94-
$config['path'] = $path;
95-
96-
return $config;
84+
return array_filter(array_replace($dsn->getQuery(), [
85+
'path' => $dsn->getPath(),
86+
'pre_fetch_count' => $dsn->getInt('pre_fetch_count'),
87+
'chmod' => $dsn->getOctal('chmod'),
88+
'polling_interval' => $dsn->getInt('polling_interval'),
89+
]), function ($value) { return null !== $value; });
9790
}
9891

9992
private function defaultConfig(): array

pkg/fs/Tests/FsConnectionFactoryConfigTest.php

+14-4
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,30 @@ public function testThrowNeitherArrayStringNorNullGivenAsConfig()
2121
new FsConnectionFactory(new \stdClass());
2222
}
2323

24-
public function testThrowIfSchemeIsNotAmqp()
24+
public function testThrowIfSchemeIsNotFileScheme()
2525
{
2626
$this->expectException(\LogicException::class);
27-
$this->expectExceptionMessage('The given DSN "http://example.com" is not supported. Must start with "file:');
27+
$this->expectExceptionMessage('The given scheme protocol "http" is not supported. It must be one of "file"');
2828

2929
new FsConnectionFactory('http://example.com');
3030
}
3131

3232
public function testThrowIfDsnCouldNotBeParsed()
3333
{
3434
$this->expectException(\LogicException::class);
35-
$this->expectExceptionMessage('Failed to parse DSN path ":@/". The path must start with "/"');
35+
$this->expectExceptionMessage('The DSN is invalid.');
3636

37-
new FsConnectionFactory('file://:@/');
37+
new FsConnectionFactory('foo');
38+
}
39+
40+
public function testThrowIfArrayConfigGivenWithEmptyPath()
41+
{
42+
$this->expectException(\LogicException::class);
43+
$this->expectExceptionMessage('The path option must be set.');
44+
45+
new FsConnectionFactory([
46+
'path' => null,
47+
]);
3848
}
3949

4050
/**

pkg/fs/composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"require": {
99
"php": "^7.1.3",
1010
"queue-interop/queue-interop": "0.7.x-dev",
11+
"enqueue/dsn": "0.9.x-dev",
1112
"symfony/filesystem": "^3.4|^4",
1213
"makasim/temp-file": "^0.2@stable"
1314
},

0 commit comments

Comments
 (0)