• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

brick / lock / 17475241346

04 Sep 2025 07:59PM UTC coverage: 5.5%. Remained the same
17475241346

push

github

BenMorel
Apply coding standard

11 of 200 relevant lines covered (5.5%)

3.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Driver/AbstractMysqlLockDriver.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Brick\Lock\Driver;
6

7
use Brick\Lock\Database\ConnectionInterface;
8
use Brick\Lock\Database\QueryException;
9
use Brick\Lock\Exception\LockAcquireException;
10
use Brick\Lock\Exception\LockReleaseException;
11
use Brick\Lock\LockDriverInterface;
12
use Override;
13

14
use function sha1;
15
use function sprintf;
16
use function var_export;
17

18
/**
19
 * Base class for MysqlLockDriver and MariadbLockDriver.
20
 */
21
abstract readonly class AbstractMysqlLockDriver implements LockDriverInterface
22
{
23
    public function __construct(
24
        private ConnectionInterface $connection,
25
    ) {
26
    }
×
27

28
    #[Override]
29
    public function acquire(string $lockName): void
30
    {
31
        $lockAcquired = $this->doAcquire($lockName, timeoutSeconds: $this->getInfiniteTimeout());
×
32

33
        if (! $lockAcquired) {
×
34
            throw LockAcquireException::forLockName($lockName, 'Got false from GET_LOCK() with infinite timeout, which should not happen.');
×
35
        }
36
    }
37

38
    #[Override]
39
    public function tryAcquire(string $lockName): bool
40
    {
41
        return $this->doAcquire($lockName, timeoutSeconds: 0);
×
42
    }
43

44
    #[Override]
45
    public function tryAcquireWithTimeout(string $lockName, int $timeoutSeconds): bool
46
    {
47
        return $this->doAcquire($lockName, $timeoutSeconds);
×
48
    }
49

50
    #[Override]
51
    public function release(string $lockName): void
52
    {
53
        $hashedName = $this->hashLockName($lockName);
×
54

55
        try {
56
            $result = $this->connection->querySingleValue('SELECT RELEASE_LOCK(?)', [$hashedName]);
×
57
        } catch (QueryException $e) {
×
58
            throw LockReleaseException::forLockName($lockName, 'Error while calling RELEASE_LOCK()', $e);
×
59
        }
60

61
        if ($result === 1 || $result === '1') {
×
62
            return; // lock was released successfully
×
63
        }
64

65
        if ($result === 0 || $result === '0') {
×
66
            throw LockReleaseException::forLockName($lockName, 'The lock exists, but was not established by this thread.');
×
67
        }
68

69
        if ($result === null) {
×
70
            throw LockReleaseException::forLockName($lockName, 'The lock does not exist.');
×
71
        }
72

73
        throw LockReleaseException::forLockName($lockName, sprintf(
×
74
            'Unexpected result from RELEASE_LOCK(): %s',
×
75
            var_export($result, true),
×
76
        ));
×
77
    }
78

79
    /**
80
     * Returns a value representing an infinite timeout.
81
     */
82
    abstract protected function getInfiniteTimeout(): int;
83

84
    /**
85
     * Returns true if the lock was successfully acquired, or false if non-blocking and the lock is already held by
86
     * another thread.
87
     *
88
     * @throws LockAcquireException
89
     */
90
    private function doAcquire(string $lockName, int $timeoutSeconds): bool
91
    {
92
        $hashedName = $this->hashLockName($lockName);
×
93

94
        try {
95
            $result = $this->connection->querySingleValue('SELECT GET_LOCK(?, ?)', [$hashedName, $timeoutSeconds]);
×
96
        } catch (QueryException $e) {
×
97
            throw LockAcquireException::forLockName($lockName, 'Error while calling GET_LOCK()', $e);
×
98
        }
99

100
        return match ($result) {
×
101
            0, '0' => false,
×
102
            1, '1' => true,
×
103
            null => throw LockAcquireException::forLockName(
×
104
                $lockName,
×
105
                "MySQL's GET_LOCK() returned NULL, which indicates an error such as running out of memory, " .
×
106
                'or the thread was killed with mysqladmin kill.',
×
107
            ),
×
108
            default => throw LockAcquireException::forLockName($lockName, sprintf(
×
109
                'Unexpected result from GET_LOCK(): %s',
×
110
                var_export($result, true),
×
111
            )),
×
112
        };
×
113
    }
114

115
    /**
116
     * Returns a hashed lock name to ensure that we stay within the MySQL lock name length limit of 64 chars.
117
     */
118
    private function hashLockName(string $lockName): string
119
    {
120
        return sha1($lockName);
×
121
    }
122
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc