3 namespace Drupal\webprofiler\DataCollector;
5 use Drupal\Core\Config\ConfigFactoryInterface;
6 use Drupal\Core\Database\Connection;
7 use Drupal\Core\Database\Database;
8 use Drupal\Core\StringTranslation\StringTranslationTrait;
9 use Drupal\webprofiler\DrupalDataCollectorInterface;
10 use Symfony\Component\HttpFoundation\Request;
11 use Symfony\Component\HttpFoundation\Response;
12 use Symfony\Component\HttpKernel\DataCollector\DataCollector;
15 * Class DatabaseDataCollector
17 class DatabaseDataCollector extends DataCollector implements DrupalDataCollectorInterface {
19 use StringTranslationTrait, DrupalDataCollectorTrait;
22 * @var \Drupal\Core\Database\Connection
27 * @var \Drupal\Core\Config\ConfigFactoryInterface
29 private $configFactory;
32 * @param \Drupal\Core\Database\Connection $database
33 * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
35 public function __construct(Connection $database, ConfigFactoryInterface $configFactory) {
36 $this->database = $database;
37 $this->configFactory = $configFactory;
43 public function collect(Request $request, Response $response, \Exception $exception = NULL) {
45 foreach (Database::getAllConnectionInfo() as $key => $info) {
46 $database = Database::getConnection('default', $key);
47 $connections[$key] = $database->getLogger()->get('webprofiler');
50 $this->data['connections'] = array_keys($connections);
53 foreach ($connections as $key => $queries) {
54 foreach ($queries as $query) {
55 // Remove caller args.
56 unset($query['caller']['args']);
58 // Remove query args element if empty.
59 if (isset($query['args']) && empty($query['args'])) {
60 unset($query['args']);
63 // Save time in milliseconds.
64 $query['time'] = $query['time'] * 1000;
65 $query['database'] = $key;
70 $querySort = $this->configFactory->get('webprofiler.config')
72 if ('duration' === $querySort) {
75 "Drupal\\webprofiler\\DataCollector\\DatabaseDataCollector",
81 $this->data['queries'] = $data;
83 $options = $this->database->getConnectionOptions();
85 // Remove password for security.
86 unset($options['password']);
88 $this->data['database'] = $options;
94 public function getDatabase() {
95 return $this->data['database'];
101 public function getQueryCount() {
102 return count($this->data['queries']);
108 public function getQueries() {
109 return $this->data['queries'];
113 * Returns the total execution time.
117 public function getTime() {
120 foreach ($this->data['queries'] as $query) {
121 $time += $query['time'];
128 * Returns a color based on the number of executed queries.
132 public function getColorCode() {
133 if ($this->getQueryCount() < 100) {
136 if ($this->getQueryCount() < 200) {
144 * Returns the configured query highlight threshold.
148 public function getQueryHighlightThreshold() {
149 // When a profile is loaded from storage this object is deserialized and
150 // no constructor is called so we cannot use dependency injection.
151 return \Drupal::config('webprofiler.config')->get('query_highlight');
157 public function getName() {
164 public function getTitle() {
165 return $this->t('Database');
171 public function getPanelSummary() {
172 return $this->t('Executed queries: @count', ['@count' => $this->getQueryCount()]);
178 public function getIcon() {
179 return 'iVBORw0KGgoAAAANSUhEUgAAABQAAAAcCAYAAABh2p9gAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQRJREFUeNpi/P//PwM1ARMDlcGogZQDlpMnT7pxc3NbA9nhQKxOpL5rQLwJiPeBsI6Ozl+YBOOOHTv+AOllQNwtLS39F2owKYZ/gRq8G4i3ggxEToggWzvc3d2Pk+1lNL4fFAs6ODi8JzdS7mMRVyDVoAMHDsANdAPiOCC+jCQvQKqBQB/BDbwBxK5AHA3E/kB8nKJkA8TMQBwLxaBIKQbi70AvTADSBiSadwFXpCikpKQU8PDwkGTaly9fHFigkaKIJid4584dkiMFFI6jkTJII0WVmpHCAixZQEXWYhDeuXMnyLsVlEQKI45qFBQZ8eRECi4DBaAlDqle/8A48ip6gAADANdQY88Uc0oGAAAAAElFTkSuQmCC';
185 public function getLibraries() {
187 'webprofiler/database',
194 public function getData() {
197 $conn = Database::getConnection();
198 foreach ($data['queries'] as &$query) {
202 if (strpos($query['query'], 'INSERT') !== FALSE) {
207 if (strpos($query['query'], 'UPDATE') !== FALSE) {
212 if (strpos($query['query'], 'CREATE') !== FALSE) {
217 if (strpos($query['query'], 'DELETE') !== FALSE) {
222 $query['explain'] = $explain;
223 $query['type'] = $type;
227 if (isset($query['args'])) {
228 foreach ((array) $query['args'] as $key => $val) {
229 $quoted[$key] = is_null($val) ? 'NULL' : $conn->quote($val);
233 $query['query_args'] = strtr($query['query'], $quoted);
236 $data['query_highlight_threshold'] = $this->getQueryHighlightThreshold();
247 private function orderQueryByTime($a, $b) {
254 return ($at < $bt) ? 1 : -1;