Passed
Pull Request — master (#19)
by Evgeniy
03:55 queued 01:50
created

MysqlMutex::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
c 0
b 0
f 0
nc 3
nop 3
dl 0
loc 12
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Mutex\Mysql;
6
7
use InvalidArgumentException;
8
use PDO;
9
use Yiisoft\Mutex\Mutex;
10
11
use function sha1;
12
13
/**
14
 * MysqlMutex implements mutex "lock" mechanism via MySQL locks.
15
 */
16
final class MysqlMutex extends Mutex
17
{
18
    private string $lockName;
19
    private PDO $connection;
20
21
    /**
22
     * @param string $name Mutex name.
23
     * @param PDO $connection PDO connection instance to use.
24
     */
25 8
    public function __construct(string $name, PDO $connection)
26
    {
27 8
        $this->lockName = sha1($name);
28 8
        $this->connection = $connection;
29
30
        /** @var string $driverName */
31 8
        $driverName = $connection->getAttribute(PDO::ATTR_DRIVER_NAME);
32
33 8
        if ($driverName !== 'mysql') {
34 1
            throw new InvalidArgumentException("MySQL connection instance should be passed. Got \"$driverName\".");
35
        }
36
37 7
        parent::__construct(self::class, $name);
38 7
    }
39
40
    /**
41
     * {@inheritdoc}
42
     *
43
     * @see https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_get-lock
44
     * @see https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_is-free-lock
45
     */
46 7
    protected function acquireLock(int $timeout = 0): bool
47
    {
48 7
        $statement = $this->connection->prepare('SELECT GET_LOCK(:name, :timeout)');
49 7
        $statement->bindValue(':name', $this->lockName);
50 7
        $statement->bindValue(':timeout', $timeout);
51 7
        $statement->execute();
52
53 7
        return (bool) $statement->fetchColumn();
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     *
59
     * @see https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_release-lock
60
     * @see https://dev.mysql.com/doc/refman/8.0/en/locking-functions.html#function_is-free-lock
61
     */
62 7
    protected function releaseLock(): bool
63
    {
64 7
        $statement = $this->connection->prepare('SELECT RELEASE_LOCK(:name)');
65 7
        $statement->bindValue(':name', $this->lockName);
66 7
        $statement->execute();
67
68 7
        return (bool) $statement->fetchColumn();
69
    }
70
}
71