LENS-256 : lens-cli should not use single parameter for two values (Rajat Khandelwal via amareshwari)
Project: http://git-wip-us.apache.org/repos/asf/incubator-lens/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-lens/commit/10917c25 Tree: http://git-wip-us.apache.org/repos/asf/incubator-lens/tree/10917c25 Diff: http://git-wip-us.apache.org/repos/asf/incubator-lens/diff/10917c25 Branch: refs/heads/master Commit: 10917c25e4bd1ddaceef242836a25bb555e3e95e Parents: 9b51b46 Author: Rajat Khandelwal <[email protected]> Authored: Thu May 7 11:14:26 2015 +0530 Committer: Amareshwari Sriramadasu <[email protected]> Committed: Thu May 7 11:14:26 2015 +0530 ---------------------------------------------------------------------- .../lens/cli/commands/BaseLensCommand.java | 47 +- .../lens/cli/commands/LensCRUDCommand.java | 75 +++ .../LensCRUDStoragePartitionCommand.java | 114 +++++ .../cli/commands/LensConnectionCommands.java | 92 ++-- .../lens/cli/commands/LensCubeCommands.java | 145 +++--- .../lens/cli/commands/LensDatabaseCommands.java | 73 +-- .../cli/commands/LensDimensionCommands.java | 131 +++--- .../commands/LensDimensionTableCommands.java | 459 ++++++++----------- .../lens/cli/commands/LensFactCommands.java | 427 ++++++++--------- .../cli/commands/LensNativeTableCommands.java | 55 ++- .../lens/cli/commands/LensQueryCommands.java | 180 ++++---- .../lens/cli/commands/LensStorageCommands.java | 111 ++--- .../commands/annotations/UserDocumentation.java | 29 ++ .../META-INF/spring/spring-shell-plugin.xml | 24 +- .../apache/lens/cli/TestLensCubeCommands.java | 6 +- .../lens/cli/TestLensDatabaseCommands.java | 2 +- .../lens/cli/TestLensDimensionCommands.java | 2 +- .../cli/TestLensDimensionTableCommands.java | 51 ++- .../apache/lens/cli/TestLensFactCommands.java | 40 +- .../apache/lens/cli/TestLensQueryCommands.java | 10 +- .../lens/cli/TestLensStorageCommands.java | 2 +- .../lens/cli/doc/TestGenerateCLIUserDoc.java | 126 +++++ lens-cli/src/test/resources/cli-intro.apt | 78 ++++ src/site/apt/user/cli.apt | 289 ++++++++---- tools/scripts/generate-site-public.sh | 2 +- 25 files changed, 1540 insertions(+), 1030 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/BaseLensCommand.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/BaseLensCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/BaseLensCommand.java index bf90cdc..8707fec 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/BaseLensCommand.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/BaseLensCommand.java @@ -18,6 +18,7 @@ */ package org.apache.lens.cli.commands; +import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -35,11 +36,15 @@ import org.codehaus.jackson.impl.Indenter; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion; import org.codehaus.jackson.util.DefaultPrettyPrinter; +import org.springframework.shell.core.ExecutionProcessor; +import org.springframework.shell.event.ParseResult; + +import com.google.common.collect.Sets; /** * The Class BaseLensCommand. */ -public class BaseLensCommand { +public class BaseLensCommand implements ExecutionProcessor { /** The mapper. */ protected ObjectMapper mapper; @@ -134,4 +139,44 @@ public class BaseLensCommand { return json.replaceAll("\\[ \\{", "\n\n ").replaceAll("\\{", "").replaceAll("}", "").replaceAll("\\[", "") .replaceAll("]", "\n").replaceAll(",", "").replaceAll("\"", "").replaceAll("\n\n", "\n"); } + + public String getValidPath(String path) { + if (path.startsWith("~")) { + path = path.replaceFirst("~", System.getProperty("user.home")); + } + File f = new File(path); + if (!f.exists()) { + throw new RuntimeException("Path " + path + " doesn't exist."); + } + return f.getAbsolutePath(); + } + + + /** + * This Code piece allows lens cli to be able to parse list arguments. It can already parse keyword args. + * More details at https://github.com/spring-projects/spring-shell/issues/72 + * @param parseResult + * @return + */ + @Override + public ParseResult beforeInvocation(ParseResult parseResult) { + Object[] args = parseResult.getArguments(); + if (args != null && Sets.newHashSet(args).size() == 1) { + if (args[0] instanceof String) { + String[] split = ((String) args[0]).split("\\s+"); + Object[] newArgs = new String[args.length]; + System.arraycopy(split, 0, newArgs, 0, split.length); + parseResult = new ParseResult(parseResult.getMethod(), parseResult.getInstance(), newArgs); + } + } + return parseResult; + } + + @Override + public void afterReturningInvocation(ParseResult parseResult, Object o) { + } + + @Override + public void afterThrowingInvocation(ParseResult parseResult, Throwable throwable) { + } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDCommand.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDCommand.java new file mode 100644 index 0000000..05922e3 --- /dev/null +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDCommand.java @@ -0,0 +1,75 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.lens.cli.commands; + +import java.io.IOException; +import java.util.List; + +import org.apache.lens.api.APIResult; + +import com.google.common.base.Joiner; + +public abstract class LensCRUDCommand<T> extends BaseLensCommand { + + // Template methods. overriding classes need a binding to commands so + // they can call them directly from their own methods. + public String showAll() { + List<String> all = getAll(); + if (all == null || all.isEmpty()) { + return "No " + getSingleObjectName() + " found"; + } + return Joiner.on("\n").join(all); + } + + public String create(String path, boolean ignoreIfExists) { + return doCreate(getValidPath(path), ignoreIfExists).getStatus().toString().toLowerCase(); + } + + public String describe(String name) { + try { + return formatJson(mapper.writer(pp).writeValueAsString(doRead(name))); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + public String update(String entity, String path) { + return doUpdate(entity, getValidPath(path)).getStatus().toString().toLowerCase(); + } + + public String drop(String name, boolean cascade) { + return doDelete(name, cascade).getStatus().toString().toLowerCase(); + } + + public String getSingleObjectName() { + return getClass().getSimpleName().substring(4, getClass().getSimpleName().indexOf("Command")).toLowerCase(); + } + + // Actual operations. Need to be overridden by overriding classes + + public abstract List<String> getAll(); + + protected abstract APIResult doCreate(String path, boolean ignoreIfExists); + + protected abstract T doRead(String name); + + public abstract APIResult doUpdate(String name, String path); + + protected abstract APIResult doDelete(String name, boolean cascade); +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDStoragePartitionCommand.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDStoragePartitionCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDStoragePartitionCommand.java new file mode 100644 index 0000000..0d53e21 --- /dev/null +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDStoragePartitionCommand.java @@ -0,0 +1,114 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.lens.cli.commands; + +import java.io.IOException; +import java.util.List; + +import org.apache.lens.api.APIResult; +import org.apache.lens.api.metastore.XPartition; +import org.apache.lens.api.metastore.XStorageTableElement; + +import com.google.common.base.Joiner; + +public abstract class LensCRUDStoragePartitionCommand<T> extends LensCRUDCommand<T> { + public String showAll(String filter) { + List<String> all = getAll(filter); + if (all == null || all.isEmpty()) { + return "No " + getSingleObjectName() + " found" + (filter == null ? "" : " for " + filter); + } + return Joiner.on("\n").join(all); + } + + public String showAllStorages(String tableName) { + String sep = ""; + StringBuilder sb = new StringBuilder(); + List<String> storages = getAllStorages(tableName); + if (storages != null) { + for (String storage : storages) { + if (!storage.isEmpty()) { + sb.append(sep).append(storage); + sep = "\n"; + } + } + } + String ret = sb.toString(); + return ret.isEmpty() ? "No storage found for " + tableName : ret; + } + + public String addStorage(String tableName, String path) { + return doAddStorage(tableName, getValidPath(path)).toString().toLowerCase(); + } + + public String getStorage(String tableName, String storage) { + try { + return formatJson(mapper.writer(pp).writeValueAsString(readStorage(tableName, storage))); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + public String dropStorage(String tableName, String storageName) { + return doDropStorage(tableName, storageName).toString().toLowerCase(); + } + + public String dropAllStorages(String tableName) { + return doDropAllStorages(tableName).toString(); + } + + public String getAllPartitions(String tableName, String storageName, String filter) { + try { + return formatJson(mapper.writer(pp).writeValueAsString(readAllPartitions(tableName, storageName, filter))); + } catch (IOException e) { + throw new IllegalArgumentException(e); + } + } + + public String addPartition(String tableName, String storageName, String path) { + return doAddPartition(tableName, storageName, getValidPath(path)).toString().toLowerCase(); + } + + public String addPartitions(String tableName, String storageName, String path) { + return doAddPartitions(tableName, storageName, getValidPath(path)).toString().toLowerCase(); + } + + public String dropPartitions(String tableName, String storageName, String filter) { + return doDropPartitions(tableName, storageName, filter).toString().toLowerCase(); + } + + protected abstract List<String> getAll(String filter); + + public abstract List<String> getAllStorages(String name); + + public abstract APIResult doAddStorage(String name, String path); + + protected abstract XStorageTableElement readStorage(String tableName, String storage); + + public abstract APIResult doDropStorage(String tableName, String storageName); + + public abstract APIResult doDropAllStorages(String name); + + protected abstract List<XPartition> readAllPartitions(String tableName, String storageName, String filter); + + protected abstract APIResult doAddPartition(String tableName, String storageName, String path); + + protected abstract APIResult doAddPartitions(String tableName, String storageName, String path); + + protected abstract APIResult doDropPartitions(String tableName, String storageName, String filter); +} http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java index b6be2e0..d727ecc 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensConnectionCommands.java @@ -20,9 +20,11 @@ package org.apache.lens.cli.commands; import java.util.List; +import javax.ws.rs.ProcessingException; + import org.apache.lens.api.APIResult; +import org.apache.lens.cli.commands.annotations.UserDocumentation; -import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.ExitShellRequest; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; @@ -34,7 +36,10 @@ import com.google.common.base.Joiner; * The Class LensConnectionCommands. */ @Component -public class LensConnectionCommands extends BaseLensCommand implements CommandMarker { +@UserDocumentation(title = "Session management", + description = "Opening the lens CLI shell is equivalent to open a session with lens server." + + "This section provides all the commands available for in shell which are applicable for the full session.") +public class LensConnectionCommands extends BaseLensCommand { /** * Sets the param. @@ -42,8 +47,8 @@ public class LensConnectionCommands extends BaseLensCommand implements CommandMa * @param keyval the keyval * @return the string */ - @CliCommand(value = "set", help = "sets a session parameter.") - public String setParam(@CliOption(key = {"", "param"}, mandatory = true, help = "key=val") String keyval) { + @CliCommand(value = "set", help = "Assign <value> to session parameter specified with <key> on lens server") + public String setParam(@CliOption(key = {""}, mandatory = true, help = "<key>=<value>") String keyval) { String[] pair = keyval.split("="); if (pair.length != 2) { return "Error: Pass parameter as <key>=<value>"; @@ -53,39 +58,25 @@ public class LensConnectionCommands extends BaseLensCommand implements CommandMa } /** - * Show parameters. + * Gets the param. * - * @return the string + * @param param the param + * @return the param */ - @CliCommand(value = "show params", help = "list of all session parameter") - public String showParameters() { - List<String> params = getClient().getConnectionParam(); - return Joiner.on("\n").skipNulls().join(params); + @CliCommand(value = "get", help = "Fetches and prints session parameter specified with name <key> from lens server") + public String getParam(@CliOption(key = {"", "key"}, mandatory = true, help = "<key>") String param) { + return Joiner.on("\n").skipNulls().join(getClient().getConnectionParam(param)); } /** - * List resources. + * Show parameters. * * @return the string */ - @CliCommand(value = "list resources", help = "list all resources from session") - public String listResources(@CliOption(key = {"", "type"}, mandatory = false, help = "jar/file") String type) { - List<String> resources = getClient().listResources(type); - if (resources == null) { - return "No resources found"; - } - return Joiner.on("\n").skipNulls().join(resources); - } - - /** - * Gets the param. - * - * @param param the param - * @return the param - */ - @CliCommand(value = "get", help = "gets value of session parameter") - public String getParam(@CliOption(key = {"", "param"}, mandatory = true, help = "param name") String param) { - return Joiner.on("\n").skipNulls().join(getClient().getConnectionParam(param)); + @CliCommand(value = "show params", help = "Fetches and prints all session parameter from lens server") + public String showParameters() { + List<String> params = getClient().getConnectionParam(); + return Joiner.on("\n").skipNulls().join(params); } /** @@ -94,9 +85,9 @@ public class LensConnectionCommands extends BaseLensCommand implements CommandMa * @param path the path * @return the string */ - @CliCommand(value = "add jar", help = "adds a jar resource to session") + @CliCommand(value = "add jar", help = "Adds jar resource to the session") public String addJar( - @CliOption(key = {"", "param"}, mandatory = true, help = "path to jar on serverside") String path) { + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-jar-on-server-side>") String path) { APIResult result = getClient().addJarResource(path); return result.getMessage(); } @@ -107,9 +98,9 @@ public class LensConnectionCommands extends BaseLensCommand implements CommandMa * @param path the path * @return the string */ - @CliCommand(value = "remove jar", help = "removes a jar resource from session") + @CliCommand(value = "remove jar", help = "Removes a jar resource from session") public String removeJar( - @CliOption(key = {"", "param"}, mandatory = true, help = "path to jar on serverside") String path) { + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-jar-on-server-side>") String path) { APIResult result = getClient().removeJarResource(path); return result.getMessage(); } @@ -120,9 +111,9 @@ public class LensConnectionCommands extends BaseLensCommand implements CommandMa * @param path the path * @return the string */ - @CliCommand(value = "add file", help = "adds a file resource to session") + @CliCommand(value = "add file", help = "Adds a file resource to session") public String addFile( - @CliOption(key = {"", "param"}, mandatory = true, help = "path to file on serverside") String path) { + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-file-on-server-side>") String path) { APIResult result = getClient().addFileResource(path); return result.getMessage(); } @@ -135,19 +126,42 @@ public class LensConnectionCommands extends BaseLensCommand implements CommandMa */ @CliCommand(value = "remove file", help = "removes a file resource from session") public String removeFile( - @CliOption(key = {"", "param"}, mandatory = true, help = "path to file on serverside") String path) { + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-file-on-server-side>") String path) { APIResult result = getClient().removeFileResource(path); return result.getMessage(); } /** + * List resources. + * + * @return the string + */ + @CliCommand(value = "list resources", + help = "list all resources from session. If type is provided, " + + " lists resources of type <resource-type>. Valid values for type are jar and file.") + public String listResources(@CliOption(key = {"", "type"}, mandatory = false, + help = "<resource-type>") String type) { + List<String> resources = getClient().listResources(type); + if (resources == null) { + return "No resources found"; + } + return Joiner.on("\n").skipNulls().join(resources); + } + + /** * Quit shell. * * @return the exit shell request */ - @CliCommand(value = {"close"}, help = "Exits the shell") + @CliCommand(value = {"close", "bye"}, help = "Releases all resources of the server session and exits the shell") public ExitShellRequest quitShell() { - closeClientConnection(); - return ExitShellRequest.NORMAL_EXIT; + try { + closeClientConnection(); + return ExitShellRequest.NORMAL_EXIT; + } catch (ProcessingException e) { + System.out.println(e.getMessage()); + LOG.error(e); + return ExitShellRequest.FATAL_EXIT; + } } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java index 675e830..095d70d 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCubeCommands.java @@ -18,145 +18,122 @@ */ package org.apache.lens.cli.commands; -import java.io.File; -import java.io.IOException; import java.util.Date; import java.util.List; import org.apache.lens.api.APIResult; +import org.apache.lens.api.metastore.XCube; +import org.apache.lens.cli.commands.annotations.UserDocumentation; -import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.stereotype.Component; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - /** * The Class LensCubeCommands. */ @Component -public class LensCubeCommands extends BaseLensCommand implements CommandMarker { +@UserDocumentation(title = "OLAP Data cube metadata management", + description = "These commands provide CRUD for cubes") +public class LensCubeCommands extends LensCRUDCommand<XCube> { /** * Show cubes. * * @return the string */ - @CliCommand(value = "show cubes", help = "show list of cubes in database") + @CliCommand(value = "show cubes", help = "show list of cubes in current database") public String showCubes() { - List<String> cubes = getClient().getAllCubes(); - if (cubes != null) { - return Joiner.on("\n").join(cubes); - } else { - return "No Cubes found"; - } + return showAll(); } /** * Creates the cube. * - * @param cubeSpec the cube spec + * @param path the cube spec * @return the string */ - @CliCommand(value = "create cube", help = "Create a new Cube") + @CliCommand(value = "create cube", help = "Create a new Cube, taking spec from <path-to-cube-spec-file>") public String createCube( - @CliOption(key = {"", "table"}, mandatory = true, help = "<path to cube-spec file>") String cubeSpec) { - File f = new File(cubeSpec); - - if (!f.exists()) { - return "cube spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - APIResult result = getClient().createCube(cubeSpec); - - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "create cube succeeded"; - } else { - return "create cube failed"; - } + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-cube-spec-file>") String path) { + return create(path, false); } /** - * Drop cube. + * Describe cube. * - * @param cube the cube + * @param name the cube name * @return the string */ - @CliCommand(value = "drop cube", help = "drop cube") - public String dropCube( - @CliOption(key = {"", "table"}, mandatory = true, help = "cube name to be dropped") String cube) { - APIResult result = getClient().dropCube(cube); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully dropped " + cube + "!!!"; - } else { - return "Dropping cube failed"; - } + @CliCommand(value = "describe cube", help = "describe cube with name <cube-name>") + public String describeCube(@CliOption(key = {"", "name"}, mandatory = true, help = "<cube-name>") String name) { + return describe(name); } /** * Update cube. * - * @param specPair the spec pair + * @param name cube name + * @param path path to new spec file * @return the string */ - @CliCommand(value = "update cube", help = "update cube") + @CliCommand(value = "update cube", help = "update cube <cube-name> with spec from <path-to-cube-spec-file>") public String updateCube( - @CliOption(key = {"", "cube"}, mandatory = true, help = - "<cube-name> <path to cube-spec file>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " + "format. create fact <fact spec path> <storage spec path>"; - } - - File f = new File(pair[1]); - - if (!f.exists()) { - return "Fact spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - - APIResult result = getClient().updateCube(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Update of " + pair[0] + " succeeded"; - } else { - return "Update of " + pair[0] + " failed"; - } + @CliOption(key = {"", "name"}, mandatory = true, help = "<cube-name>") String name, + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-cube-spec-file>") String path) { + return update(name, path); } /** - * Describe cube. + * Drop cube. * - * @param cubeName the cube name + * @param name the cube * @return the string */ - @CliCommand(value = "describe cube", help = "describe cube") - public String describeCube(@CliOption(key = {"", "cube"}, mandatory = true, help = "<cube-name>") String cubeName) { - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getCube(cubeName))); - - } catch (IOException e) { - throw new IllegalArgumentException(e); - - } + @CliCommand(value = "drop cube", help = "drop cube <cube-name>") + public String dropCube(@CliOption(key = {"", "name"}, mandatory = true, help = "<cube-name>") String name) { + return drop(name, false); } /** - * Describe cube. + * Cube latest date * - * @param specPair <cube name, timePartition> + * @param cube cube name + * @param timeDim time dimension name * @return the string */ - @CliCommand(value = "cube latestdate", help = "cube get latest") + @CliCommand(value = "cube latestdate", + help = "get latest date of data available in cube <cube-name> for time dimension <time-dimension-name>") public String getLatest( - @CliOption(key = {"", "cube"}, mandatory = true, help = "<cube-name> <timePartition>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " + "format. cube get latest <cubeName> <timePartition>"; - } - Date dt = getClient().getLatestDateOfCube(pair[0], pair[1]); + @CliOption(key = {"", "cube"}, mandatory = true, help = "<cube-name>") String cube, + @CliOption(key = {"", "timeDimension"}, mandatory = true, help = "<time-dimension-name>") String timeDim) { + Date dt = getClient().getLatestDateOfCube(cube, timeDim); return dt == null ? "No Data Available" : formatDate(dt); } + + @Override + public List<String> getAll() { + return getClient().getAllCubes(); + } + + @Override + protected APIResult doCreate(String path, boolean ignoreIfExists) { + return getClient().createCube(path); + } + + @Override + protected APIResult doDelete(String name, boolean cascade) { + return getClient().dropCube(name); + } + + @Override + public APIResult doUpdate(String name, String path) { + return getClient().updateCube(name, path); + } + + @Override + protected XCube doRead(String name) { + return getClient().getCube(name); + } + } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java index f030d0d..800c0b5 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDatabaseCommands.java @@ -21,19 +21,18 @@ package org.apache.lens.cli.commands; import java.util.List; import org.apache.lens.api.APIResult; +import org.apache.lens.cli.commands.annotations.UserDocumentation; -import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.stereotype.Component; -import com.google.common.base.Joiner; - /** * The Class LensDatabaseCommands. */ @Component -public class LensDatabaseCommands extends BaseLensCommand implements CommandMarker { +@UserDocumentation(title = "Database management commands", description = "These commands provide CRUD for databases") +public class LensDatabaseCommands extends LensCRUDCommand { /** * Show all databases. @@ -42,12 +41,7 @@ public class LensDatabaseCommands extends BaseLensCommand implements CommandMark */ @CliCommand(value = "show databases", help = "displays list of all databases") public String showAllDatabases() { - List<String> databases = getClient().getAllDatabases(); - if (databases != null) { - return Joiner.on("\n").join(databases); - } else { - return "No Dabases found"; - } + return showAll(); } /** @@ -58,7 +52,7 @@ public class LensDatabaseCommands extends BaseLensCommand implements CommandMark */ @CliCommand(value = "use", help = "change to new database") public String switchDatabase( - @CliOption(key = {"", "db"}, mandatory = true, help = "Database to change to") String database) { + @CliOption(key = {"", "db"}, mandatory = true, help = "<database-name>") String database) { boolean status = getClient().setDatabase(database); if (status) { return "Successfully switched to " + database; @@ -70,20 +64,19 @@ public class LensDatabaseCommands extends BaseLensCommand implements CommandMark /** * Creates the database. * - * @param database the database - * @param ignore the ignore + * @param database the database + * @param ignoreIfExists the ignore * @return the string */ - @CliCommand(value = "create database", help = "create a database with specified name") + @CliCommand(value = "create database", + help = "create a database with specified name. if <ignore-if-exists> is true, " + + "create will not be tried if already exists. Default is false") public String createDatabase( - @CliOption(key = {"", "db"}, mandatory = true, help = "Database to create") String database, - @CliOption(key = {"ignore"}, mandatory = false, unspecifiedDefaultValue = "false") boolean ignore) { - APIResult result = getClient().createDatabase(database, ignore); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return ("Create database " + database + " successful"); - } else { - return result.getMessage(); - } + @CliOption(key = {"", "db"}, mandatory = true, help = "<database-name>") String database, + @CliOption(key = {"ignoreIfExists"}, mandatory = false, unspecifiedDefaultValue = "false", + help = "<ignore-if-exists>") boolean ignoreIfExists) { + // first arg is not file. LensCRUDCommand.create expects file path as first arg. So calling method directly here. + return doCreate(database, ignoreIfExists).toString().toLowerCase(); } /** @@ -94,13 +87,35 @@ public class LensDatabaseCommands extends BaseLensCommand implements CommandMark */ @CliCommand(value = "drop database", help = "drop a database with specified name") public String dropDatabase(@CliOption(key = {"", "db"}, mandatory = true, - help = "Database to drop") String database) { - APIResult result = getClient().dropDatabase(database); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return ("drop database " + database + " successful"); - } else { - return result.getMessage(); - } + help = "<database-name>") String database) { + return drop(database, false); } + @Override + public List<String> getAll() { + return getClient().getAllDatabases(); + } + + // Create is directly implemented + @Override + protected APIResult doCreate(String database, boolean ignoreIfExists) { + return getClient().createDatabase(database, ignoreIfExists); + } + + // Doesn't make sense for database + @Override + protected Object doRead(String name) { + return null; + } + + // Also, doesn't make sense + @Override + public APIResult doUpdate(String name, String path) { + return null; + } + + @Override + protected APIResult doDelete(String name, boolean cascade) { + return getClient().dropDatabase(name); + } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java index 7539ea9..dc44f80 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionCommands.java @@ -18,126 +18,113 @@ */ package org.apache.lens.cli.commands; -import java.io.File; import java.io.IOException; import java.util.List; import org.apache.lens.api.APIResult; +import org.apache.lens.api.metastore.XDimension; +import org.apache.lens.cli.commands.annotations.UserDocumentation; -import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.stereotype.Component; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - /** * The Class LensDimensionCommands. */ @Component -public class LensDimensionCommands extends BaseLensCommand implements CommandMarker { +@UserDocumentation(title = "Dimension Management", description = "These commands provide CRUD for Dimensions") +public class LensDimensionCommands extends LensCRUDCommand<XDimension> { /** * Show dimensions. * * @return the string */ - @CliCommand(value = "show dimensions", help = "show list of dimensions in database") + @CliCommand(value = "show dimensions", help = "show list of all dimensions in current database") public String showDimensions() { - List<String> dimensions = getClient().getAllDimensions(); - if (dimensions != null) { - return Joiner.on("\n").join(dimensions); - } else { - return "No Dimensions found"; - } + return showAll(); } /** * Creates the dimension. * - * @param dimensionSpec the dimension spec + * @param path the dimension spec * @return the string */ - @CliCommand(value = "create dimension", help = "Create a new Dimension") + @CliCommand(value = "create dimension", + help = "Create a new Dimension, taking spec from <path-to-dimension-spec file>") public String createDimension( - @CliOption(key = {"", "table"}, mandatory = true, help = - "<path to dimension-spec file>") String dimensionSpec) { - File f = new File(dimensionSpec); - - if (!f.exists()) { - return "dimension spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - APIResult result = getClient().createDimension(dimensionSpec); - - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "create dimension succeeded"; - } else { - return "create dimension failed"; - } + @CliOption(key = {"", "path"}, mandatory = true, help = + "<path-to-dimension-spec file>") String path) { + return create(path, false); } /** - * Drop dimension. + * Describe dimension. * - * @param dimension the dimension + * @param name the dimension name * @return the string */ - @CliCommand(value = "drop dimension", help = "drop dimension") - public String dropDimension( - @CliOption(key = {"", "table"}, mandatory = true, help = "dimension name to be dropped") String dimension) { - APIResult result = getClient().dropDimension(dimension); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully dropped " + dimension + "!!!"; - } else { - return "Dropping dimension failed"; + @CliCommand(value = "describe dimension", help = "describe dimension <dimension-name>") + public String describeDimension( + @CliOption(key = {"", "name"}, mandatory = true, help = "<dimension-name>") String name) { + try { + return formatJson(mapper.writer(pp).writeValueAsString(getClient().getDimension(name))); + } catch (IOException e) { + throw new IllegalArgumentException(e); } } /** * Update dimension. * - * @param specPair the spec pair + * @param name the dimension to be updated + * @param path path to spec fild * @return the string */ - @CliCommand(value = "update dimension", help = "update dimension") + @CliCommand(value = "update dimension", + help = "update dimension <dimension-name>, taking spec from <path-to-dimension-spec file>") public String updateDimension( - @CliOption(key = {"", "dimension"}, mandatory = true, help - = "<dimension-name> <path to dimension-spec file>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " + "format. create fact <fact spec path> <storage spec path>"; - } - - File f = new File(pair[1]); - - if (!f.exists()) { - return "Fact spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - - APIResult result = getClient().updateDimension(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Update of " + pair[0] + " succeeded"; - } else { - return "Update of " + pair[0] + " failed"; - } + @CliOption(key = {"", "name"}, mandatory = true, help = "<dimension-name>") String name, + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-dimension-spec-file>") String path) { + return update(name, path); } /** - * Describe dimension. + * Drop dimension. * - * @param dimensionName the dimension name + * @param name the dimension * @return the string */ - @CliCommand(value = "describe dimension", help = "describe dimension") - public String describeDimension( - @CliOption(key = {"", "dimension"}, mandatory = true, help = "<dimension-name>") String dimensionName) { - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getDimension(dimensionName))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } + @CliCommand(value = "drop dimension", help = "drop dimension <dimension-name>") + public String dropDimension( + @CliOption(key = {"", "name"}, mandatory = true, help = "<dimension-name>") String name) { + return drop(name, false); + } + + @Override + public List<String> getAll() { + return getClient().getAllDimensions(); + } + + @Override + protected APIResult doCreate(String path, boolean ignoreIfExists) { + return getClient().createDimension(path); + } + + @Override + protected XDimension doRead(String name) { + return getClient().getDimension(name); + } + + @Override + public APIResult doUpdate(String name, String path) { + return getClient().updateDimension(name, path); + } + + @Override + protected APIResult doDelete(String name, boolean cascade) { + return getClient().dropDimension(name); } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java index c3b7f37..d4b7418 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensDimensionTableCommands.java @@ -18,375 +18,312 @@ */ package org.apache.lens.cli.commands; -import java.io.File; -import java.io.IOException; import java.util.List; import org.apache.lens.api.APIResult; +import org.apache.lens.api.metastore.XDimensionTable; +import org.apache.lens.api.metastore.XPartition; +import org.apache.lens.api.metastore.XStorageTableElement; +import org.apache.lens.cli.commands.annotations.UserDocumentation; import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.stereotype.Component; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - /** * The Class LensDimensionTableCommands. */ @Component -public class LensDimensionTableCommands extends BaseLensCommand implements CommandMarker { +@UserDocumentation(title = "Commands for Dimension Tables", + description = "These commands provide CRUD for dimension tables, associated storages, and fact partitions") +public class LensDimensionTableCommands extends LensCRUDStoragePartitionCommand<XDimensionTable> + implements CommandMarker { /** * Show dimension tables. * * @return the string */ - @CliCommand(value = "show dimtables", help = "show list of dimension tables in database") + @CliCommand(value = "show dimtables", + help = "display list of dimtables in current database. If optional <dimension-name> is supplied," + + " only facts belonging to dimension <dimension-name> will be displayed") public String showDimensionTables( - @CliOption(key = {"", "dimension"}, mandatory = false, help = "<optional dimension name>") String dimensionName) { - List<String> dims = getClient().getAllDimensionTables(dimensionName); - if (dims != null) { - return Joiner.on("\n").join(dims); - } else { - return "No Dimensions Found"; - } + @CliOption(key = {"", "dimension-name"}, mandatory = false, help = "<dimension-name>") String dimensionName) { + return showAll(dimensionName); } /** * Creates the dimension table. * - * @param dimSpec Path to dim spec + * @param path Path to dim spec * @return the string */ - @CliCommand(value = "create dimtable", help = "Create a new dimension table") + @CliCommand(value = "create dimtable", + help = "Create a new dimension table taking spec from <path-to-dimtable-spec-file>") public String createDimensionTable( - @CliOption(key = {"", "table"}, mandatory = true, help = "<path to dim-spec>") String dimSpec) { - - File f = new File(dimSpec); - if (!f.exists()) { - return "dimtable spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - - APIResult result = getClient().createDimensionTable(dimSpec); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "create dimension table succeeded"; - } else { - return "create dimension table failed"; - } + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-dimtable-spec-file>") String path) { + return create(path, false); } /** - * Drop dimension table. + * Describe dimension table. * - * @param dim the dim - * @param cascade the cascade + * @param name the dim * @return the string */ - @CliCommand(value = "drop dimtable", help = "drop dimension table") - public String dropDimensionTable( - @CliOption(key = {"", "table"}, mandatory = true, help = "dimension table name to be dropped") String dim, - @CliOption(key = {"cascade"}, mandatory = false, unspecifiedDefaultValue = "false") boolean cascade) { - APIResult result = getClient().dropDimensionTable(dim, cascade); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully dropped " + dim + "!!!"; - } else { - return "Dropping " + dim + " table failed"; - } + @CliCommand(value = "describe dimtable", help = "describe dimtable <dimtable-name>") + public String describeDimensionTable( + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String name) { + return describe(name); } /** * Update dimension table. * - * @param specPair the spec pair + * @param name the dimtable name + * @param path the path to spec file * @return the string */ - @CliCommand(value = "update dimtable", help = "update dimension table") + @CliCommand(value = "update dimtable", + help = "update dimtable <dimtable-name> taking spec from <path-to-dimtable-spec>") public String updateDimensionTable( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<dimension-table-name> <path to table-spec>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " - + "format. create dimtable <dimtable spec path> <storage spec path>"; - } - - File f = new File(pair[1]); - - if (!f.exists()) { - return "Fact spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - - APIResult result = getClient().updateDimensionTable(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Update of " + pair[0] + " succeeded"; - } else { - return "Update of " + pair[0] + " failed"; - } + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String name, + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-dimtable-spec>") String path) { + return update(name, path); } + /** - * Describe dimension table. + * Drop dimension table. * - * @param dim the dim + * @param name the dim + * @param cascade the cascade * @return the string */ - @CliCommand(value = "describe dimtable", help = "describe a dimension table") - public String describeDimensionTable( - @CliOption(key = {"", "table"}, mandatory = true, help = "dimension table name to be described") String dim) { - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getDimensionTable(dim))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } + @CliCommand(value = "drop dimtable", + help = "drop dimtable <dimtable-name>. " + + " If <cascade> is true, all the storage tables associated with the dimtable <dimtable-name> are also dropped." + + " By default <cascade> is false") + public String dropDimensionTable( + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String name, + @CliOption(key = {"cascade"}, mandatory = false, unspecifiedDefaultValue = "false", help = "<cascade>") + boolean cascade) { + return drop(name, cascade); } /** * Gets the dim storages. * - * @param dim the dim + * @param table the dim * @return the dim storages */ - @CliCommand(value = "dimtable list storage", help = "display list of storage associated to dimension table") + @CliCommand(value = "dimtable list storages", help = "display list of storage associated to dimtable <dimtable-name>") public String getDimStorages( - @CliOption(key = {"", "table"}, mandatory = true, help = "<table-name> for listing storages") String dim) { - List<String> storages = getClient().getDimStorages(dim); - StringBuilder sb = new StringBuilder(); - if (storages != null && !storages.isEmpty()) { - for (String storage : storages) { - if (!storage.isEmpty()) { - sb.append(storage).append("\n"); - } - } - } - - if (sb.toString().isEmpty()) { - return "No storages found for " + dim; - } - return sb.toString().substring(0, sb.toString().length() - 1); + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String table) { + return showAllStorages(table); } /** - * Drop all dim storages. + * Adds the new dim storage. * - * @param table the table + * @param tableName dimtable name + * @param path path to storage spec * @return the string */ - @CliCommand(value = "dimtable drop-all storages", help = "drop all storages associated to dimension table") - public String dropAllDimStorages( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<table-name> for which all storage should be dropped") String table) { - APIResult result = getClient().dropAllStoragesOfDim(table); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "All storages of " + table + " dropped successfully"; - } else { - return "Error dropping storages of " + table; - } + @CliCommand(value = "dimtable add storage", + help = "adds a new storage to dimtable <dimtable-name>, taking storage spec from <path-to-storage-spec>") + public String addNewDimStorage( + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName, + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-storage-spec>") String path) { + return addStorage(tableName, path); } /** - * Adds the new dim storage. + * Gets the storage from dim. * - * @param tablepair the tablepair - * @return the string + * @param tableName dimtable name + * @return path storage spec path */ - @CliCommand(value = "dimtable add storage", help = "adds a new storage to dimension") - public String addNewDimStorage( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<dim-table-name> <path to storage-spec>") String tablepair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(tablepair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " - + "format. create dimtable <dimtable spec path> <storage spec path>"; - } - - File f = new File(pair[1]); - if (!f.exists()) { - return "Storage spech path " + f.getAbsolutePath() + " does not exist. Please check the path"; - } - - APIResult result = getClient().addStorageToDim(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Dim table storage addition completed"; - } else { - return "Dim table storage addition failed"; - } + @CliCommand(value = "dimtable get storage", help = "describe storage <storage-name> of dimtable <dimtable-name>") + public String getStorageFromDim( + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<storage-name>") String storage) { + return getStorage(tableName, storage); } /** * Drop storage from dim. * - * @param tablepair the tablepair + * @param tableName dimtable name + * @param storageName storage name * @return the string */ - @CliCommand(value = "dimtable drop storage", help = "drop storage to dimension table") + @CliCommand(value = "dimtable drop storage", help = "drop storage <storage-name> from dimtable <dimtable-name>") public String dropStorageFromDim( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<dimension-table-name> <storage-name>") String tablepair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(tablepair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " - + "format. create dimtable <dimtable spec path> <storage spec path>"; - } - APIResult result = getClient().dropStorageFromDim(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Dim table storage removal successful"; - } else { - return "Dim table storage removal failed"; - } + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<storage-name>") String storageName) { + return dropStorage(tableName, storageName); } /** - * Gets the storage from dim. + * Drop all dim storages. * - * @param tablepair the tablepair - * @return the storage from dim + * @param tableName the table + * @return the string */ - @CliCommand(value = "dimtable get storage", help = "describe storage of dimension table") - public String getStorageFromDim( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<dimension-table-name> <storage-name>") String tablepair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(tablepair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " - + "format. create dimtable <dimtable spec path> <storage spec path>"; - } - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getStorageFromDim(pair[0], pair[1]))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } + @CliCommand(value = "dimtable drop all storages", help = "drop all storages associated to dimension table") + public String dropAllDimStorages( + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName) { + return dropAllStorages(tableName); } /** * Gets the all partitions of dim. * - * @param specPair the spec pair + * @param tableName dimtable name + * @param storageName storage name + * @param filter partition filter * @return the all partitions of dim */ - @CliCommand(value = "dimtable list partitions", help = "get all partitions associated with dimension table") + @CliCommand(value = "dimtable list partitions", + help = "get all partitions associated with dimtable <dimtable-name>, " + + "storage <storage-name> filtered by <partition-filter>") public String getAllPartitionsOfDim( - @CliOption(key = {"", "table"}, mandatory = true, help = "<dimension-table-name> <storageName> " - + "[optional <partition query filter> to get]") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length == 2) { - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getAllPartitionsOfDim(pair[0], pair[1]))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } - } - - if (pair.length == 3) { - try { - return formatJson(mapper.writer(pp).writeValueAsString( - getClient().getAllPartitionsOfDim(pair[0], pair[1], pair[2]))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } - } - - return "Syntax error, please try in following " - + "format. dim list partitions <table> <storage> [partition values]"; + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "filter"}, mandatory = false, help = "<partition-filter>") String filter) { + return getAllPartitions(tableName, storageName, filter); } /** * Drop all partitions of dim. * - * @param specPair the spec pair + * @param tableName dimtable name + * @param storageName storage name + * @param filter partition query filter * @return the string */ - @CliCommand(value = "dimtable drop partitions", help = "drop all partitions associated with dimension table") + @CliCommand(value = "dimtable drop partitions", + help = "drop all partitions associated with dimtable " + + "<dimtable-name>, storage <storage-name> filtered by <partition-filter>") public String dropAllPartitionsOfDim( - @CliOption(key = {"", "table"}, mandatory = true, help = "<dimension-table-name> <storageName> " - + "[optional <partition query filter> to drop]") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - APIResult result; - if (pair.length == 2) { - result = getClient().dropAllPartitionsOfDim(pair[0], pair[1]); - } - if (pair.length == 3) { - result = getClient().dropAllPartitionsOfDim(pair[0], pair[1], pair[3]); - } else { - return "Syntax error, please try in following " - + "format. dimtable drop partitions <table> <storage> [partition values]"; - } - - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully dropped partition of " + pair[0]; - } else { - return "failure in dropping partition of " + pair[0]; - } - + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "filter"}, mandatory = false, help = "<partition-filter>") String filter) { + return dropPartitions(tableName, storageName, filter); } /** * Adds the partition to dim table. * - * @param specPair the spec pair + * @param tableName dimtable name + * @param storageName storage name + * @param path partition spec path * @return the string */ - @CliCommand(value = "dimtable add single-partition", help = "add a partition to dim table") - public String addPartitionToDimTable( - @CliOption(key = {"", "table"}, mandatory = true, help = "<dimension-table-name> <storage-name>" - + " <path to partition specification>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - APIResult result; - if (pair.length != 3) { - return "Syntax error, please try in following " - + "format. dimtable add single-partition <table> <storage> <partition spec>"; - } - - File f = new File(pair[2]); - if (!f.exists()) { - return "Partition spec does not exist"; - } - - result = getClient().addPartitionToDim(pair[0], pair[1], pair[2]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully added partition to " + pair[0]; - } else { - return "failure in addition of partition to " + pair[0]; - } + @CliCommand(value = "dimtable add single-partition", + help = "add single partition to dimtable <dimtable-name>'s" + + " storage <storage-name>, reading spec from <partition-spec-path>") + public String addPartitionToDimtable( + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "path"}, mandatory = true, help = "<partition-spec-path>") String path) { + return addPartition(tableName, storageName, path); } /** - * Adds partitions to dim table. + * Adds the partitions to dim table. * - * @param specPair the spec pair + * @param tableName dimtable name + * @param storageName storage name + * @param path partition spec path * @return the string */ - @CliCommand(value = "dimtable add partitions", help = "add partitions to dim table") - public String addPartitionsToDimTable( - @CliOption(key = {"", "table"}, mandatory = true, help = "<dimension-table-name> <storage-name>" - + " <path to partitions specification>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - APIResult result; - if (pair.length != 3) { - return "Syntax error, please try in following " - + "format. dimtable add partitions <table> <storage> <partition spec>"; - } - - File f = new File(pair[2]); - if (!f.exists()) { - return "Partition spec does not exist"; - } - - result = getClient().addPartitionsToDim(pair[0], pair[1], pair[2]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully added partition to " + pair[0]; - } else { - return "failure in addition of partition to " + pair[0]; - } + + @CliCommand(value = "dimtable add partitions", + help = "add multiple partition to dimtable <dimtable-name>'s" + + " storage <storage-name>, reading partition list spec from <partition-list-spec-path>") + public String addPartitionsToDimtable( + @CliOption(key = {"", "dimtable-name"}, mandatory = true, help = "<dimtable-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "path"}, mandatory = true, help = "<partition-list-spec-path>") String path) { + return addPartitions(tableName, storageName, path); + } + + @Override + protected XStorageTableElement readStorage(String tableName, String storage) { + return getClient().getStorageFromDim(tableName, storage); + } + + @Override + public APIResult doDropStorage(String tableName, String storageName) { + return getClient().dropStorageFromDim(tableName, storageName); + } + + + @Override + public List<String> getAllStorages(String name) { + return getClient().getDimStorages(name); + } + + @Override + public APIResult doAddStorage(String name, String path) { + return getClient().addStorageToDim(name, path); + } + + @Override + public APIResult doDropAllStorages(String name) { + return getClient().dropAllStoragesOfDim(name); + } + + @Override + protected List<XPartition> readAllPartitions(String tableName, String storageName, String filter) { + return getClient().getAllPartitionsOfDim(tableName, storageName, filter); + } + + @Override + protected APIResult doAddPartition(String tableName, String storageName, String path) { + return getClient().addPartitionToDim(tableName, storageName, path); + } + + @Override + protected APIResult doAddPartitions(String tableName, String storageName, String path) { + return getClient().addPartitionsToDim(tableName, storageName, path); + } + + @Override + protected APIResult doDropPartitions(String tableName, String storageName, String filter) { + return getClient().dropAllPartitionsOfDim(tableName, storageName, filter); + } + + @Override + public List<String> getAll() { + return getClient().getAllDimensionTables(); + } + + @Override + public List<String> getAll(String dimesionName) { + return getClient().getAllDimensionTables(dimesionName); + } + + @Override + protected APIResult doCreate(String path, boolean ignoreIfExists) { + return getClient().createDimensionTable(path); + } + + @Override + protected XDimensionTable doRead(String name) { + return getClient().getDimensionTable(name); + } + + @Override + public APIResult doUpdate(String name, String path) { + return getClient().updateDimensionTable(name, path); + } + + @Override + protected APIResult doDelete(String name, boolean cascade) { + return getClient().dropDimensionTable(name, cascade); } } http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/10917c25/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java ---------------------------------------------------------------------- diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java index 1e8abf9..818bd99 100644 --- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java +++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LensFactCommands.java @@ -18,352 +18,297 @@ */ package org.apache.lens.cli.commands; -import java.io.File; -import java.io.IOException; import java.util.List; import org.apache.lens.api.APIResult; +import org.apache.lens.api.metastore.XFactTable; +import org.apache.lens.api.metastore.XPartition; +import org.apache.lens.api.metastore.XStorageTableElement; +import org.apache.lens.cli.commands.annotations.UserDocumentation; -import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.stereotype.Component; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; - /** * The Class LensFactCommands. */ @Component -public class LensFactCommands extends BaseLensCommand implements CommandMarker { +@UserDocumentation(title = "Management of Facts", + description = "These command provide CRUD for facts, associated storages, and fact partitions") +public class LensFactCommands extends LensCRUDStoragePartitionCommand<XFactTable> { /** * Show facts. * * @return the string */ - @CliCommand(value = "show facts", help = "display list of fact tables in database") + @CliCommand(value = "show facts", + help = "display list of fact tables in current database. " + + "If optional <cube-name> is supplied, only facts belonging to cube <cube-name> will be displayed") public String showFacts( - @CliOption(key = {"", "cube"}, mandatory = false, help = "<optional cube name>") String cubeName) { - List<String> facts = getClient().getAllFactTables(cubeName); - if (facts != null) { - return Joiner.on("\n").join(facts); - } else { - return "No Facts Found"; - } + @CliOption(key = {"", "cube-name"}, mandatory = false, help = "<cube-name>") String cubeName) { + return showAll(cubeName); } /** * Creates the fact. * - * @param factSpecFileName Path to fact spec + * @param path Path to fact spec * @return the string */ - @CliCommand(value = "create fact", help = "create a fact table") + @CliCommand(value = "create fact", help = "create a fact table with spec from <path-to-fact-spec-file>") public String createFact( - @CliOption(key = {"", "table"}, mandatory = true, help = "<fact spec path>") String factSpecFileName) { - File f = new File(factSpecFileName); - - if (!f.exists()) { - return "Fact spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - APIResult result = getClient().createFactTable(factSpecFileName); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Fact table Successfully completed"; - } else { - return "Fact table creation failed"; - } + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-fact-spec-file>") String path) { + return create(path, false); } /** - * Drop fact. + * Describe fact table. * - * @param fact the fact - * @param cascade the cascade + * @param name the fact * @return the string */ - @CliCommand(value = "drop fact", help = "drop fact table") - public String dropFact( - @CliOption(key = {"", "table"}, mandatory = true, help = "table name to be dropped") String fact, - @CliOption(key = {"cascade"}, mandatory = false, unspecifiedDefaultValue = "false") boolean cascade) { - APIResult result = getClient().dropFactTable(fact, cascade); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully dropped " + fact + "!!!"; - } else { - return "Dropping " + fact + " table failed"; - } + @CliCommand(value = "describe fact", help = "describe fact <fact-name>") + public String describeFactTable( + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String name) { + return describe(name); } /** * Update fact table. * - * @param specPair the spec pair + * @param name fact name to be updated + * @param specPath path to the file containing new spec of the fact * @return the string */ - @CliCommand(value = "update fact", help = "update fact table") + @CliCommand(value = "update fact", help = "update fact <fact-name> taking spec from <path-to-fact-spec>") public String updateFactTable( - @CliOption(key = {"", "table"}, mandatory = true, help = "<table-name> <path to table-spec>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " + "format. create fact <fact spec path> <storage spec path>"; - } - - File f = new File(pair[1]); - - if (!f.exists()) { - return "Fact spec path" + f.getAbsolutePath() + " does not exist. Please check the path"; - } - - APIResult result = getClient().updateFactTable(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Update of " + pair[0] + " succeeded"; - } else { - return "Update of " + pair[0] + " failed"; - } + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String name, + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-fact-spec>") String specPath) { + return update(name, specPath); } /** - * Describe fact table. + * Drop fact. * - * @param fact the fact + * @param fact the fact + * @param cascade the cascade * @return the string */ - @CliCommand(value = "describe fact", help = "describe a fact table") - public String describeFactTable( - @CliOption(key = {"", "table"}, mandatory = true, help = "tablename to be described") String fact) { - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getFactTable(fact))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } + @CliCommand(value = "drop fact", + help = "drops fact <fact-name>." + + " If <cascade> is true, all the storage tables associated with the fact <fact-name> are also dropped." + + " By default <cascade> is false") + public String dropFact( + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String fact, + @CliOption(key = {"cascade"}, mandatory = false, unspecifiedDefaultValue = "false", help = "<cascade>") + boolean cascade) { + return drop(fact, cascade); } /** * Gets the fact storages. * - * @param fact the fact + * @param tableName the fact * @return the fact storages */ - @CliCommand(value = "fact list storage", help = "display list of storages associated to fact table") + @CliCommand(value = "fact list storage", help = "display list of storages associated to fact <fact-name>") public String getFactStorages( - @CliOption(key = {"", "table"}, mandatory = true, help = "tablename for getting storages") String fact) { - List<String> storages = getClient().getFactStorages(fact); - if (storages == null || storages.isEmpty()) { - return "No storages found for " + fact; - } - return Joiner.on("\n").join(storages); + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName) { + return showAllStorages(tableName); } /** - * Drop all fact storages. + * Adds the new fact storage. * - * @param table the table + * @param tableName the fact name + * @param path the path to storage spec * @return the string */ - @CliCommand(value = "fact dropall storages", help = "drop all storages associated to fact table") - public String dropAllFactStorages( - @CliOption(key = {"", "table"}, mandatory = true, help = "tablename for dropping all storages") String table) { - APIResult result = getClient().dropAllStoragesOfFact(table); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "All storages of " + table + " dropped successfully"; - } else { - return "Error dropping storages of " + table; - } + @CliCommand(value = "fact add storage", + help = "adds a new storage to fact <fact-name>, taking storage spec from <path-to-storage-spec>") + public String addNewFactStorage( + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName, + @CliOption(key = {"", "path"}, mandatory = true, help = "<path-to-storage-spec>") String path) { + return addStorage(tableName, path); } /** - * Adds the new fact storage. + * Gets the storage from fact. * - * @param tablepair the tablepair - * @return the string + * @param tableName fact table name + * @param storage storage spec path + * @return the storage from fact */ - @CliCommand(value = "fact add storage", help = "adds a new storage to fact") - public String addNewFactStorage( - @CliOption(key = {"", "table"}, mandatory = true, help = "<table> <path to storage-spec>") String tablepair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(tablepair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " + "format. fact add storage <table> <storage spec path>"; - } - - File f = new File(pair[1]); - if (!f.exists()) { - return "Storage spech path " + f.getAbsolutePath() + " does not exist. Please check the path"; - } - - APIResult result = getClient().addStorageToFact(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Fact table storage addition completed"; - } else { - return "Fact table storage addition failed"; - } + @CliCommand(value = "fact get storage", help = "describe storage <storage-name> of fact <fact-name>") + public String getStorageFromFact( + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<path-to-storage-spec>") String storage) { + return getStorage(tableName, storage); } /** * Drop storage from fact. * - * @param tablepair the tablepair + * @param tableName the table name + * @param storageName the storage name * @return the string */ - @CliCommand(value = "fact drop storage", help = "drop a storage from fact") + @CliCommand(value = "fact drop storage", help = "drop storage <storage-name> from fact <fact-name>") public String dropStorageFromFact( - @CliOption(key = {"", "table"}, mandatory = true, help = "<table-name> <storage-name>") String tablepair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(tablepair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " + "format. fact drop storage <table> <storage>"; - } - - APIResult result = getClient().dropStorageFromFact(pair[0], pair[1]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Fact table storage removal successful"; - } else { - return "Fact table storage removal failed"; - } + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName, + @CliOption(key = {"", "storage-name"}, mandatory = true, help = "<storage-name>") String storageName) { + return dropStorage(tableName, storageName); } /** - * Gets the storage from fact. + * Drop all fact storages. * - * @param tablepair the tablepair - * @return the storage from fact + * @param name the table + * @return the string */ - @CliCommand(value = "fact get storage", help = "get storage of fact table") - public String getStorageFromFact( - @CliOption(key = {"", "table"}, mandatory = true, help = "<table-name> <storage-name>") String tablepair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(tablepair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length != 2) { - return "Syntax error, please try in following " + "format. fact get storage <table> <storage>"; - } - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getStorageFromFact(pair[0], pair[1]))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } + @CliCommand(value = "fact drop all storages", help = "drop all storages associated to fact <fact-name>") + public String dropAllFactStorages( + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String name) { + return dropAllStorages(name); } /** * Gets the all partitions of fact. * - * @param specPair the spec pair + * @param tableName fact name + * @param storageName storage name + * @param filter partition filter * @return the all partitions of fact */ - @CliCommand(value = "fact list partitions", help = "get all partitions associated with fact") + @CliCommand(value = "fact list partitions", + help = "get all partitions associated with fact <fact-name>, storage <storage-name> filtered by <partition-filter>") public String getAllPartitionsOfFact( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<table-name> <storageName> [optional <partition query filter> to get]") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - if (pair.length == 2) { - try { - return formatJson(mapper.writer(pp).writeValueAsString(getClient().getAllPartitionsOfFact(pair[0], pair[1]))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } - } - if (pair.length == 3) { - try { - return formatJson(mapper.writer(pp).writeValueAsString( - getClient().getAllPartitionsOfFact(pair[0], pair[1], pair[2]))); - } catch (IOException e) { - throw new IllegalArgumentException(e); - } - } - return "Syntax error, please try in following " - + "format. fact list partitions <table> <storage> [partition values]"; + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName, + @CliOption(key = {"", "storage"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "filter"}, mandatory = false, help = "<partition-filter>") String filter) { + return getAllPartitions(tableName, storageName, filter); } /** * Drop all partitions of fact. * - * @param specPair the spec pair + * @param tableName fact name + * @param storageName storage name + * @param filter partition query filter * @return the string */ - @CliCommand(value = "fact drop partitions", help = "drop all partitions associated with fact") + @CliCommand(value = "fact drop partitions", + help = "drop all partitions associated with fact <fact-name>, " + + "storage <storage-name> filtered by <partition-filter>") public String dropAllPartitionsOfFact( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<tablename> <storageName> [optional <partition query filter> to drop]") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - APIResult result; - if (pair.length == 2) { - result = getClient().dropAllPartitionsOfFact(pair[0], pair[1]); - } else if (pair.length == 3) { - result = getClient().dropAllPartitionsOfFact(pair[0], pair[1], pair[2]); - } else { - return "Syntax error, please try in following " - + "format. fact drop partitions <table> <storage> [partition values]"; - } - - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully dropped partition of " + pair[0]; - } else { - return "failure in dropping partition of " + pair[0]; - } + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName, + @CliOption(key = {"", "storage"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "filter"}, mandatory = false, help = "<partition-filter>") String filter) { + return dropPartitions(tableName, storageName, filter); } /** * Adds the partition to fact. * - * @param specPair the spec pair + * @param tableName fact name + * @param storageName storage name + * @param path partition spec path * @return the string */ - @CliCommand(value = "fact add single-partition", help = "add a partition to fact table") + @CliCommand(value = "fact add single-partition", + help = "add single partition to fact <fact-name>'s" + + " storage <storage-name>, reading spec from <partition-spec-path>") public String addPartitionToFact( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<table> <storage> <path to partition spec>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - APIResult result; - if (pair.length != 3) { - return "Syntax error, please try in following " + "format. fact add single-partition " - + "<table> <storage> <partition spec>"; - } - - File f = new File(pair[2]); - if (!f.exists()) { - return "Partition spec does not exist"; - } - - result = getClient().addPartitionToFact(pair[0], pair[1], pair[2]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully added partition to " + pair[0]; - } else { - return "failure in addition of partition to " + pair[0]; - } + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName, + @CliOption(key = {"", "storage"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "path"}, mandatory = true, help = "<partition-spec-path>") String path) { + return addPartition(tableName, storageName, path); } - /** - * Adds the partitions to fact. - * - * @param specPair the spec pair - * @return the string - */ - @CliCommand(value = "fact add partitions", help = "add a partitions to fact table") + @CliCommand(value = "fact add partitions", + help = "add multiple partition to fact <fact-name>'s" + + " storage <storage-name>, reading partition list spec from <partition-list-spec-path>") public String addPartitionsToFact( - @CliOption(key = {"", "table"}, mandatory = true, help - = "<table> <storage> <path to partitions spec>") String specPair) { - Iterable<String> parts = Splitter.on(' ').trimResults().omitEmptyStrings().split(specPair); - String[] pair = Iterables.toArray(parts, String.class); - APIResult result; - if (pair.length != 3) { - return "Syntax error, please try in following " - + "format. fact add partitions <table> <storage> <partitions spec>"; - } - - File f = new File(pair[2]); - if (!f.exists()) { - return "Partition spec does not exist"; - } - result = getClient().addPartitionsToFact(pair[0], pair[1], pair[2]); - if (result.getStatus() == APIResult.Status.SUCCEEDED) { - return "Successfully added partition to " + pair[0]; - } else { - return "failure in addition of partition to " + pair[0]; - } + @CliOption(key = {"", "fact-name"}, mandatory = true, help = "<fact-name>") String tableName, + @CliOption(key = {"", "storage"}, mandatory = true, help = "<storage-name>") String storageName, + @CliOption(key = {"", "path"}, mandatory = true, help = "<partition-list-spec-path>") String path) { + return addPartitions(tableName, storageName, path); + } + + @Override + protected XStorageTableElement readStorage(String tableName, String storage) { + return getClient().getStorageFromFact(tableName, storage); + } + + @Override + public APIResult doDropStorage(String tableName, String storageName) { + return getClient().dropStorageFromFact(tableName, storageName); + } + + @Override + public List<String> getAllStorages(String name) { + return getClient().getFactStorages(name); + } + + @Override + public APIResult doAddStorage(String name, String path) { + return getClient().addStorageToFact(name, path); + } + + @Override + public APIResult doDropAllStorages(String name) { + return getClient().dropAllStoragesOfFact(name); + } + + @Override + protected List<XPartition> readAllPartitions(String tableName, String storageName, String filter) { + return getClient().getAllPartitionsOfFact(tableName, storageName, filter); + } + + @Override + protected APIResult doAddPartition(String tableName, String storageName, String path) { + return getClient().addPartitionToFact(tableName, storageName, path); + } + + @Override + protected APIResult doAddPartitions(String tableName, String storageName, String path) { + return getClient().addPartitionsToFact(tableName, storageName, path); + } + + @Override + protected APIResult doDropPartitions(String tableName, String storageName, String filter) { + return getClient().dropAllPartitionsOfFact(tableName, storageName, filter); + } + + @Override + public List<String> getAll() { + return getClient().getAllFactTables(); + } + + @Override + public List<String> getAll(String cubeName) { + return getClient().getAllFactTables(cubeName); + } + + @Override + protected APIResult doCreate(String path, boolean ignoreIfExists) { + return getClient().createFactTable(path); + } + + @Override + protected XFactTable doRead(String name) { + return getClient().getFactTable(name); + } + + @Override + public APIResult doUpdate(String name, String path) { + return getClient().updateFactTable(name, path); + } + + @Override + protected APIResult doDelete(String name, boolean cascade) { + return getClient().dropFactTable(name, cascade); } }
