diff --git a/build/media_source/plg_system_debug/widgets/sqlqueries/widget.es5.js b/build/media_source/plg_system_debug/widgets/sqlqueries/widget.es5.js
index f0af1cfdf75db..16fbbd8be3593 100644
--- a/build/media_source/plg_system_debug/widgets/sqlqueries/widget.es5.js
+++ b/build/media_source/plg_system_debug/widgets/sqlqueries/widget.es5.js
@@ -124,30 +124,50 @@
})
}
- var tableExplain
+ var tableExplain;
+
+ function showTableExplain() {
+ if (tableExplain) {
+ tableExplain.show();
+ return;
+ }
+
+ // Render table
+ tableExplain = $('
').addClass(csscls('callstack')).appendTo(li);
+ tableExplain.append('| ' + stmt.explain_col.join(' | ') + ' |
');
+
+ var i, entry, cols;
+ for (i in stmt.explain) {
+ cols = []
+ entry = stmt.explain[i];
+
+ stmt.explain_col.forEach(function (key){
+ cols.push(entry[key]);
+ });
+
+ tableExplain.append('| ' + cols.join(' | ') + ' |
');
+ }
+
+ tableExplain.show();
+ }
if (stmt.explain && !$.isEmptyObject(stmt.explain)) {
var btnExplain = $('')
- .text('Explain')
- .addClass(csscls('eye'))
- .css('cursor', 'pointer')
- .on('click', function () {
- if (tableExplain.is(':visible')) {
- tableExplain.hide()
- btnExplain.addClass(csscls('eye'))
- btnExplain.removeClass(csscls('eye-dash'))
- } else {
- tableExplain.show()
- btnExplain.addClass(csscls('eye-dash'))
- btnExplain.removeClass(csscls('eye'))
- }
- })
- .appendTo(li)
-
- tableExplain = $(''
- + '| Explain |
'
- + '| Id | Select Type | Table | Type | Possible Keys | Key | Key Len | Ref | Rows | Extra |
'
- + '
').addClass(csscls('callstack'))
+ .text('Explain')
+ .addClass(csscls('eye'))
+ .css('cursor', 'pointer')
+ .on('click', function () {
+ if (tableExplain && tableExplain.is(':visible')) {
+ tableExplain.hide()
+ btnExplain.addClass(csscls('eye'))
+ btnExplain.removeClass(csscls('eye-dash'))
+ } else {
+ showTableExplain();
+ btnExplain.addClass(csscls('eye-dash'))
+ btnExplain.removeClass(csscls('eye'))
+ }
+ })
+ .appendTo(li)
}
var tableStack
@@ -214,19 +234,6 @@
}
}
- if (tableExplain) {
- tableExplain.appendTo(li)
- for (i in stmt.explain) {
- var entry = stmt.explain[i]
- tableExplain.append(''
- + '| ' + entry.id + ' | ' + entry.select_type + ' | ' + entry.table + ' | '
- + '' + entry.type + ' | ' + entry.possible_keys + ' | ' + entry.key + ' | '
- + '' + entry.key_len + ' | ' + entry.ref + ' | ' + entry.rows + ' | '
- + '' + entry.Extra + ' | '
- + '
')
- }
- }
-
li.attr('dupeindex', 'dupe-0')
}
})
diff --git a/composer.lock b/composer.lock
index d1a72c9d3fb56..696d9faad8829 100644
--- a/composer.lock
+++ b/composer.lock
@@ -910,16 +910,16 @@
},
{
"name": "joomla/database",
- "version": "2.0.0-beta",
+ "version": "2.0.0-beta2",
"source": {
"type": "git",
"url": "https://github.com/joomla-framework/database.git",
- "reference": "1332ca4c1ed8411d58898c5c68c1a818ff95bb21"
+ "reference": "1eef40d30cca0661b5cfb5c60c8600ed0d09b42d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/joomla-framework/database/zipball/1332ca4c1ed8411d58898c5c68c1a818ff95bb21",
- "reference": "1332ca4c1ed8411d58898c5c68c1a818ff95bb21",
+ "url": "https://api.github.com/repos/joomla-framework/database/zipball/1eef40d30cca0661b5cfb5c60c8600ed0d09b42d",
+ "reference": "1eef40d30cca0661b5cfb5c60c8600ed0d09b42d",
"shasum": ""
},
"require": {
@@ -936,6 +936,7 @@
"joomla/test": "^2.0",
"phpunit/phpunit": "^8.5|^9.0",
"psr/log": "^1.1",
+ "symfony/deprecation-contracts": "^2.1",
"symfony/phpunit-bridge": "^4.4|^5.0"
},
"suggest": {
@@ -971,7 +972,7 @@
"framework",
"joomla"
],
- "time": "2020-06-05T11:27:58+00:00"
+ "time": "2020-09-01T07:19:19+00:00"
},
{
"name": "joomla/di",
@@ -6806,6 +6807,7 @@
"keywords": [
"tokenizer"
],
+ "abandoned": true,
"time": "2019-09-17T06:23:10+00:00"
},
{
diff --git a/plugins/system/debug/debug.php b/plugins/system/debug/debug.php
index 2e44410d4ce8b..2c13d631871fe 100644
--- a/plugins/system/debug/debug.php
+++ b/plugins/system/debug/debug.php
@@ -508,7 +508,8 @@ public function onAfterDisconnect(ConnectionEvent $event)
if ($this->params->get('query_explains') && in_array($db->getServerType(), ['mysql', 'postgresql'], true))
{
- $logs = $this->queryMonitor->getLogs();
+ $logs = $this->queryMonitor->getLogs();
+ $boundParams = $this->queryMonitor->getBoundParams();
foreach ($logs as $k => $query)
{
@@ -524,12 +525,22 @@ public function onAfterDisconnect(ConnectionEvent $event)
{
try
{
- $db->setQuery('EXPLAIN ' . ($dbVersion56 ? 'EXTENDED ' : '') . $query);
- $this->explains[$k] = $db->loadAssocList();
+ $queryInstance = $db->getQuery(true);
+ $queryInstance->setQuery('EXPLAIN ' . ($dbVersion56 ? 'EXTENDED ' : '') . $query);
+
+ if ($boundParams[$k])
+ {
+ foreach ($boundParams[$k] as $key => $obj)
+ {
+ $queryInstance->bind($key, $obj->value, $obj->dataType, $obj->length, $obj->driverOptions);
+ }
+ }
+
+ $this->explains[$k] = $db->setQuery($queryInstance)->loadAssocList();
}
catch (Exception $e)
{
- $this->explains[$k] = [['Error' => $e->getMessage()]];
+ $this->explains[$k] = [['error' => $e->getMessage()]];
}
}
}
diff --git a/plugins/system/debug/src/DataCollector/QueryCollector.php b/plugins/system/debug/src/DataCollector/QueryCollector.php
index bedd048a00d3c..445ebb0ec5724 100644
--- a/plugins/system/debug/src/DataCollector/QueryCollector.php
+++ b/plugins/system/debug/src/DataCollector/QueryCollector.php
@@ -233,13 +233,23 @@ private function getStatements(): array
}
}
+ $explain = $this->explains[$id] ?? [];
+ $explainColumns = [];
+
+ // Extract column labels for Explain table
+ if ($explain)
+ {
+ $explainColumns = array_keys(reset($explain));
+ }
+
$statements[] = [
'sql' => $item,
'duration_str' => $this->getDataFormatter()->formatDuration($queryTime),
'memory_str' => $this->getDataFormatter()->formatBytes($queryMemory),
'caller' => $callerLocation,
'callstack' => $trace,
- 'explain' => $this->explains[$id] ?? [],
+ 'explain' => $explain,
+ 'explain_col' => $explainColumns,
'profile' => $this->profiles[$id] ?? [],
];
}