PgsqlMutex   A
last analyzed

Complexity

Total Complexity 4

Size/Duplication

Total Lines 53
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 4
eloc 18
dl 0
loc 53
ccs 19
cts 19
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A acquireLock() 0 8 1
A releaseLock() 0 8 1
A __construct() 0 14 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Mutex\Pgsql;
6
7
use InvalidArgumentException;
8
use PDO;
9
use Yiisoft\Mutex\Mutex;
10
11
use function array_values;
12
use function sha1;
13
use function unpack;
14
15
/**
16
 * PgsqlMutex implements mutex "lock" mechanism via PostgreSQL locks.
17
 */
18
final class PgsqlMutex extends Mutex
19
{
20
    private array $lockKeys;
21
    private PDO $connection;
22
23
    /**
24
     * @param string $name Mutex name.
25
     * @param PDO $connection PDO connection instance to use.
26
     */
27 8
    public function __construct(string $name, PDO $connection)
28
    {
29
        // Converts a string into two 16-bit integer keys using the SHA1 hash function.
30 8
        $this->lockKeys = array_values(unpack('n2', sha1($name, true)));
31 8
        $this->connection = $connection;
32
33
        /** @var string $driverName */
34 8
        $driverName = $connection->getAttribute(PDO::ATTR_DRIVER_NAME);
35
36 8
        if ($driverName !== 'pgsql') {
37 1
            throw new InvalidArgumentException("PostgreSQL connection instance should be passed. Got \"$driverName\".");
38
        }
39
40 7
        parent::__construct(self::class, $name);
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     *
46
     * @see https://www.postgresql.org/docs/13/functions-admin.html
47
     */
48 7
    protected function acquireLock(int $timeout = 0): bool
49
    {
50 7
        $statement = $this->connection->prepare('SELECT pg_try_advisory_lock(:key1, :key2)');
51 7
        $statement->bindValue(':key1', $this->lockKeys[0]);
52 7
        $statement->bindValue(':key2', $this->lockKeys[1]);
53 7
        $statement->execute();
54
55 7
        return (bool) $statement->fetchColumn();
56
    }
57
58
    /**
59
     * {@inheritdoc}
60
     *
61
     * @see https://www.postgresql.org/docs/13/functions-admin.html
62
     */
63 7
    protected function releaseLock(): bool
64
    {
65 7
        $statement = $this->connection->prepare('SELECT pg_advisory_unlock(:key1, :key2)');
66 7
        $statement->bindValue(':key1', $this->lockKeys[0]);
67 7
        $statement->bindValue(':key2', $this->lockKeys[1]);
68 7
        $statement->execute();
69
70 7
        return (bool) $statement->fetchColumn();
71
    }
72
}
73