Lines 100.00% 4 / 4
Methods 100.00% 2 / 2
Classes 100.00% 1 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 lockStatement n/a 0 / 0 n/a 0 / 0 0
 unlockStatement n/a 0 / 0 n/a 0 / 0 0
 withLock 100.00% 3 / 3 100.00% 1 / 1 1
18abstract class SqlLock implements Lock
19{
20    /**
21     * @param  SqlConnection  $connection
22     */
23    public function __construct(protected readonly SqlConnection $connection) {}
24
25    /**
26     * The SQL that acquires the dialect's lock.
27     *
28     * The lock name never appears in this SQL — it is bound as a parameter
29     * by {@see withLock()}.
30     *
31     * @return string
32     */
33    abstract protected function lockStatement(): string;
34
35    /**
36     * The SQL that releases the dialect's lock.
37     *
38     * @return string
39     */
40    abstract protected function unlockStatement(): string;
41
42    /**
43     * Run the callback while holding the named session-level lock.
44     *
45     * @template TReturn
46     *
47     * @param  callable(): TReturn  $callback
48     * @param  string  $name
49     * @return TReturn
50     * @throws \Throwable
51     */
52    #[\Override]
53    final public function withLock(callable $callback, string $name): mixed
54    {
55        // The lock statement runs with the name bound (no interpolation); a
56        // failure to acquire must surface as an exception, not a silent
57        // no-lock run.
58        $this->connection->statement($this->lockStatement(), [$name]);
59        try {
60            return $callback();
61        } finally {
62            $this->connection->statement($this->unlockStatement(), [$name]);
63        }
64    }
65}