-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Lock] Add MysqlStore
#45982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 7.4
Are you sure you want to change the base?
[Lock] Add MysqlStore
#45982
Changes from 1 commit
6a18831
f849ecb
2f26e01
6954fc6
4730f91
d28db69
2def8dd
cda417a
827545a
9a32d39
e2f0faa
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
CHANGELOG | ||
========= | ||
6.1 | ||
6.2 | ||
--- | ||
* Add `MysqlStore` based on MySQL `GET_LOCK()` functionality | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,19 +23,25 @@ | |
*/ | ||
class MysqlStore implements PersistingStoreInterface | ||
{ | ||
private \PDO $conn; | ||
private ?\PDO $conn; | ||
|
||
public function __construct(\PDO $conn) | ||
{ | ||
if ('mysql' !== $driver = $conn->getAttribute(\PDO::ATTR_DRIVER_NAME)) { | ||
throw new InvalidArgumentException(sprintf('The adapter "%s" does not support the "%s" driver.', __CLASS__, $driver)); | ||
} | ||
private ?string $dsn; | ||
|
||
private array $options; | ||
|
||
if (\PDO::ERRMODE_EXCEPTION !== $conn->getAttribute(\PDO::ATTR_ERRMODE)) { | ||
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__)); | ||
public function __construct(\PDO|string $connOrDsn, array $options = []) | ||
{ | ||
if ($connOrDsn instanceof \PDO) { | ||
$this->conn = $connOrDsn; | ||
$this->assertMysqlDriver(); | ||
if (\PDO::ERRMODE_EXCEPTION !== $this->conn->getAttribute(\PDO::ATTR_ERRMODE)) { | ||
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__)); | ||
} | ||
} else { | ||
$this->dsn = $connOrDsn; | ||
} | ||
|
||
$this->conn = $conn; | ||
$this->options = $options; | ||
} | ||
|
||
public function save(Key $key): void | ||
|
@@ -44,11 +50,9 @@ public function save(Key $key): void | |
return; | ||
} | ||
|
||
// todo ? check that mysql > 5.7.3 | ||
|
||
// mysql limits lock name length to 64 chars | ||
$name = (string) $key; | ||
$name = \strlen($name) > 64 ? hash('sha256', $name) : $name; | ||
$name = \strlen($name) > 64 ? hash('xxh128', $name) : $name; | ||
|
||
$stmt = $this->conn->prepare('SELECT IF(IS_USED_LOCK(:name) = CONNECTION_ID(), -1, GET_LOCK(:name, 0))'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you elaborate on this requirement? Im concerned that using the
I moved the state into the store since the tests assert that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
$stmt->bindValue(':name', $name, \PDO::PARAM_STR); | ||
|
@@ -103,4 +107,27 @@ public function exists(Key $key): bool | |
|
||
return 1 === $stmt->fetchColumn(); | ||
} | ||
|
||
private function getConnection(): \PDO | ||
{ | ||
if (!$this->conn) { | ||
$this->conn = new \PDO( | ||
$this->dsn, | ||
$this->options['db_username'] ?? null, | ||
$this->options['db_password'] ?? null, | ||
$this->options['db_connection_options'] ?? null | ||
); | ||
$this->conn->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); | ||
$this->assertMysqlDriver(); | ||
} | ||
|
||
return $this->conn; | ||
} | ||
|
||
private function assertMysqlDriver(): void | ||
{ | ||
if ('mysql' !== $driver = $this->conn->getAttribute(\PDO::ATTR_DRIVER_NAME)) { | ||
throw new InvalidArgumentException(sprintf('The adapter "%s" does not support the "%s" driver.', __CLASS__, $driver)); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe rename it to
MysqlLocksStore
to indicate Mysql user locks are used (not to be confused with data storage in Pdo store