%PDF- %PDF-
Direktori : /www/varak.net/losik.varak.net/vendor/nette/database/src/Bridges/DatabaseTracy/ |
Current File : /www/varak.net/losik.varak.net/vendor/nette/database/src/Bridges/DatabaseTracy/ConnectionPanel.php |
<?php /** * This file is part of the Nette Framework (https://nette.org) * Copyright (c) 2004 David Grudl (https://davidgrudl.com) */ declare(strict_types=1); namespace Nette\Bridges\DatabaseTracy; use Nette; use Nette\Database\Connection; use Nette\Database\Helpers; use Tracy; /** * Debug panel for Nette\Database. */ class ConnectionPanel implements Tracy\IBarPanel { use Nette\SmartObject; /** @var int */ public $maxQueries = 100; /** @var string */ public $name; /** @var bool|string explain queries? */ public $explain = true; /** @var bool */ public $disabled = false; /** @var float */ public $performanceScale = 0.25; /** @var float logged time */ private $totalTime = 0; /** @var int */ private $count = 0; /** @var array */ private $queries = []; /** @var Tracy\BlueScreen */ private $blueScreen; public static function initialize( Connection $connection, bool $addBarPanel = false, string $name = '', bool $explain = true, ?Tracy\Bar $bar = null, ?Tracy\BlueScreen $blueScreen = null ): ?self { $blueScreen = $blueScreen ?? Tracy\Debugger::getBlueScreen(); $blueScreen->addPanel([self::class, 'renderException']); if ($addBarPanel) { $panel = new self($connection, $blueScreen); $panel->explain = $explain; $panel->name = $name; $bar = $bar ?? Tracy\Debugger::getBar(); $bar->addPanel($panel); } return $panel ?? null; } public function __construct(Connection $connection, Tracy\BlueScreen $blueScreen) { $connection->onQuery[] = \Closure::fromCallable([$this, 'logQuery']); $this->blueScreen = $blueScreen; } private function logQuery(Connection $connection, $result): void { if ($this->disabled) { return; } $this->count++; $source = null; $trace = $result instanceof \PDOException ? $result->getTrace() : debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); foreach ($trace as $row) { if ( (isset($row['file']) && preg_match('~\.(php.?|phtml)$~', $row['file']) && !$this->blueScreen->isCollapsed($row['file'])) && ($row['class'] ?? '') !== self::class && !is_a($row['class'] ?? '', Connection::class, true) ) { $source = [$row['file'], (int) $row['line']]; break; } } if ($result instanceof Nette\Database\ResultSet) { $this->totalTime += $result->getTime(); if ($this->count < $this->maxQueries) { $this->queries[] = [$connection, $result->getQueryString(), $result->getParameters(), $source, $result->getTime(), $result->getRowCount(), null]; } } elseif ($result instanceof \PDOException && $this->count < $this->maxQueries) { $this->queries[] = [$connection, $result->queryString, null, $source, null, null, $result->getMessage()]; } } public static function renderException(?\Throwable $e): ?array { if (!$e instanceof \PDOException) { return null; } if (isset($e->queryString)) { $sql = $e->queryString; } elseif ($item = Tracy\Helpers::findTrace($e->getTrace(), 'PDO::prepare')) { $sql = $item['args'][0]; } return isset($sql) ? [ 'tab' => 'SQL', 'panel' => Helpers::dumpSql($sql, $e->params ?? []), ] : null; } public function getTab(): string { return Nette\Utils\Helpers::capture(function () { $name = $this->name; $count = $this->count; $totalTime = $this->totalTime; require __DIR__ . '/templates/ConnectionPanel.tab.phtml'; }); } public function getPanel(): ?string { if (!$this->count) { return null; } $queries = []; foreach ($this->queries as $query) { [$connection, $sql, $params, , , , $error] = $query; $explain = null; $command = preg_match('#\s*\(?\s*(SELECT|INSERT|UPDATE|DELETE)\s#iA', $sql, $m) ? strtolower($m[1]) : null; if (!$error && $this->explain && $command === 'select') { try { $cmd = is_string($this->explain) ? $this->explain : 'EXPLAIN'; $explain = (new Nette\Database\ResultSet($connection, "$cmd $sql", $params))->fetchAll(); } catch (\PDOException $e) { } } $query[] = $command; $query[] = $explain; $queries[] = $query; } return Nette\Utils\Helpers::capture(function () use ($queries, $connection) { $name = $this->name; $count = $this->count; $totalTime = $this->totalTime; $performanceScale = $this->performanceScale; require __DIR__ . '/templates/ConnectionPanel.panel.phtml'; }); } }