Skip to content

Commit 6954fc6

Browse files
committed
Add dsn support
1 parent 2f26e01 commit 6954fc6

File tree

3 files changed

+56
-14
lines changed

3 files changed

+56
-14
lines changed

src/Symfony/Component/Lock/CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CHANGELOG
22
=========
3-
6.1
3+
6.2
44
---
55
* Add `MysqlStore` based on MySQL `GET_LOCK()` functionality
66

src/Symfony/Component/Lock/Store/MysqlStore.php

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,25 @@
2323
*/
2424
class MysqlStore implements PersistingStoreInterface
2525
{
26-
private \PDO $conn;
26+
private ?\PDO $conn;
2727

28-
public function __construct(\PDO $conn)
29-
{
30-
if ('mysql' !== $driver = $conn->getAttribute(\PDO::ATTR_DRIVER_NAME)) {
31-
throw new InvalidArgumentException(sprintf('The adapter "%s" does not support the "%s" driver.', __CLASS__, $driver));
32-
}
28+
private ?string $dsn;
29+
30+
private array $options;
3331

34-
if (\PDO::ERRMODE_EXCEPTION !== $conn->getAttribute(\PDO::ATTR_ERRMODE)) {
35-
throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __METHOD__));
32+
public function __construct(\PDO|string $connOrDsn, array $options = [])
33+
{
34+
if ($connOrDsn instanceof \PDO) {
35+
$this->conn = $connOrDsn;
36+
$this->assertMysqlDriver();
37+
if (\PDO::ERRMODE_EXCEPTION !== $this->conn->getAttribute(\PDO::ATTR_ERRMODE)) {
38+
throw new InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __METHOD__));
39+
}
40+
} else {
41+
$this->dsn = $connOrDsn;
3642
}
3743

38-
$this->conn = $conn;
44+
$this->options = $options;
3945
}
4046

4147
public function save(Key $key): void
@@ -44,11 +50,9 @@ public function save(Key $key): void
4450
return;
4551
}
4652

47-
// todo ? check that mysql > 5.7.3
48-
4953
// mysql limits lock name length to 64 chars
5054
$name = (string) $key;
51-
$name = \strlen($name) > 64 ? hash('sha256', $name) : $name;
55+
$name = \strlen($name) > 64 ? hash('xxh128', $name) : $name;
5256

5357
$stmt = $this->conn->prepare('SELECT IF(IS_USED_LOCK(:name) = CONNECTION_ID(), -1, GET_LOCK(:name, 0))');
5458
$stmt->bindValue(':name', $name, \PDO::PARAM_STR);
@@ -103,4 +107,27 @@ public function exists(Key $key): bool
103107

104108
return 1 === $stmt->fetchColumn();
105109
}
110+
111+
private function getConnection(): \PDO
112+
{
113+
if (!$this->conn) {
114+
$this->conn = new \PDO(
115+
$this->dsn,
116+
$this->options['db_username'] ?? null,
117+
$this->options['db_password'] ?? null,
118+
$this->options['db_connection_options'] ?? null
119+
);
120+
$this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
121+
$this->assertMysqlDriver();
122+
}
123+
124+
return $this->conn;
125+
}
126+
127+
private function assertMysqlDriver(): void
128+
{
129+
if ('mysql' !== $driver = $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME)) {
130+
throw new InvalidArgumentException(sprintf('The adapter "%s" does not support the "%s" driver.', __CLASS__, $driver));
131+
}
132+
}
106133
}

src/Symfony/Component/Lock/Tests/Store/MysqlStoreTest.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
class MysqlStoreTest extends AbstractStoreTest
1212
{
13-
protected function getPdo(): \PDO
13+
protected function getEnv(): array
1414
{
1515
if (!$host = getenv('MYSQL_HOST')) {
1616
$this->markTestSkipped('Missing MYSQL_HOST env variable');
@@ -24,6 +24,13 @@ protected function getPdo(): \PDO
2424
$this->markTestSkipped('Missing MYSQL_PASSWORD env variable');
2525
}
2626

27+
return [$host, $user, $pass];
28+
}
29+
30+
protected function getPdo(): \PDO
31+
{
32+
[$host, $user, $pass] = $this->getEnv();
33+
2734
return new \PDO('mysql:host='.$host, $user, $pass);
2835
}
2936

@@ -73,4 +80,12 @@ public function testOtherConflictException()
7380
$this->assertStringContainsString('acquired by other', $e->getMessage());
7481
}
7582
}
83+
84+
public function testDsnConstructor()
85+
{
86+
$this->expectNotToPerformAssertions();
87+
88+
[$host, $user, $pass] = $this->getEnv();
89+
new MysqlStore("mysql:$host", ['db_username' => $user, 'db_password' => $pass]);
90+
}
7691
}

0 commit comments

Comments
 (0)