LENS-836: Query commands in CLI should take default value for query handle as the last executed query
Project: http://git-wip-us.apache.org/repos/asf/lens/repo Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/7a89db13 Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/7a89db13 Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/7a89db13 Branch: refs/heads/current-release-line Commit: 7a89db13e74984de81d840dc015c4ba59471d785 Parents: 04f5a82 Author: Rajat Khandelwal <pro...@apache.org> Authored: Thu Dec 24 13:19:12 2015 +0530 Committer: Rajat Khandelwal <rajatgupt...@gmail.com> Committed: Thu Dec 24 13:19:12 2015 +0530 ---------------------------------------------------------------------- .../lens/cli/commands/LensQueryCommands.java | 76 ++++++++++++-------- .../apache/lens/cli/TestLensQueryCommands.java | 7 +- .../java/org/apache/lens/client/LensClient.java | 9 +-- .../org/apache/lens/client/LensStatement.java | 12 +--- src/site/apt/user/cli.apt | 10 +-- 5 files changed, 62 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lens/blob/7a89db13/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java index e3c08ff..a29600d 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensQueryCommands.java @@ -61,6 +61,8 @@ import com.google.common.base.Joiner; + " <<<query execute cube select id,name from dim_table where name != \"\"first\"\">>>,\n" + " will be parsed as <<<cube select id,name from dim_table where name != \"first\">>>") public class LensQueryCommands extends BaseLensCommand { + private static final String DEFAULT_QUERY_HANDLE_DESCRIPTION = + "If not provided, takes last query handle interacted with."; /** * Execute query. @@ -110,7 +112,6 @@ public class LensQueryCommands extends BaseLensCommand { */ private String formatResultSet(LensClient.LensClientResultSetWithStats rs) { StringBuilder b = new StringBuilder(); - int numRows = 0; if (rs.getResultSet() != null) { QueryResultSetMetadata resultSetMetadata = rs.getResultSet().getResultSetMetadata(); for (ResultColumn column : resultSetMetadata.getColumns()) { @@ -125,7 +126,7 @@ public class LensQueryCommands extends BaseLensCommand { PersistentQueryResult temp = (PersistentQueryResult) r; b.append("Results of query stored at : ").append(temp.getPersistedURI()).append(" "); if (null != temp.getNumRows()) { - b.append(temp.getNumRows() + " rows "); + b.append(temp.getNumRows()).append(" rows "); } } } @@ -139,20 +140,33 @@ public class LensQueryCommands extends BaseLensCommand { return b.toString(); } + public String getOrDefaultQueryHandleString(String queryHandleString) { + if (queryHandleString != null) { + return queryHandleString; + } + if (getClient().getStatement().getQuery() != null) { + return getClient().getStatement().getQueryHandleString(); + } + throw new IllegalArgumentException("Query handle not provided and no queries interacted with in the session."); + } + /** * Gets the status. * * @param qh the qh * @return the status */ - @CliCommand(value = "query status", help = "Fetch status of executed query having query handle <query_handle>") + @CliCommand(value = "query status", + help = "Fetch status of executed query having query handle <query_handle>. " + DEFAULT_QUERY_HANDLE_DESCRIPTION) public String getStatus( - @CliOption(key = {"", "query_handle"}, mandatory = true, help = "<query_handle>") String qh) { - QueryStatus status = getClient().getQueryStatus(new QueryHandle(UUID.fromString(qh))); + @CliOption(key = {"", "query_handle"}, mandatory = false, help = "<query_handle>") String qh) { + qh = getOrDefaultQueryHandleString(qh); + QueryHandle handle = QueryHandle.fromString(qh); + QueryStatus status = getClient().getQueryStatus(handle); if (status == null) { - return "Unable to find status for " + qh; + return "Unable to find status for " + handle; } - return status.toString(); + return "Query Handle: " + qh + "\n" + status.toString(); } /** @@ -161,15 +175,15 @@ public class LensQueryCommands extends BaseLensCommand { * @param qh the qh * @return the query */ - @CliCommand(value = "query details", help = "Get query details of query with handle <query_handle>") + @CliCommand(value = "query details", + help = "Get query details of query with handle <query_handle>." + DEFAULT_QUERY_HANDLE_DESCRIPTION) public String getDetails( - @CliOption(key = {"", "query_handle"}, mandatory = true, help - = "<query_handle>") String qh) { + @CliOption(key = {"", "query_handle"}, mandatory = false, help = "<query_handle>") String qh) { + qh = getOrDefaultQueryHandleString(qh); LensQuery query = getClient().getQueryDetails(qh); if (query == null) { return "Unable to find query for " + qh; } - try { return formatJson(mapper.writer(pp).writeValueAsString(query)); } catch (IOException e) { @@ -185,10 +199,11 @@ public class LensQueryCommands extends BaseLensCommand { * @throws LensAPIException * @throws UnsupportedEncodingException the unsupported encoding exception */ - @CliCommand(value = "query explain", help = "Explain execution plan of query <query-string>. " + @CliCommand(value = "query explain", + help = "Explain execution plan of query <query-string>. " + "Can optionally save the plan to a file by providing <save_location>") - public String explainQuery(@CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql, - @CliOption(key = { "save_location" }, mandatory = false, help = "<save_location>") final File path) + public String explainQuery(@CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql, + @CliOption(key = {"save_location"}, mandatory = false, help = "<save_location>") final File path) throws IOException, LensAPIException { PrettyPrintable cliOutput; @@ -197,7 +212,7 @@ public class LensQueryCommands extends BaseLensCommand { if (path != null && StringUtils.isNotBlank(path.getPath())) { String validPath = getValidPath(path, false, false); try (OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(validPath), - Charset.defaultCharset())) { + Charset.defaultCharset())) { osw.write(plan.getPlanString()); } return "Saved to " + validPath; @@ -250,9 +265,10 @@ public class LensQueryCommands extends BaseLensCommand { * @param qh the qh * @return the string */ - @CliCommand(value = "query kill", help = "Kill query with handle <query_handle>") - public String killQuery( - @CliOption(key = {"", "query_handle"}, mandatory = true, help = "<query_handle>") String qh) { + @CliCommand(value = "query kill", help = "Kill query with handle <query_handle>." + DEFAULT_QUERY_HANDLE_DESCRIPTION) + public String killQuery(@CliOption(key = {"", "query_handle"}, mandatory = false, help = "<query_handle>") String + qh) { + qh = getOrDefaultQueryHandleString(qh); boolean status = getClient().killQuery(new QueryHandle(UUID.fromString(qh))); if (status) { return "Successfully killed " + qh; @@ -268,19 +284,19 @@ public class LensQueryCommands extends BaseLensCommand { * @return the query results */ @CliCommand(value = "query results", - help = "get results of query with query handle <query_handle>. If async is false " - + "then wait till the query execution is completed, it's by default true. " + help = "get results of query with query handle <query_handle>. " + DEFAULT_QUERY_HANDLE_DESCRIPTION + + "If async is false then wait till the query execution is completed, it's by default true. " + "Can optionally save the results to a file by providing <save_location>.") public String getQueryResults( - @CliOption(key = {"", "query_handle"}, mandatory = true, help = "<query_handle>") String qh, + @CliOption(key = {"", "query_handle"}, mandatory = false, help = "<query_handle>") String qh, @CliOption(key = {"save_location"}, mandatory = false, help = "<save_location>") final File path, @CliOption(key = {"async"}, mandatory = false, unspecifiedDefaultValue = "true", help = "<async>") boolean async) { + qh = getOrDefaultQueryHandleString(qh); QueryHandle queryHandle = new QueryHandle(UUID.fromString(qh)); LensClient.LensClientResultSetWithStats results; String location = path != null ? path.getPath() : null; try { - String prefix = ""; if (StringUtils.isNotBlank(location)) { location = getValidPath(path, true, true); Response response = getClient().getHttpResults(queryHandle); @@ -289,7 +305,7 @@ public class LensQueryCommands extends BaseLensCommand { String fileName = disposition.split("=")[1].trim(); location = getValidPath(new File(location + File.separator + fileName), false, false); try (InputStream stream = response.readEntity(InputStream.class); - FileOutputStream outStream = new FileOutputStream(new File(location))) { + FileOutputStream outStream = new FileOutputStream(new File(location))) { IOUtils.copy(stream, outStream); } return "Saved to " + location; @@ -364,7 +380,7 @@ public class LensQueryCommands extends BaseLensCommand { StringBuilder sb = new StringBuilder() .append("User query:").append(prepared.getUserQuery()).append("\n") .append("Prepare handle:").append(prepared.getPrepareHandle()).append("\n") - .append("User:" + prepared.getPreparedUser()).append("\n") + .append("User:").append(prepared.getPreparedUser()).append("\n") .append("Prepared at:").append(prepared.getPreparedTime()).append("\n") .append("Selected driver :").append(prepared.getSelectedDriverName()).append("\n") .append("Driver query:").append(prepared.getDriverQuery()).append("\n"); @@ -454,19 +470,17 @@ public class LensQueryCommands extends BaseLensCommand { * the unsupported encoding exception * @throws LensAPIException */ - @CliCommand(value = "prepQuery explain", help = "Explain and prepare query <query-string>. " - + "Can optionally provide <query-name>") + @CliCommand(value = "prepQuery explain", + help = "Explain and prepare query <query-string>. Can optionally provide <query-name>") public String explainAndPrepare( - @CliOption(key = { "", "query" }, mandatory = true, help = "<query-string>") String sql, - @CliOption(key = { "name" }, mandatory = false, help = "<query-name>") String queryName) + @CliOption(key = {"", "query"}, mandatory = true, help = "<query-string>") String sql, + @CliOption(key = {"name"}, mandatory = false, help = "<query-name>") String queryName) throws UnsupportedEncodingException, LensAPIException { PrettyPrintable cliOutput; try { QueryPlan plan = getClient().explainAndPrepare(sql, queryName).getData(); - StringBuilder planStr = new StringBuilder(plan.getPlanString()); - planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle()); - return planStr.toString(); + return plan.getPlanString() + "\n" + "Prepare handle:" + plan.getPrepareHandle(); } catch (final LensAPIException e) { BriefError briefError = new BriefError(e.getLensAPIErrorCode(), e.getLensAPIErrorMessage()); cliOutput = new IdBriefErrorTemplate(IdBriefErrorTemplateKey.REQUEST_ID, e.getLensAPIRequestId(), briefError); http://git-wip-us.apache.org/repos/asf/lens/blob/7a89db13/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java index 6ebfff7..2de3cc1 100644 --- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java +++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensQueryCommands.java @@ -102,6 +102,7 @@ public class TestLensQueryCommands extends LensCliApplicationTest { String sql = "cube select id,name from test_dim"; String result = qCom.executeQuery(sql, false, "testQuery2"); assertTrue(result.contains("1\tfirst"), result); + } /** @@ -237,11 +238,11 @@ public class TestLensQueryCommands extends LensCliApplicationTest { String[] resultSplits = result.split("\n"); // assert on the number of queries assertEquals(String.valueOf(resultSplits.length - 1), resultSplits[resultSplits.length - 1].split(": ")[1]); - + assertEquals(qCom.getOrDefaultQueryHandleString(null), qh); QueryStatus queryStatus = qCom.getClient().getQueryStatus(qh); while (!queryStatus.finished()) { if (queryStatus.launched()) { - String details = qCom.getDetails(qh); + String details = qCom.getDetails(null); assertTrue(details.contains("driverQuery")); } Thread.sleep(1000); @@ -256,7 +257,7 @@ public class TestLensQueryCommands extends LensCliApplicationTest { String details = qCom.getDetails(qh); assertTrue(details.contains("driverQuery")); - result = qCom.getQueryResults(qh, null, true); + result = qCom.getQueryResults(null, null, true); assertTrue(result.contains("1\tfirst")); downloadResult(qCom, qh, result); http://git-wip-us.apache.org/repos/asf/lens/blob/7a89db13/lens-client/src/main/java/org/apache/lens/client/LensClient.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/LensClient.java b/lens-client/src/main/java/org/apache/lens/client/LensClient.java index 8f197e4..f7f99c7 100644 --- a/lens-client/src/main/java/org/apache/lens/client/LensClient.java +++ b/lens-client/src/main/java/org/apache/lens/client/LensClient.java @@ -57,6 +57,7 @@ public class LensClient { private LensConnection connection; private final HashMap<QueryHandle, LensStatement> statementMap = Maps.newHashMap(); + @Getter private final LensStatement statement; @Getter @@ -192,11 +193,11 @@ public class LensClient { } public QueryStatus getQueryStatus(QueryHandle query) { - return new LensStatement(connection).getQuery(query).getStatus(); + return statement.getQuery(query).getStatus(); } public LensQuery getQueryDetails(QueryHandle handle) { - return new LensStatement(connection).getQuery(handle); + return statement.getQuery(handle); } public QueryStatus getQueryStatus(String q) { @@ -208,7 +209,7 @@ public class LensClient { } public LensAPIResult<QueryPlan> getQueryPlan(String q) throws LensAPIException { - return new LensStatement(connection).explainQuery(q); + return statement.explainQuery(q); } public boolean killQuery(QueryHandle q) { @@ -228,7 +229,7 @@ public class LensClient { public List<QueryHandle> getQueries(String state, String queryName, String user, String driver, long fromDate, long toDate) { - return new LensStatement(connection).getAllQueries(state, queryName, user, driver, fromDate, toDate); + return statement.getAllQueries(state, queryName, user, driver, fromDate, toDate); } private void connectToLensServer() { http://git-wip-us.apache.org/repos/asf/lens/blob/7a89db13/lens-client/src/main/java/org/apache/lens/client/LensStatement.java ---------------------------------------------------------------------- diff --git a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java index 71caa48..8de7708 100644 --- a/lens-client/src/main/java/org/apache/lens/client/LensStatement.java +++ b/lens-client/src/main/java/org/apache/lens/client/LensStatement.java @@ -40,9 +40,12 @@ import org.glassfish.jersey.media.multipart.FormDataBodyPart; import org.glassfish.jersey.media.multipart.FormDataContentDisposition; import org.glassfish.jersey.media.multipart.FormDataMultiPart; +import lombok.RequiredArgsConstructor; + /** * Top level class which is used to execute lens queries. */ +@RequiredArgsConstructor public class LensStatement { /** The connection. */ @@ -52,15 +55,6 @@ public class LensStatement { private LensQuery query; /** - * Instantiates a new lens statement. - * - * @param connection the connection - */ - public LensStatement(LensConnection connection) { - this.connection = connection; - } - - /** * Execute. * * @param sql the sql http://git-wip-us.apache.org/repos/asf/lens/blob/7a89db13/src/site/apt/user/cli.apt ---------------------------------------------------------------------- diff --git a/src/site/apt/user/cli.apt b/src/site/apt/user/cli.apt index 3db53c4..65380e6 100644 --- a/src/site/apt/user/cli.apt +++ b/src/site/apt/user/cli.apt @@ -347,19 +347,19 @@ User CLI Commands *--+--+ |prepQuery prepare [--query] \<query-string\> [--name \<query-name\>]|Prepapre query <<<query-string>>> and return prepare handle. Can optionaly provide <<<query-name>>>| *--+--+ -|query details [--query_handle] \<query_handle\>|Get query details of query with handle <<<query_handle>>>| +|query details [[--query_handle] \<query_handle\>]|Get query details of query with handle <<<query_handle>>>.If not provided, takes last query handle interacted with.| *--+--+ |query execute [--query] \<query-string\> [--async \<async\>] [--name \<query-name\>]|Execute query <<<query-string>>>. If <<<async>>> is true, The query is launched in async manner and query handle is returned. It's by default false. <<<query name>>> can also be provided, though not required| *--+--+ |query explain [--query] \<query-string\> [--save_location \<save_location\>]|Explain execution plan of query <<<query-string>>>. Can optionally save the plan to a file by providing <<<save_location>>>| *--+--+ -|query kill [--query_handle] \<query_handle\>|Kill query with handle <<<query_handle>>>| +|query kill [[--query_handle] \<query_handle\>]|Kill query with handle <<<query_handle>>>.If not provided, takes last query handle interacted with.| *--+--+ -|query list [--state \<query-status\>] [--name \<query-name\>] [--user \<user-who-submitted-query\>] [--driver \<driver-where-query-was-executed\>] [--fromDate \<submission-time-is-after\>] [--toDate \<submission-time-is-before\>]|Get all queries. Various filter options can be provided(optionally), as can be seen from the command syntax| +|query list [--state \<query-status\>] [--name \<query-name\>] [--user \<user-who-submitted-query\>] [--driver \<driver-where-query-ran\>] [--fromDate \<submission-time-is-after\>] [--toDate \<submission-time-is-before\>]|Get all queries. Various filter options can be provided(optionally), as can be seen from the command syntax| *--+--+ -|query results [--query_handle] \<query_handle\> [--save_location \<save_location\>] [--async \<async\>]|get results of query with query handle <<<query_handle>>>. If async is false then wait till the query execution is completed, it's by default true. Can optionally save the results to a file by providing <<<save_location>>>.| +|query results [[--query_handle] \<query_handle\>] [--save_location \<save_location\>] [--async \<async\>]|get results of query with query handle <<<query_handle>>>. If not provided, takes last query handle interacted with.If async is false then wait till the query execution is completed, it's by default true. Can optionally save the results to a file by providing <<<save_location>>>.| *--+--+ -|query status [--query_handle] \<query_handle\>|Fetch status of executed query having query handle <<<query_handle>>>| +|query status [[--query_handle] \<query_handle\>]|Fetch status of executed query having query handle <<<query_handle>>>. If not provided, takes last query handle interacted with.| *--+--+ <<Lens Query Commands>>