feature #34057 [Lock][Cache] Allows URL DSN in PDO adapters (jderusse)
This PR was merged into the 4.4 branch.
Discussion
----------
[Lock][Cache] Allows URL DSN in PDO adapters
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | -
| License | MIT
| Doc PR | TODO
This PR duplicate a feature from PdoSessionHandler that convert URL DSN ( ie. mysql://localhost/test) into PDO DSN (ie. mysql:host=localhost;dbname=test)
that would ease configuration by using the same well-known variable
```
framework:
lock: '%env(DATABASE_URL)%'
```
note: I applied the same change on Cache component for consistency.
Commits
-------
474daf976e
Allows URL DSN in Lock and Cache
This commit is contained in:
commit
e2c625e78b
@ -71,4 +71,33 @@ class PdoAdapterTest extends AdapterTestCase
|
|||||||
$this->assertFalse($newItem->isHit());
|
$this->assertFalse($newItem->isHit());
|
||||||
$this->assertSame(0, $getCacheItemCount(), 'PDOAdapter must clean up expired items');
|
$this->assertSame(0, $getCacheItemCount(), 'PDOAdapter must clean up expired items');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideDsn
|
||||||
|
*/
|
||||||
|
public function testDsn(string $dsn, string $file = null)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$pool = new PdoAdapter($dsn);
|
||||||
|
$pool->createTable();
|
||||||
|
|
||||||
|
$item = $pool->getItem('key');
|
||||||
|
$item->set('value');
|
||||||
|
$this->assertTrue($pool->save($item));
|
||||||
|
} finally {
|
||||||
|
if (null !== $file) {
|
||||||
|
@unlink($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideDsn()
|
||||||
|
{
|
||||||
|
$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
|
||||||
|
yield ['sqlite://localhost/'.$dbFile, ''.$dbFile];
|
||||||
|
yield ['sqlite:'.$dbFile, ''.$dbFile];
|
||||||
|
yield ['sqlite3:///'.$dbFile, ''.$dbFile];
|
||||||
|
yield ['sqlite://localhost/:memory:'];
|
||||||
|
yield ['sqlite::memory:'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ namespace Symfony\Component\Cache\Traits;
|
|||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
use Doctrine\DBAL\DBALException;
|
use Doctrine\DBAL\DBALException;
|
||||||
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
|
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
|
||||||
|
use Doctrine\DBAL\DriverManager;
|
||||||
use Doctrine\DBAL\Exception\TableNotFoundException;
|
use Doctrine\DBAL\Exception\TableNotFoundException;
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
use Symfony\Component\Cache\Exception\InvalidArgumentException;
|
||||||
@ -370,8 +371,15 @@ trait PdoTrait
|
|||||||
private function getConnection()
|
private function getConnection()
|
||||||
{
|
{
|
||||||
if (null === $this->conn) {
|
if (null === $this->conn) {
|
||||||
$this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions);
|
if (strpos($this->dsn, '://')) {
|
||||||
$this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
if (!class_exists(DriverManager::class)) {
|
||||||
|
throw new InvalidArgumentException(sprintf('Failed to parse the DSN "%s". Try running "composer require doctrine/dbal".', $this->dsn));
|
||||||
|
}
|
||||||
|
$this->conn = DriverManager::getConnection(['url' => $this->dsn]);
|
||||||
|
} else {
|
||||||
|
$this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions);
|
||||||
|
$this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (null === $this->driver) {
|
if (null === $this->driver) {
|
||||||
if ($this->conn instanceof \PDO) {
|
if ($this->conn instanceof \PDO) {
|
||||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\Lock\Store;
|
|||||||
|
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
use Doctrine\DBAL\DBALException;
|
use Doctrine\DBAL\DBALException;
|
||||||
|
use Doctrine\DBAL\DriverManager;
|
||||||
use Doctrine\DBAL\Schema\Schema;
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
use Symfony\Component\Lock\Exception\InvalidArgumentException;
|
use Symfony\Component\Lock\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Lock\Exception\InvalidTtlException;
|
use Symfony\Component\Lock\Exception\InvalidTtlException;
|
||||||
@ -229,8 +230,15 @@ class PdoStore implements StoreInterface
|
|||||||
private function getConnection()
|
private function getConnection()
|
||||||
{
|
{
|
||||||
if (null === $this->conn) {
|
if (null === $this->conn) {
|
||||||
$this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions);
|
if (strpos($this->dsn, '://')) {
|
||||||
$this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
if (!class_exists(DriverManager::class)) {
|
||||||
|
throw new InvalidArgumentException(sprintf('Failed to parse the DSN "%s". Try running "composer require doctrine/dbal".', $this->dsn));
|
||||||
|
}
|
||||||
|
$this->conn = DriverManager::getConnection(['url' => $this->dsn]);
|
||||||
|
} else {
|
||||||
|
$this->conn = new \PDO($this->dsn, $this->username, $this->password, $this->connectionOptions);
|
||||||
|
$this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->conn;
|
return $this->conn;
|
||||||
|
@ -73,4 +73,34 @@ class PdoStoreTest extends AbstractStoreTest
|
|||||||
|
|
||||||
return new PdoStore('sqlite:'.self::$dbFile, [], 0.1, 0.1);
|
return new PdoStore('sqlite:'.self::$dbFile, [], 0.1, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideDsn
|
||||||
|
*/
|
||||||
|
public function testDsn(string $dsn, string $file = null)
|
||||||
|
{
|
||||||
|
$key = new Key(uniqid(__METHOD__, true));
|
||||||
|
|
||||||
|
try {
|
||||||
|
$store = new PdoStore($dsn);
|
||||||
|
$store->createTable();
|
||||||
|
|
||||||
|
$store->save($key);
|
||||||
|
$this->assertTrue($store->exists($key));
|
||||||
|
} finally {
|
||||||
|
if (null !== $file) {
|
||||||
|
@unlink($file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provideDsn()
|
||||||
|
{
|
||||||
|
$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
|
||||||
|
yield ['sqlite://localhost/'.$dbFile, ''.$dbFile];
|
||||||
|
yield ['sqlite:'.$dbFile, ''.$dbFile];
|
||||||
|
yield ['sqlite3:///'.$dbFile, ''.$dbFile];
|
||||||
|
yield ['sqlite://localhost/:memory:'];
|
||||||
|
yield ['sqlite::memory:'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,13 @@
|
|||||||
"psr/log": "~1.0"
|
"psr/log": "~1.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"doctrine/dbal": "~2.4",
|
"doctrine/dbal": "~2.5",
|
||||||
"mongodb/mongodb": "~1.1",
|
"mongodb/mongodb": "~1.1",
|
||||||
"predis/predis": "~1.0"
|
"predis/predis": "~1.0"
|
||||||
},
|
},
|
||||||
|
"conflict": {
|
||||||
|
"doctrine/dbal": "<2.5"
|
||||||
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": { "Symfony\\Component\\Lock\\": "" },
|
"psr-4": { "Symfony\\Component\\Lock\\": "" },
|
||||||
"exclude-from-classmap": [
|
"exclude-from-classmap": [
|
||||||
|
Reference in New Issue
Block a user