Lines 100.00% 9 / 9
Functions and Methods 100.00% 8 / 8
Classes and Traits 100.00% 1 / 1
Name Lines Functions and Methods CRAP Classes and Traits
MySqlConnection 100.00% 9 / 9 100.00% 8 / 8 8 100.00% 1 / 1
 getDefaultQueryGrammar 100.00% 1 / 1 100.00% 1 / 1 1
 getDefaultSchemaGrammar 100.00% 1 / 1 100.00% 1 / 1 1
 getDefaultSchemaInspector 100.00% 1 / 1 100.00% 1 / 1 1
 supportsSavepoints 100.00% 1 / 1 100.00% 1 / 1 1
 createSavepoint 100.00% 1 / 1 100.00% 1 / 1 1
 releaseSavepoint 100.00% 1 / 1 100.00% 1 / 1 1
 rollbackToSavepoint 100.00% 1 / 1 100.00% 1 / 1 1
 withLock 100.00% 2 / 2 100.00% 1 / 1 1
1<?php
2
3declare(strict_types=1);
4
5namespace BlueprintAU\Radiant\Database\Connections;
6
7use BlueprintAU\Radiant\Database\Grammars\Grammar;
8use BlueprintAU\Radiant\Database\Grammars\MySqlGrammar;
9use BlueprintAU\Radiant\Database\Schema\Grammars\MySqlSchemaGrammar;
10use BlueprintAU\Radiant\Database\Schema\Grammars\SchemaGrammar;
11use BlueprintAU\Radiant\Database\Schema\Inspectors\MySqlSchemaInspector;
12use BlueprintAU\Radiant\Database\Schema\Inspectors\SchemaInspector;
13use Override;
14
15/**
16 * A database connection backed by MySQL.
17 *
18 * MySQL supports savepoints, so all four transaction hooks map onto
19 * `SAVEPOINT`, `RELEASE SAVEPOINT` and `ROLLBACK TO SAVEPOINT`. Note that
20 * MySQL follows the ANSI SQL standard here: a same-named savepoint is
21 * silently replaced, so releasing it is a no-op — only creating and rolling
22 * back to one are real SQL statements.
23 *
24 * @see SqlConnection
25 *
26 * @extends SqlConnection<\BlueprintAU\Radiant\Database\Grammars\MySqlGrammar, \BlueprintAU\Radiant\Database\Schema\Grammars\MySqlSchemaGrammar, \BlueprintAU\Radiant\Database\Schema\Inspectors\MySqlSchemaInspector>
27 */
28class MySqlConnection extends SqlConnection
29{
30    /**
31     * The default query grammar for this connection.
32     *
33     * @return Grammar
34     */
35    protected function getDefaultQueryGrammar(): Grammar
36    {
37        return new MySqlGrammar();
38    }
39
40    /**
41     * The default schema grammar for this connection.
42     *
43     * @return SchemaGrammar
44     */
45    protected function getDefaultSchemaGrammar(): SchemaGrammar
46    {
47        return new MySqlSchemaGrammar();
48    }
49
50    /**
51     * The dialect's live-schema reader.
52     *
53     * @return MySqlSchemaInspector
54     */
55    protected function getDefaultSchemaInspector(): SchemaInspector
56    {
57        return new MySqlSchemaInspector($this->pdo);
58    }
59
60    /**
61     * Whether this dialect supports savepoints for nested transactions.
62     *
63     * @return bool
64     */
65    protected function supportsSavepoints(): bool
66    {
67        return true;
68    }
69
70    /**
71     * Create a named savepoint.
72     *
73     * @param  string  $name
74     */
75    protected function createSavepoint(string $name): void
76    {
77        $this->pdo->exec("SAVEPOINT {$name}");
78    }
79
80    /**
81     * Release a named savepoint.
82     *
83     * Deliberately a no-op: MySQL follows the ANSI SQL standard here —
84     * `SAVEPOINT name` silently replaces an existing savepoint of the same
85     * name rather than pushing onto a stack, so there is no savepoint to
86     * release.
87     *
88     * @param  string  $name
89     */
90    protected function releaseSavepoint(string $name): void
91    {
92        // no-op — MySQL replaces same-named savepoints
93    }
94
95    /**
96     * Roll back to a named savepoint.
97     *
98     * @param  string  $name
99     */
100    protected function rollbackToSavepoint(string $name): void
101    {
102        $this->pdo->exec("ROLLBACK TO SAVEPOINT {$name}");
103    }
104
105    /**
106     * Run the callback under MySQL's `GET_LOCK` advisory lock on the given
107     * lock domain.
108     *
109     * @template TReturn
110     *
111     * @param  callable(): TReturn  $callback
112     * @param  string  $name
113     * @return TReturn
114     * @throws \Throwable
115     */
116    #[Override]
117    public function withLock(callable $callback, string $name): mixed
118    {
119        return (new \BlueprintAU\Radiant\Database\Locks\MySqlLock($this))
120            ->withLock($callback, $name);
121    }
122}