Skip to content

Commit ce1e50e

Browse files
committed
refactor: refactorisation du collector
1 parent d6de95f commit ce1e50e

File tree

2 files changed

+164
-70
lines changed

2 files changed

+164
-70
lines changed

src/Collectors/DatabaseCollector.php

Lines changed: 136 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
use BlitzPHP\Database\Connection\BaseConnection;
1616
use BlitzPHP\Database\ConnectionResolver;
1717
use BlitzPHP\Debug\Toolbar\Collectors\BaseCollector;
18+
use BlitzPHP\Utilities\Date;
19+
use BlitzPHP\Utilities\String\Text;
1820

1921
/**
2022
* Collecteur pour l'onglet Base de données de la barre d'outils de débogage.
@@ -41,7 +43,7 @@ class DatabaseCollector extends BaseCollector
4143
/**
4244
* {@inheritDoc}
4345
*/
44-
protected string $title = 'Database';
46+
protected string $title = 'Base de donées';
4547

4648
/**
4749
* Tableau de connexions à la base de données.
@@ -52,8 +54,6 @@ class DatabaseCollector extends BaseCollector
5254

5355
/**
5456
* Les instances de requête qui ont été collectées via l'événement DBQuery.
55-
*
56-
* @var stdClass[]
5757
*/
5858
protected static array $queries = [];
5959

@@ -74,13 +74,24 @@ public static function collect(EventInterface $event)
7474
* @var \BlitzPHP\Database\Result\BaseResult
7575
*/
7676
$result = $event->getTarget();
77-
$config = (object) config('toolbar');
7877

79-
// Fournit la valeur par défaut au cas où elle n'est pas définie
80-
$max = $config->max_queries ?: 100;
78+
if (count(static::$queries) < config('toolbar.max_queries', 100)) {
79+
$query = (object) $result->details();
80+
81+
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
82+
83+
if (! is_cli()) {
84+
// lorsqu'ils sont appelés dans le navigateur, les deux premiers tableaux de traces
85+
// proviennent du déclencheur d'événement de la base de données, qui ne sont pas nécessaires
86+
$backtrace = array_slice($backtrace, 2);
87+
}
8188

82-
if (count(static::$queries) < $max) {
83-
static::$queries[] = (object) $result->details();
89+
static::$queries[] = [
90+
'query' => $query,
91+
'string' => $query->sql,
92+
'duplicate' => in_array($query->sql, array_column(static::$queries, 'string', null), true),
93+
'trace' => $backtrace,
94+
];
8495
}
8596
}
8697

@@ -93,20 +104,20 @@ protected function formatTimelineData(): array
93104

94105
foreach ($this->connections as $alias => $connection) {
95106
$data[] = [
96-
'name' => 'Connecting to Database: "' . $connection->getDatabase() . '". Config: "' . $alias . '"',
97-
'component' => 'Database',
107+
'name' => 'Connexion à la base de données: "' . $connection->getDatabase() . '". Config: "' . $alias . '"',
108+
'component' => 'Base de données',
98109
'start' => $connection->getConnectStart(),
99110
'duration' => $connection->getConnectDuration(),
100111
];
101112
}
102113

103114
foreach (static::$queries as $query) {
104115
$data[] = [
105-
'name' => 'Query',
106-
'component' => 'Database',
107-
'query' => $query->sql,
108-
'start' => $query->start,
109-
'duration' => $query->duration,
116+
'name' => 'Requête',
117+
'component' => 'Base de données',
118+
'query' => $query['query']->sql,
119+
'start' => $query['query']->start,
120+
'duration' => $query['query']->duration,
110121
];
111122
}
112123

@@ -118,64 +129,57 @@ protected function formatTimelineData(): array
118129
*/
119130
public function display(): array
120131
{
121-
// Mots clés que nous voulons mettre en gras
122-
$highlight = [
123-
'SELECT',
124-
'DISTINCT',
125-
'FROM',
126-
'WHERE',
127-
'AND',
128-
'INNER JOIN',
129-
'LEFT JOIN',
130-
'RIGHT JOIN',
131-
'JOIN',
132-
'ORDER BY',
133-
'ASC',
134-
'DESC',
135-
'GROUP BY',
136-
'LIMIT',
137-
'INSERT',
138-
'INTO',
139-
'VALUES',
140-
'UPDATE',
141-
'OR ',
142-
'HAVING',
143-
'OFFSET',
144-
'NOT IN',
145-
'IN',
146-
'NOT LIKE',
147-
'LIKE',
148-
'COUNT',
149-
'MAX',
150-
'MIN',
151-
'ON',
152-
'AS',
153-
'As',
154-
'AVG',
155-
'SUM',
156-
'UPPER',
157-
'LOWER',
158-
'(',
159-
')',
160-
];
132+
$data = [];
133+
$data['view'] = __NAMESPACE__ . '\Views\database.tpl';
134+
$data['queries'] = array_map(function (array $query): array {
135+
$isDuplicate = $query['duplicate'] === true;
161136

162-
$data = [
163-
'queries' => [],
164-
];
137+
$firstNonSystemLine = '';
165138

166-
foreach (static::$queries as $query) {
167-
$sql = $query->sql;
139+
foreach ($query['trace'] as $index => &$line) {
140+
// simplifier le fichier et la ligne
141+
if (isset($line['file'])) {
142+
$line['file'] = clean_path($line['file']) . ':' . $line['line'];
143+
unset($line['line']);
144+
} else {
145+
$line['file'] = '[internal function]';
146+
}
147+
148+
// trouver la première ligne de trace qui ne provient pas du systeme
149+
if ($firstNonSystemLine === '' && ! Text::contains($line['file'], ['SYST_PATH', 'BLITZ_PATH'])) {
150+
$firstNonSystemLine = $line['file'];
151+
}
152+
153+
// simplifier l'appel de fonction
154+
if (isset($line['class'])) {
155+
$line['function'] = $line['class'] . $line['type'] . $line['function'];
156+
unset($line['class'], $line['type']);
157+
}
158+
159+
if (strrpos($line['function'], '{closure}') === false) {
160+
$line['function'] .= '()';
161+
}
162+
163+
$line['function'] = str_repeat(chr(0xC2) . chr(0xA0), 8) . $line['function'];
168164

169-
foreach ($highlight as $term) {
170-
$sql = str_replace($term, "<strong>{$term}</strong>", $sql);
165+
// ajouter une numérotation d'index complétée par un espace insécable
166+
$indexPadded = str_pad(sprintf('%d', $index + 1), 3, ' ', STR_PAD_LEFT);
167+
$indexPadded = preg_replace('/\s/', chr(0xC2) . chr(0xA0), $indexPadded);
168+
169+
$line['index'] = $indexPadded . str_repeat(chr(0xC2) . chr(0xA0), 4);
171170
}
172171

173-
$data['queries'][] = [
174-
'duration' => (number_format($query->duration, 5) * 1000) . ' ms',
175-
'sql' => $sql,
176-
'affected_rows' => $query->affected_rows,
172+
return [
173+
'hover' => $isDuplicate ? 'Cette requête a été appelée plus d\'une fois.' : '',
174+
'class' => $isDuplicate ? 'duplicate' : '',
175+
'duration' => (number_format($query['query']->duration, 5) * 1000) . ' ms',
176+
'sql' => $this->highlight($query['query']->sql),
177+
'affected_rows' => $query['query']->affected_rows,
178+
'trace' => $query['trace'],
179+
'trace-file' => $firstNonSystemLine,
180+
'qid' => md5($query['query']->sql . Date::now()->format('0.u00 U')),
177181
];
178-
}
182+
}, static::$queries);
179183

180184
return $data;
181185
}
@@ -195,16 +199,29 @@ public function getBadgeValue(): int
195199
*/
196200
public function getTitleDetails(): string
197201
{
198-
return '(' . count(static::$queries) . ' Queries across ' . ($countConnection = count($this->connections)) . ' Connection' .
199-
($countConnection > 1 ? 's' : '') . ')';
202+
$this->getConnections();
203+
204+
$queryCount = count(static::$queries);
205+
$uniqueCount = count(array_filter(static::$queries, static fn ($query): bool => $query['duplicate'] === false));
206+
$connectionCount = count($this->connections);
207+
208+
return sprintf(
209+
'(%d requête%s au total, %s %d unique sur %d connexion%s)',
210+
$queryCount,
211+
$queryCount > 1 ? 's' : '',
212+
$uniqueCount > 1 ? 'dont' : '',
213+
$uniqueCount,
214+
$connectionCount,
215+
$connectionCount > 1 ? 's' : '',
216+
);
200217
}
201218

202219
/**
203220
* {@inheritDoc}
204221
*/
205222
public function isEmpty(): bool
206223
{
207-
return empty(static::$queries);
224+
return static::$queries === [];
208225
}
209226

210227
/**
@@ -222,4 +239,53 @@ private function getConnections()
222239
{
223240
$this->connections = ConnectionResolver::getConnections();
224241
}
242+
243+
private function highlight(string $statement): string
244+
{
245+
// Liste des mots-clés à mettre en gras
246+
$replacements = array_map(fn($term) => "<strong>{$term}</strong>", $search = [
247+
'SELECT',
248+
'DISTINCT',
249+
'FROM',
250+
'WHERE',
251+
'AND',
252+
'INNER JOIN',
253+
'LEFT JOIN',
254+
'NATURAL JOIN',
255+
'RIGHT JOIN',
256+
'JOIN',
257+
'ORDER BY',
258+
'ASC',
259+
'DESC',
260+
'GROUP BY',
261+
'LIMIT',
262+
'INSERT',
263+
'INTO',
264+
'VALUES',
265+
'UPDATE',
266+
'OR ',
267+
'HAVING',
268+
'OFFSET',
269+
'NOT IN',
270+
'IN',
271+
'IS NOT NULL',
272+
'IS NULL',
273+
'NOT LIKE',
274+
'LIKE',
275+
'COUNT',
276+
'MAX',
277+
'MIN',
278+
'ON',
279+
'AS',
280+
'As',
281+
'AVG',
282+
'SUM',
283+
'UPPER',
284+
'LOWER',
285+
'(',
286+
')',
287+
]);
288+
289+
return strtr($statement, array_combine($search, $replacements));
290+
}
225291
}

src/Collectors/Views/database.tpl

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<table>
2+
<thead>
3+
<tr>
4+
<th class="debug-bar-width6r">Durée</th>
5+
<th>Requête</th>
6+
<th>Lignes affectées</th>
7+
</tr>
8+
</thead>
9+
<tbody>
10+
{queries}
11+
<tr class="{class}" title="{hover}" data-toggle="{qid}-trace">
12+
<td class="narrow">{duration}</td>
13+
<td>{! sql !}</td>
14+
<td>{affected_rows}</td>
15+
<td class="debug-bar-alignRight"><strong>{trace-file}</strong></td>
16+
</tr>
17+
<tr class="muted debug-bar-ndisplay" id="{qid}-trace">
18+
<td></td>
19+
<td colspan="3">
20+
{trace}
21+
{index}<strong>{file}</strong><br/>
22+
{function}<br/><br/>
23+
{/trace}
24+
</td>
25+
</tr>
26+
{/queries}
27+
</tbody>
28+
</table>

0 commit comments

Comments
 (0)