Skip to content

Commit 3c65a54

Browse files
authored
Merge pull request #510 from php-enqueue/symfony-default-factory-resolve-dsn-in-runtime
[Symfony] default factory should resolve DSN in runtime
2 parents 0ae852b + 78d6994 commit 3c65a54

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1774
-628
lines changed

bin/test.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
set -x
44
set -e
55

6-
docker-compose run --workdir="/mqdev" --rm dev ./docker/bin/test.sh "$@"
6+
docker-compose run --workdir="/mqdev" --rm dev ./docker/bin/test.sh $@

composer.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"require-dev": {
3434
"phpunit/phpunit": "^5.5",
3535
"phpstan/phpstan": "^0.10",
36-
"queue-interop/queue-spec": "^0.5.5@dev",
36+
"queue-interop/queue-spec": "^0.5.9@dev",
3737
"symfony/browser-kit": "4.0.*",
3838
"symfony/config": "4.0.*",
3939
"symfony/process": "4.0.*",
@@ -73,13 +73,11 @@
7373
"Enqueue\\Sqs\\": "pkg/sqs/",
7474
"Enqueue\\Stomp\\": "pkg/stomp/",
7575
"Enqueue\\Test\\": "pkg/test/",
76+
"Enqueue\\Dsn\\": "pkg/dsn/",
7677
"Enqueue\\": "pkg/enqueue/"
7778
},
7879
"exclude-from-classmap": [
7980
"/Tests/"
80-
],
81-
"files": [
82-
"pkg/enqueue/functions_include.php"
8381
]
8482
},
8583
"autoload-dev": {

docs/transport/amqp.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ $factory = new AmqpConnectionFactory([
6363

6464
$psrContext = $factory->createContext();
6565

66-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
67-
$psrContext = \Enqueue\dsn_to_context('amqp:');
68-
$psrContext = \Enqueue\dsn_to_context('amqp+ext:');
66+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
67+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('amqp:')->createContext();
68+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('amqp+ext:')->createContext();
6969
```
7070

7171
## Declare topic.

docs/transport/amqp_bunny.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ $factory = new AmqpConnectionFactory('amqp://user:pass@example.com:10000/%2f');
5353

5454
$psrContext = $factory->createContext();
5555

56-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
57-
$psrContext = \Enqueue\dsn_to_context('amqp:');
58-
$psrContext = \Enqueue\dsn_to_context('amqp+bunny:');
56+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
57+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('amqp:')->createContext();
58+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('amqp+bunny:')->createContext();
5959
```
6060

6161
## Declare topic.

docs/transport/amqp_lib.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,9 @@ $factory = new AmqpConnectionFactory([
6161

6262
$psrContext = $factory->createContext();
6363

64-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
65-
$psrContext = \Enqueue\dsn_to_context('amqp:');
66-
$psrContext = \Enqueue\dsn_to_context('amqp+lib:');
64+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
65+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('amqp:')->createContext();
66+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('amqp+lib:')->createContext();
6767
```
6868

6969
## Declare topic.

docs/transport/dbal.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ $factory = new ManagerRegistryConnectionFactory($registry, [
4949

5050
$psrContext = $factory->createContext();
5151

52-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
53-
$psrContext = \Enqueue\dsn_to_context('mysql:');
52+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
53+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('mysql:')->createContext();
5454
```
5555

5656
## Init database

docs/transport/filesystem.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ $connectionFactory = new FsConnectionFactory([
4848

4949
$psrContext = $connectionFactory->createContext();
5050

51-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
52-
$psrContext = \Enqueue\dsn_to_context('file:');
51+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
52+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('file:')->createContext();
5353
```
5454

5555
## Send message to topic

docs/transport/gearman.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ $factory = new GearmanConnectionFactory([
3939

4040
$psrContext = $factory->createContext();
4141

42-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
43-
$psrContext = \Enqueue\dsn_to_context('gearman:');
42+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
43+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('gearman:')->createContext();
4444
```
4545

4646
## Send message to topic

docs/transport/gps.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ $connectionFactory = new GpsConnectionFactory('gps:');
3232

3333
$psrContext = $connectionFactory->createContext();
3434

35-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
36-
$psrContext = \Enqueue\dsn_to_context('gps:');
35+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
36+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('gps:')->createContext();
3737
```
3838

3939
## Send message to topic

docs/transport/kafka.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ $connectionFactory = new RdKafkaConnectionFactory([
4545

4646
$psrContext = $connectionFactory->createContext();
4747

48-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
49-
$psrContext = \Enqueue\dsn_to_context('kafka:');
48+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
49+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('kafka:')->createContext();
5050
```
5151

5252
## Send message to topic

docs/transport/mongodb.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ $factory = new MongodbConnectionFactory([
4141

4242
$psrContext = $factory->createContext();
4343

44-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
45-
$psrContext = \Enqueue\dsn_to_context('mongodb:');
44+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
45+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('mongodb:')->createContext();
4646
```
4747

4848
## Send message to topic

docs/transport/pheanstalk.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ $factory = new PheanstalkConnectionFactory([
3939

4040
$psrContext = $factory->createContext();
4141

42-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
43-
$psrContext = \Enqueue\dsn_to_context('beanstalk:');
42+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
43+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('beanstalk:')->createContext();
4444
```
4545

4646
## Send message to topic

docs/transport/redis.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ $factory = new RedisConnectionFactory('redis://example.com:1000?vendor=phpredis'
6060

6161
$psrContext = $factory->createContext();
6262

63-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
64-
$psrContext = \Enqueue\dsn_to_context('redis:');
63+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
64+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('redis:')->createContext();
6565

6666
// pass redis instance directly
6767
$redis = new \Enqueue\Redis\PhpRedis([ /** redis connection options */ ]);

docs/transport/sqs.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ $psrContext = $factory->createContext();
3838
$client = new Aws\Sqs\SqsClient([ /* ... */ ]);
3939
$factory = new SqsConnectionFactory($client);
4040

41-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
42-
$psrContext = \Enqueue\dsn_to_context('sqs:');
41+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
42+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('sqs:')->createContext();
4343
```
4444

4545
## Declare queue.

docs/transport/stomp.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ $factory = new StompConnectionFactory('stomp://example.com:1000?login=theLogin')
3939

4040
$psrContext = $factory->createContext();
4141

42-
// if you have enqueue/enqueue library installed you can use a function from there to create the context
43-
$psrContext = \Enqueue\dsn_to_context('stomp:');
42+
// if you have enqueue/enqueue library installed you can use a factory to build context from DSN
43+
$psrContext = (new \Enqueue\ConnectionFactoryFactory())->create('stomp:')->createContext();
4444
```
4545

4646
## Send message to topic

phpunit.xml.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,10 @@
100100
<testsuite name="async-command">
101101
<directory>pkg/async-command/Tests</directory>
102102
</testsuite>
103+
104+
<testsuite name="dsn">
105+
<directory>pkg/dsn/Tests</directory>
106+
</testsuite>
103107
</testsuites>
104108

105109
<php>

pkg/dbal/DbalConnectionFactory.php

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -92,51 +92,55 @@ private function establishConnection()
9292
return $this->connection;
9393
}
9494

95-
/**
96-
* @param string $dsn
97-
*
98-
* @return array
99-
*/
100-
private function parseDsn($dsn)
95+
private function parseDsn(string $dsn): array
10196
{
97+
if (false === strpos($dsn, ':')) {
98+
throw new \LogicException(sprintf('The DSN is invalid. It does not have scheme separator ":".'));
99+
}
100+
102101
if (false === parse_url($dsn)) {
103102
throw new \LogicException(sprintf('Failed to parse DSN "%s"', $dsn));
104103
}
105104

106-
if (!preg_match('/^([0-9a-z_]+):(.+)?$/', $dsn, $matches)) {
107-
throw new \LogicException('Schema is empty');
105+
list($scheme) = explode(':', $dsn, 2);
106+
107+
$scheme = strtolower($scheme);
108+
if (false == preg_match('/^[a-z\d+-.]*$/', $scheme)) {
109+
throw new \LogicException('The DSN is invalid. Scheme contains illegal symbols.');
108110
}
109-
$schema = $matches[1];
110111

111112
$supported = [
112-
'db2' => true,
113-
'ibm_db2' => true,
114-
'mssql' => true,
115-
'pdo_sqlsrv' => true,
116-
'mysql' => true,
117-
'mysql2' => true,
118-
'pdo_mysql' => true,
119-
'pgsql' => true,
120-
'postgres' => true,
121-
'postgresql' => true,
122-
'pdo_pgsql' => true,
123-
'sqlite' => true,
124-
'sqlite3' => true,
125-
'pdo_sqlite' => true,
113+
'db2' => 'db2',
114+
'ibm-db2' => 'ibm-db2',
115+
'mssql' => 'mssql',
116+
'sqlsrv+pdo' => 'pdo_sqlsrv',
117+
'mysql' => 'mysql',
118+
'mysql2' => 'mysql2',
119+
'mysql+pdo' => 'pdo_mysql',
120+
'pgsql' => 'pgsql',
121+
'postgres' => 'postgres',
122+
'pgsql+pdo' => 'pdo_pgsql',
123+
'sqlite' => 'sqlite',
124+
'sqlite3' => 'sqlite3',
125+
'sqlite+pdo' => 'pdo_sqlite',
126126
];
127127

128-
if (false == isset($supported[$schema])) {
128+
if (false == isset($supported[$scheme])) {
129129
throw new \LogicException(sprintf(
130130
'The given DSN schema "%s" is not supported. There are supported schemes: "%s".',
131-
$schema,
131+
$scheme,
132132
implode('", "', array_keys($supported))
133133
));
134134
}
135135

136+
$doctrineScheme = $supported[$scheme];
137+
136138
return [
137139
'lazy' => true,
138140
'connection' => [
139-
'url' => $schema.':' === $dsn ? $schema.'://root@localhost' : $dsn,
141+
'url' => $scheme.':' === $dsn ?
142+
$doctrineScheme.'://root@localhost' :
143+
str_replace($scheme, $doctrineScheme, $dsn),
140144
],
141145
];
142146
}

pkg/dbal/Tests/DbalConnectionFactoryConfigTest.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ public function testThrowNeitherArrayStringNorNullGivenAsConfig()
2424
public function testThrowIfSchemeIsNotSupported()
2525
{
2626
$this->expectException(\LogicException::class);
27-
$this->expectExceptionMessage('The given DSN schema "http" is not supported. There are supported schemes: "db2", "ibm_db2", "mssql", "pdo_sqlsrv", "mysql", "mysql2", "pdo_mysql", "pgsql", "postgres", "postgresql", "pdo_pgsql", "sqlite", "sqlite3", "pdo_sqlite"');
27+
$this->expectExceptionMessage('The given DSN schema "http" is not supported. There are supported schemes: "db2", "ibm-db2", "mssql", "sqlsrv+pdo", "mysql", "mysql2", "mysql+pdo", "pgsql", "postgres", "pgsql+pdo", "sqlite", "sqlite3", "sqlite+pdo".');
2828

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

3232
public function testThrowIfDsnCouldNotBeParsed()
3333
{
3434
$this->expectException(\LogicException::class);
35-
$this->expectExceptionMessage('Schema is empty');
35+
$this->expectExceptionMessage('The DSN is invalid. It does not have scheme separator ":".');
3636

3737
new DbalConnectionFactory('invalidDSN');
3838
}
@@ -78,7 +78,7 @@ public static function provideConfigs()
7878
];
7979

8080
yield [
81-
'pdo_mysql:',
81+
'mysql+pdo:',
8282
[
8383
'connection' => [
8484
'url' => 'pdo_mysql://root@localhost',
@@ -114,7 +114,7 @@ public static function provideConfigs()
114114
];
115115

116116
yield [
117-
'pdo_mysql://user:pass@host:10001/db',
117+
'mysql+pdo://user:pass@host:10001/db',
118118
[
119119
'connection' => [
120120
'url' => 'pdo_mysql://user:pass@host:10001/db',

pkg/dsn/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*~
2+
/composer.lock
3+
/composer.phar
4+
/phpunit.xml
5+
/vendor/
6+
/.idea/

pkg/dsn/.travis.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
sudo: false
2+
3+
git:
4+
depth: 10
5+
6+
language: php
7+
8+
php:
9+
- '7.1'
10+
- '7.2'
11+
12+
cache:
13+
directories:
14+
- $HOME/.composer/cache
15+
16+
install:
17+
- composer self-update
18+
- composer install --prefer-source
19+
20+
script:
21+
- vendor/bin/phpunit

0 commit comments

Comments
 (0)