You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2022/03/08 12:47:54 UTC
[sling-org-apache-sling-app-cms] branch master updated: SLING-11102 - Adding execution support to query debug console
This is an automated email from the ASF dual-hosted git repository.
dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-app-cms.git
The following commit(s) were added to refs/heads/master by this push:
new e100237 SLING-11102 - Adding execution support to query debug console
e100237 is described below
commit e1002375c7728ee3f532361a911b6dca14bdccf7
Author: Dan Klco <kl...@adobe.com>
AuthorDate: Tue Mar 8 07:47:30 2022 -0500
SLING-11102 - Adding execution support to query debug console
---
.../sling/cms/core/models/QueryDebugger.java | 76 ++++++++++++++++++++--
.../components/cms/querydebug/querydebug.jsp | 45 +++++++++----
.../libs/sling-cms/content/admin/querydebug.json | 36 ++++++++++
3 files changed, 138 insertions(+), 19 deletions(-)
diff --git a/core/src/main/java/org/apache/sling/cms/core/models/QueryDebugger.java b/core/src/main/java/org/apache/sling/cms/core/models/QueryDebugger.java
index 7ce7012..e367b5f 100644
--- a/core/src/main/java/org/apache/sling/cms/core/models/QueryDebugger.java
+++ b/core/src/main/java/org/apache/sling/cms/core/models/QueryDebugger.java
@@ -30,7 +30,9 @@ import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
+import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
+import javax.jcr.query.RowIterator;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
@@ -42,6 +44,7 @@ import javax.management.openmbean.CompositeData;
import javax.management.openmbean.TabularData;
import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.injectorspecific.Self;
import org.osgi.annotation.versioning.ProviderType;
@@ -56,10 +59,14 @@ public class QueryDebugger {
private static final Logger log = LoggerFactory.getLogger(QueryDebugger.class);
private final String plan;
+ private final long duration;
+ private final long estimatedSize;
private final String exception;
+ private final List<Resource> results = new ArrayList<>();
private final String statement;
private final List<Map<String, Object>> slowQueries = new ArrayList<>();
private final List<Map<String, Object>> popularQueries = new ArrayList<>();
+ private final boolean enabled;
@Inject
public QueryDebugger(@Self SlingHttpServletRequest request) {
@@ -67,6 +74,11 @@ public class QueryDebugger {
Optional<String> statementParam = Optional.ofNullable(request.getParameter("statement"));
String language = Optional.ofNullable(request.getParameter("language")).orElse(Query.JCR_SQL2);
+ int limit = Optional.ofNullable(request.getParameter("sample")).map(s -> Integer.parseInt(s, 10)).orElse(0);
+
+ boolean lenabled = false;
+ long lestimate = 0;
+ long lduration = -1;
String lplan = null;
String lexception = null;
String lstatement = null;
@@ -75,18 +87,44 @@ public class QueryDebugger {
QueryManager queryManager = request.getResourceResolver().adaptTo(Session.class).getWorkspace()
.getQueryManager();
- Query query = queryManager.createQuery("explain " + statementParam.get(), language);
- Row row = query.execute().getRows().nextRow();
+ Query explainQuery = queryManager.createQuery("explain " + statementParam.get(), language);
+ Row row = explainQuery.execute().getRows().nextRow();
lplan = row.getValue("plan").getString();
lstatement = statementParam.get();
+
+ if (limit > 0) {
+ lenabled = true;
+ long start = System.currentTimeMillis();
+ Query query = queryManager.createQuery(statementParam.get(), language);
+ query.setLimit(limit);
+ QueryResult queryResult = query.execute();
+ RowIterator rowIterator = queryResult.getRows();
+ lestimate = rowIterator.getSize();
+ lduration = System.currentTimeMillis() - start;
+ while (rowIterator.hasNext()) {
+ Optional.ofNullable(rowIterator.nextRow())
+ .map(n -> {
+ try {
+ return request.getResourceResolver().getResource(n.getPath());
+ } catch (RepositoryException e) {
+ log.warn("Exception getting path from row: {}", n, e);
+ return null;
+ }
+ })
+ .ifPresent(results::add);
+ }
+ }
}
} catch (RepositoryException re) {
lexception = re.toString();
log.warn("Failed to debug query: {}", statementParam, re);
} finally {
this.plan = lplan;
+ this.duration = lduration;
this.exception = lexception;
this.statement = lstatement;
+ this.estimatedSize = lestimate;
+ this.enabled = lenabled;
}
try {
@@ -110,10 +148,24 @@ public class QueryDebugger {
}
/**
- * @return the plan
+ * @return the execution duration or -1
*/
- public String getPlan() {
- return plan;
+ public long getDuration() {
+ return duration;
+ }
+
+ /**
+ * @return the estimated size
+ */
+ public long getEstimatedSize() {
+ return estimatedSize;
+ }
+
+ /**
+ * @return if execution enabled
+ */
+ public boolean getExecutionEnabled() {
+ return enabled;
}
/**
@@ -124,6 +176,20 @@ public class QueryDebugger {
}
/**
+ * @return the plan
+ */
+ public String getPlan() {
+ return plan;
+ }
+
+ /**
+ * @return the results
+ */
+ public List<Resource> getResults() {
+ return results;
+ }
+
+ /**
* @return the statement
*/
public String getStatement() {
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/querydebug/querydebug.jsp b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/querydebug/querydebug.jsp
index fe88692..8bd1f38 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/querydebug/querydebug.jsp
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/components/cms/querydebug/querydebug.jsp
@@ -21,18 +21,35 @@
<sling:adaptTo adaptable="${slingRequest}" adaptTo="org.apache.sling.cms.core.models.QueryDebugger" var="queryDebugger" />
<br/><hr/><br/>
<dl>
- <c:if test="${not empty queryDebugger.statement}">
- <dt><fmt:message key="Query Statement" /><dt>
- <dd>${sling:encode(queryDebugger.statement,'HTML')}</dd>
- </c:if>
- <c:if test="${not empty queryDebugger.plan}">
- <dt><fmt:message key="Plan" /><dt>
- <dd>${sling:encode(queryDebugger.plan,'HTML')}</dd>
- </c:if>
- <c:if test="${not empty queryDebugger.exception}">
- <dt><fmt:message key="Exception" /><dt>
- <dd>${sling:encode(queryDebugger.exception,'HTML')}</dd>
- </c:if>
+ <c:if test="${not empty queryDebugger.statement}">
+ <dt><fmt:message key="Query Statement" /><dt>
+ <dd>${sling:encode(queryDebugger.statement,'HTML')}</dd>
+ </c:if>
+ <c:if test="${not empty queryDebugger.plan}">
+ <dt><fmt:message key="Plan" /><dt>
+ <dd>${sling:encode(queryDebugger.plan,'HTML')}</dd>
+ </c:if>
+ <c:if test="${not empty queryDebugger.exception}">
+ <dt><fmt:message key="Exception" /><dt>
+ <dd>${sling:encode(queryDebugger.exception,'HTML')}</dd>
+ </c:if>
+ <c:if test="${queryDebugger.executionEnabled}">
+ <dt><fmt:message key="Duration" /><dt>
+ <dd>${queryDebugger.duration}</dd>
+ <dt><fmt:message key="Size" /><dt>
+ <dd>${queryDebugger.estimatedSize}</dd>
+ <dt><fmt:message key="Results" /><dt>
+ <dd>
+ <nav class="panel fixed-box">
+ <c:forEach var="result" items="${queryDebugger.results}">
+ <a class="panel-block" href="/bin/browser.html${result.path}" target="_blank">
+ ${result.path} [${result.resourceType}]
+ </a>
+ </c:forEach>
+ </nav>
+ </dd>
+ </c:if>
+ </dl>
<br/><hr/><br/>
<h2><fmt:message key="Popular Queries" /></h2>
<table class="table">
@@ -59,7 +76,7 @@
${query.position}
</td>
<td>
- ${fn:encode(query.statement,'HTML')}
+ ${sling:encode(query.statement,'HTML')}
</td>
<td>
${query.language}
@@ -98,7 +115,7 @@
${query.position}
</td>
<td>
- ${fn:encode(query.statement,'HTML')}
+ ${sling:encode(query.statement,'HTML')}
</td>
<td>
${query.language}
diff --git a/ui/src/main/resources/jcr_root/libs/sling-cms/content/admin/querydebug.json b/ui/src/main/resources/jcr_root/libs/sling-cms/content/admin/querydebug.json
index 7e6ebbc..473b956 100644
--- a/ui/src/main/resources/jcr_root/libs/sling-cms/content/admin/querydebug.json
+++ b/ui/src/main/resources/jcr_root/libs/sling-cms/content/admin/querydebug.json
@@ -54,6 +54,42 @@
"value": "sql"
}
}
+ },
+ "sampleResults": {
+ "jcr:primaryType": "nt:unstructured",
+ "sling:resourceType": "sling-cms/components/editor/fields/select",
+ "label": "Sample Results",
+ "name": "sample",
+ "options": {
+ "none": {
+ "label": "None",
+ "value": "0"
+ },
+ "100": {
+ "label": "100",
+ "value": "100"
+ },
+ "1000": {
+ "label": "1000",
+ "value": "1000"
+ },
+ "10000": {
+ "label": "10000",
+ "value": "10000"
+ },
+ "100000": {
+ "label": "100000",
+ "value": "100000"
+ },
+ "1000000": {
+ "label": "1000000",
+ "value": "1000000"
+ },
+ "2147483647": {
+ "label": "MAX",
+ "value": "2147483647"
+ }
+ }
}
}
},