Completed
Push — master ( 52a6e0...c01d36 )
by Dmitriy
51s queued 49s
created

DatabaseCollector::collectTransactionRollback()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 6
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 10
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Db\Debug;
6
7
use Throwable;
8
use Yiisoft\Yii\Debug\Collector\CollectorTrait;
9
use Yiisoft\Yii\Debug\Collector\SummaryCollectorInterface;
10
11
final class DatabaseCollector implements SummaryCollectorInterface
12
{
13
    use CollectorTrait;
14
15
    private const ACTION_QUERY_START = 'query.start';
16
    private const ACTION_QUERY_END = 'query.end';
17
    private const ACTION_QUERY_ERROR = 'query.error';
18
19
    private const ACTION_TRANSACTION_START = 'transaction.start';
20
    private const ACTION_TRANSACTION_ROLLBACK = 'transaction.rollback';
21
    private const ACTION_TRANSACTION_COMMIT = 'transaction.commit';
22
23
    private const TRANSACTION_STATUS_COMMIT = 'commit';
24
    private const TRANSACTION_STATUS_ROLLBACK = 'rollback';
25
    private const TRANSACTION_STATUS_START = 'start';
26
27
    private const QUERY_STATUS_INITIALIZED = 'initialized';
28
    private const QUERY_STATUS_ERROR = 'error';
29
    private const QUERY_STATUS_SUCCESS = 'success';
30
31
    /**
32
     * @psalm-var array<string, array{
33
     *     rowNumber: int,
34
     *     transactionId: int,
35
     *     sql: string,
36
     *     rawSql: string,
37
     *     params: array,
38
     *     line: string,
39
     *     status: string,
40
     *     actions: array<string, mixed>
41
     *     }>
42
     */
43
    private array $queries = [];
44
    /**
45
     * @psalm-var array<int, array{
46
     *     id: int,
47
     *     position: int,
48
     *     status: string,
49
     *     line: string,
50
     *     level: string|null,
51
     *     actions: array<string, mixed>,
52
     *     exception: Throwable|null,
53
     *     }>
54
     */
55
    private array $transactions = [];
56
57
    private int $position = 0;
58
    private int $currentTransactionId = 0;
59
60
    /**
61
     * @psalm-suppress InvalidPropertyAssignmentValue
62
     */
63
    public function collectQueryStart(
64
        string $id,
65
        string $sql,
66
        string $rawSql,
67
        array $params,
68
        string $line,
69
    ): void {
70
        $this->queries[$id] = [
71
            'position' => $this->position++,
72
            'transactionId' => $this->currentTransactionId,
73
            'sql' => $sql,
74
            'rawSql' => $rawSql,
75
            'params' => $params,
76
            'line' => $line,
77
            'status' => self::QUERY_STATUS_INITIALIZED,
78
            'actions' => [
79
                'action' => self::ACTION_QUERY_START,
80
                'time' => microtime(true),
81
            ],
82
        ];
83
    }
84
85
    /**
86
     * @psalm-suppress InvalidPropertyAssignmentValue
87
     */
88
    public function collectQueryEnd(
89
        string $id,
90
        int $rowsNumber,
91
    ): void {
92
        $this->queries[$id]['rowsNumber'] = $rowsNumber;
93
        $this->queries[$id]['status'] = self::QUERY_STATUS_SUCCESS;
94
        $this->queries[$id]['actions'][] = [
95
            'action' => self::ACTION_QUERY_END,
96
            'time' => microtime(true),
97
        ];
98
    }
99
100
    /**
101
     * @psalm-suppress InvalidPropertyAssignmentValue
102
     */
103
    public function collectQueryError(
104
        string $id,
105
        Throwable $exception,
106
    ): void {
107
        $this->queries[$id]['exception'] = $exception;
108
        $this->queries[$id]['status'] = self::QUERY_STATUS_ERROR;
109
        $this->queries[$id]['actions'][] = [
110
            'action' => self::ACTION_QUERY_ERROR,
111
            'time' => microtime(true),
112
        ];
113
    }
114
115
    /**
116
     * @psalm-suppress InvalidPropertyAssignmentValue
117
     */
118
    public function collectTransactionStart(
119
        ?string $isolationLevel,
120
        string $line,
121
    ): void {
122
        $id = ++$this->currentTransactionId;
123
        $this->transactions[$id] = [
124
            'id' => $id,
125
            'position' => $this->position++,
126
            'status' => self::TRANSACTION_STATUS_START,
127
            'line' => $line,
128
            'level' => $isolationLevel,
129
            'actions' => [
130
                'action' => self::ACTION_TRANSACTION_START,
131
                'time' => microtime(true),
132
            ],
133
        ];
134
    }
135
136
    /**
137
     * @psalm-suppress InvalidPropertyAssignmentValue
138
     */
139
    public function collectTransactionRollback(
140
        string $line,
141
    ): void {
142
        $this->transactions[$this->currentTransactionId]['status'] = self::TRANSACTION_STATUS_ROLLBACK;
143
        $this->transactions[$this->currentTransactionId]['actions'] = [
144
            'action' => self::ACTION_TRANSACTION_ROLLBACK,
145
            'line' => $line,
146
            'time' => microtime(true),
147
        ];
148
        ++$this->currentTransactionId;
149
    }
150
151
    /**
152
     * @psalm-suppress InvalidPropertyAssignmentValue
153
     */
154
    public function collectTransactionCommit(
155
        string $line,
156
    ): void {
157
        $this->transactions[$this->currentTransactionId]['status'] = self::TRANSACTION_STATUS_COMMIT;
158
        $this->transactions[$this->currentTransactionId]['actions'] = [
159
            'action' => self::ACTION_TRANSACTION_COMMIT,
160
            'line' => $line,
161
            'time' => microtime(true),
162
        ];
163
        ++$this->currentTransactionId;
164
    }
165
166
    public function getCollected(): array
167
    {
168
        $queries = array_values($this->queries);
169
        usort($queries, fn (array $a, array $b) => $a['position'] <=> $b['position']);
170
171
        return [
172
            'queries' => $this->queries,
173
            'transactions' => $this->transactions,
174
        ];
175
    }
176
177
    public function getSummary(): array
178
    {
179
        return [
180
            'db' => [
181
                'queries' => [
182
                    'error' => count(
183
                        array_filter($this->queries, fn (array $query) => $query['status'] === self::QUERY_STATUS_ERROR)
184
                    ),
185
                    'total' => count($this->queries),
186
                ],
187
                'transactions' => [
188
                    'error' => count(
189
                        array_filter(
190
                            $this->transactions,
191
                            fn (array $query) => $query['status'] === self::TRANSACTION_STATUS_ROLLBACK
192
                        )
193
                    ),
194
                    'total' => count($this->transactions),
195
                ],
196
            ],
197
        ];
198
    }
199
200
    private function reset(): void
0 ignored issues
show
Unused Code introduced by
The method reset() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
201
    {
202
        $this->queries = [];
203
        $this->transactions = [];
204
        $this->position = 0;
205
        $this->currentTransactionId = 0;
206
    }
207
}
208