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

mpyw / laravel-database-advisory-lock / 20213075082

14 Dec 2025 07:33PM UTC coverage: 95.732% (-4.3%) from 100.0%
20213075082

Pull #14

github

mpyw
Exclude bootstrap files from PHPStan analysis

Bootstrap files contain trait stubs for testing that PHPStan
incorrectly reports as unused.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pull Request #14: [Claude] Add PHP 8.5 to CI test matrix

157 of 164 relevant lines covered (95.73%)

126.84 hits per line

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

96.0
/src/MySqlSessionLocker.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Mpyw\LaravelDatabaseAdvisoryLock;
6

7
use Illuminate\Database\MySqlConnection;
8
use Mpyw\LaravelDatabaseAdvisoryLock\Concerns\SessionLocks;
9
use Mpyw\LaravelDatabaseAdvisoryLock\Contracts\LockFailedException;
10
use Mpyw\LaravelDatabaseAdvisoryLock\Contracts\SessionLock;
11
use Mpyw\LaravelDatabaseAdvisoryLock\Contracts\SessionLocker;
12
use Mpyw\LaravelDatabaseAdvisoryLock\Contracts\UnsupportedTimeoutPrecisionException;
13
use Mpyw\LaravelDatabaseAdvisoryLock\Utilities\Selector;
14
use WeakMap;
15

16
use function array_fill;
17
use function is_float;
18
use function sprintf;
19

20
final class MySqlSessionLocker implements SessionLocker
21
{
22
    use SessionLocks;
23

24
    /**
25
     * @var WeakMap<SessionLock, bool>
26
     */
27
    private WeakMap $locks;
28

29
    public function __construct(
30
        private MySqlConnection $connection,
31
    ) {
32
        $this->locks = new WeakMap();
231✔
33
    }
34

35
    public function lockOrFail(string $key, float|int $timeout = 0): SessionLock
36
    {
37
        if (is_float($timeout)) {
231✔
38
            throw new UnsupportedTimeoutPrecisionException(sprintf(
22✔
39
                'Float timeout value is not allowed for MySQL/MariaDB: key=%s, timeout=%s',
22✔
40
                $key,
22✔
41
                $timeout,
22✔
42
            ));
22✔
43
        }
44

45
        // When key strings exceed 64 chars limit,
46
        // it takes first 24 chars from them and appends 40 chars `sha1()` hashes.
47
        $sql = "SELECT GET_LOCK(CASE WHEN CHAR_LENGTH(?) > 64 THEN CONCAT(SUBSTR(?, 1, 24), SHA1(?)) ELSE ? END, {$timeout})";
209✔
48
        $bindings = array_fill(0, 4, $key);
209✔
49

50
        $result = (bool)(new Selector($this->connection))
209✔
51
            ->select($sql, $bindings);
209✔
52

53
        if (!$result) {
209✔
54
            throw new LockFailedException(
66✔
55
                (string)$this->connection->getName(),
66✔
56
                "Failed to acquire lock: {$key}",
66✔
57
                $sql,
66✔
58
                $bindings,
66✔
59
            );
66✔
60
        }
61

62
        // Register the lock when it succeeds.
63
        $lock = new MySqlSessionLock($this->connection, $this->locks, $key);
187✔
64
        $this->locks[$lock] = true;
187✔
65

66
        return $lock;
187✔
67
    }
68

69
    public function withLocking(string $key, callable $callback, float|int $timeout = 0): mixed
70
    {
71
        $lock = $this->lockOrFail($key, $timeout);
132✔
72

73
        try {
74
            return $callback($this->connection);
132✔
75
        } finally {
76
            $lock->release();
132✔
77
        }
78
    }
79

80
    public function hasAny(): bool
81
    {
82
        return $this->locks->count() > 0;
×
83
    }
84
}
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