You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by am...@apache.org on 2015/06/12 08:01:36 UTC
[2/2] incubator-lens git commit: LENS-531 : Add cli command to show
all queryable fields of cube or dimension
LENS-531 : Add cli command to show all queryable fields of cube or dimension
Project: http://git-wip-us.apache.org/repos/asf/incubator-lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-lens/commit/ff31ad96
Tree: http://git-wip-us.apache.org/repos/asf/incubator-lens/tree/ff31ad96
Diff: http://git-wip-us.apache.org/repos/asf/incubator-lens/diff/ff31ad96
Branch: refs/heads/master
Commit: ff31ad96b928850f4d549ebcde7e79f260b025e7
Parents: 7a7bdec
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Fri Jun 12 11:31:19 2015 +0530
Committer: Amareshwari Sriramadasu <am...@apache.org>
Committed: Fri Jun 12 11:31:19 2015 +0530
----------------------------------------------------------------------
lens-api/pom.xml | 5 +
lens-api/src/main/resources/cube-0.1.xsd | 611 ++++++++++---------
.../LensCRUDStoragePartitionCommand.java | 114 ----
.../lens/cli/commands/LensCubeCommands.java | 21 +-
.../cli/commands/LensDimensionCommands.java | 19 +-
.../commands/LensDimensionTableCommands.java | 2 +-
.../lens/cli/commands/LensFactCommands.java | 2 +-
.../lens/cli/commands/LensQueryCommands.java | 3 +-
.../cli/commands/LogicalTableCrudCommand.java | 31 +
.../cli/commands/PhysicalTableCrudCommand.java | 114 ++++
.../org/apache/lens/cli/skel/LensBanner.java | 5 +
.../lens/cli/skel/LensHistoryFileProvider.java | 2 +-
.../lens/cli/skel/LensPromptProvider.java | 2 +-
.../apache/lens/cli/table/CollectionTable.java | 59 ++
.../lens/cli/table/CollectionTableFactory.java | 158 +++++
.../lens/cli/table/XFlattenedColumnTable.java | 97 +++
.../apache/lens/cli/table/XJoinChainTable.java | 77 +++
.../apache/lens/cli/TestLensCubeCommands.java | 40 +-
.../lens/cli/TestLensDimensionCommands.java | 26 +-
.../apache/lens/cli/TestLensQueryCommands.java | 15 +-
.../java/org/apache/lens/client/LensClient.java | 7 +
.../apache/lens/client/LensMetadataClient.java | 35 +-
.../api/metastore/CubeMetastoreService.java | 6 +-
.../metastore/CubeMetastoreServiceImpl.java | 80 ++-
.../server/metastore/MetastoreResource.java | 36 +-
pom.xml | 7 +-
src/site/apt/user/cli.apt | 10 +-
27 files changed, 1109 insertions(+), 475 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-api/pom.xml
----------------------------------------------------------------------
diff --git a/lens-api/pom.xml b/lens-api/pom.xml
index adc464a..184f8a8 100644
--- a/lens-api/pom.xml
+++ b/lens-api/pom.xml
@@ -66,6 +66,10 @@
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.jvnet.jaxb2_commons</groupId>
+ <artifactId>jaxb2-basics-runtime</artifactId>
+ </dependency>
</dependencies>
<build>
<plugins>
@@ -85,6 +89,7 @@
<args>
<arg>-extension</arg>
<arg>-Xinheritance</arg>
+ <arg>-XtoString</arg>
</args>
<plugins>
<plugin>
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-api/src/main/resources/cube-0.1.xsd
----------------------------------------------------------------------
diff --git a/lens-api/src/main/resources/cube-0.1.xsd b/lens-api/src/main/resources/cube-0.1.xsd
index 719d10d..2ae606f 100644
--- a/lens-api/src/main/resources/cube-0.1.xsd
+++ b/lens-api/src/main/resources/cube-0.1.xsd
@@ -18,18 +18,53 @@
under the License.
-->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified"
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
+ attributeFormDefault="unqualified" elementFormDefault="qualified"
targetNamespace="uri:lens:cube:0.1" xmlns="uri:lens:cube:0.1" xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
jaxb:version="2.1">
+
<xs:annotation>
<xs:appinfo>
<jaxb:schemaBindings>
- <jaxb:package name="org.apache.lens.api.metastore" />
+ <jaxb:package name="org.apache.lens.api.metastore"/>
</jaxb:schemaBindings>
</xs:appinfo>
</xs:annotation>
- <xs:element name="x_cube" abstract="true" type="x_cube" />
+ <xs:element name="x_field" abstract="true" type="x_field"/>
+
+ <xs:complexType name="x_field" abstract="true">
+ <xs:annotation>
+ <xs:documentation>
+ some documentation
+ </xs:documentation>
+ </xs:annotation>
+ <xs:attribute type="xs:string" name="name" use="required"/>
+ <xs:attribute type="xs:string" name="display_string">
+ <xs:annotation>
+ <xs:documentation>
+ Display string that should be shown to end users. Can be space separated. It gives UI systems
+ built on top to use this value to show the field to end user.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="description"/>
+ </xs:complexType>
+
+ <xs:element name="x_fields" type="x_fields"/>
+
+ <xs:complexType name="x_fields">
+ <xs:annotation>
+ <xs:documentation>
+ Set of fields.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:sequence>
+ <xs:element type="x_field" name="fields" maxOccurs="unbounded" minOccurs="1"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:element name="x_cube" abstract="true" type="x_cube"/>
<xs:complexType name="x_cube" abstract="true">
<xs:annotation>
@@ -65,44 +100,44 @@
Additional properties:
1. cube.timedim.relation.{time_dim1}: time_dim2+[timediff1,timediff2]. It's assumed that
- timediff1 is smaller than timediff2. Means that time_dim1 can be expected to be between
- [time_dim2+timediff1 and time_dim2+timediff2]. One use case would be the following:
+ timediff1 is smaller than timediff2. Means that time_dim1 can be expected to be between
+ [time_dim2+timediff1 and time_dim2+timediff2]. One use case would be the following:
- 1.1. if a query is on range of time_dim1 and
- time_dim1 has no partitioning column in some fact, then partitions for time_dim2 can be looked at.
- Let's say time_dim2's part col is part_col2, then for a query asking for time_dim1 between [a,b) can
- be answered by looking at partitions of part_col2 in range [a-timediff2, b-timediff1).
+ 1.1. if a query is on range of time_dim1 and
+ time_dim1 has no partitioning column in some fact, then partitions for time_dim2 can be looked at.
+ Let's say time_dim2's part col is part_col2, then for a query asking for time_dim1 between [a,b) can
+ be answered by looking at partitions of part_col2 in range [a-timediff2, b-timediff1).
- This property is first looked into fact properties, then cube properties and if that's a derived cube,
- then next in base cube properties. Wherever found first, that will be considered as the final relation
- between time dimensions.
+ This property is first looked into fact properties, then cube properties and if that's a derived cube,
+ then next in base cube properties. Wherever found first, that will be considered as the final relation
+ between time dimensions.
- Time dimension relations are transitive, but not reversible. i.e.
- cube.timedim.relation.time_dim1 = time_dim2 + [a, b]
- cube.timedim.relation.time_dim2 = time_dim3 + [c, d]
+ Time dimension relations are transitive, but not reversible. i.e.
+ cube.timedim.relation.time_dim1 = time_dim2 + [a, b]
+ cube.timedim.relation.time_dim2 = time_dim3 + [c, d]
- implies:
+ implies:
- cube.timedim.relation.time_dim1 = time_dim3 + [a+c, b+d]
+ cube.timedim.relation.time_dim1 = time_dim3 + [a+c, b+d]
- but not:
+ but not:
- cube.timedim.relation.time_dim2 = time_dim1 + [-b, -a]
+ cube.timedim.relation.time_dim2 = time_dim1 + [-b, -a]
- Reverse relations have to be defined explicitly.
+ Reverse relations have to be defined explicitly.
- Timediff syntax is sign, quantity and unit. Spaces in between can be present. e.g. -4 days, +4days, +4 day
- etc all are valid.
+ Timediff syntax is sign, quantity and unit. Spaces in between can be present. e.g. -4 days, +4days, +4 day
+ etc all are valid.
</xs:documentation>
</xs:annotation>
</xs:element>
</xs:sequence>
- <xs:attribute type="xs:string" name="name" use="required" />
- <xs:attribute type="xs:string" name="description" />
+ <xs:attribute type="xs:string" name="name" use="required"/>
+ <xs:attribute type="xs:string" name="description"/>
</xs:complexType>
- <xs:element name="x_base_cube" type="x_base_cube" />
+ <xs:element name="x_base_cube" type="x_base_cube"/>
<xs:complexType name="x_base_cube">
<xs:annotation>
<xs:documentation>
@@ -113,16 +148,16 @@
<xs:complexContent>
<xs:extension base="x_cube">
<xs:sequence>
- <xs:element type="x_measures" name="measures" maxOccurs="1" minOccurs="1" />
- <xs:element type="x_dim_attributes" name="dim_attributes" maxOccurs="1" minOccurs="0" />
- <xs:element type="x_expressions" name="expressions" maxOccurs="1" minOccurs="0" />
- <xs:element type="x_join_chains" name="join_chains" maxOccurs="1" minOccurs="0" />
+ <xs:element type="x_measures" name="measures" maxOccurs="1" minOccurs="1"/>
+ <xs:element type="x_dim_attributes" name="dim_attributes" maxOccurs="1" minOccurs="0"/>
+ <xs:element type="x_expressions" name="expressions" maxOccurs="1" minOccurs="0"/>
+ <xs:element type="x_join_chains" name="join_chains" maxOccurs="1" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
- <xs:element name="x_derived_cube" type="x_derived_cube" />
+ <xs:element name="x_derived_cube" type="x_derived_cube"/>
<xs:complexType name="x_derived_cube">
<xs:annotation>
<xs:documentation>
@@ -134,10 +169,10 @@
<xs:complexContent>
<xs:extension base="x_cube">
<xs:sequence>
- <xs:element type="x_measure_names" name="measure_names" maxOccurs="1" minOccurs="0" />
- <xs:element type="x_dim_attr_names" name="dim_attr_names" maxOccurs="1" minOccurs="0" />
+ <xs:element type="x_measure_names" name="measure_names" maxOccurs="1" minOccurs="0"/>
+ <xs:element type="x_dim_attr_names" name="dim_attr_names" maxOccurs="1" minOccurs="0"/>
</xs:sequence>
- <xs:attribute type="xs:string" name="parent" use="required" />
+ <xs:attribute type="xs:string" name="parent" use="required"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
@@ -151,13 +186,13 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element type="x_dim_attributes" name="attributes" maxOccurs="1" minOccurs="0" />
- <xs:element type="x_expressions" name="expressions" maxOccurs="1" minOccurs="0" />
- <xs:element type="x_join_chains" name="join_chains" maxOccurs="1" minOccurs="0" />
- <xs:element type="x_properties" name="properties" maxOccurs="1" minOccurs="0" />
+ <xs:element type="x_dim_attributes" name="attributes" maxOccurs="1" minOccurs="0"/>
+ <xs:element type="x_expressions" name="expressions" maxOccurs="1" minOccurs="0"/>
+ <xs:element type="x_join_chains" name="join_chains" maxOccurs="1" minOccurs="0"/>
+ <xs:element type="x_properties" name="properties" maxOccurs="1" minOccurs="0"/>
</xs:sequence>
- <xs:attribute type="xs:string" name="name" use="required" />
- <xs:attribute type="xs:string" name="description" />
+ <xs:attribute type="xs:string" name="name" use="required"/>
+ <xs:attribute type="xs:string" name="description"/>
</xs:complexType>
<xs:complexType name="x_property">
@@ -166,8 +201,8 @@
A key-value pair for storing property's name and its value.
</xs:documentation>
</xs:annotation>
- <xs:attribute type="xs:string" name="name" use="required" />
- <xs:attribute type="xs:string" name="value" use="required" />
+ <xs:attribute type="xs:string" name="name" use="required"/>
+ <xs:attribute type="xs:string" name="value" use="required"/>
</xs:complexType>
<xs:complexType name="x_properties">
@@ -187,72 +222,68 @@
A cube measure.
</xs:documentation>
</xs:annotation>
- <xs:attribute type="xs:string" name="name" use="required" />
- <xs:attribute type="x_measure_type" name="type" use="required" />
- <xs:attribute type="xs:string" name="description" />
- <xs:attribute type="xs:string" name="display_string">
- <xs:annotation>
- <xs:documentation>
- Display string that should be shown to end users. Can be comma separated. It gives UI systems
- built on top to use this value to show the field to end user.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="default_aggr">
- <xs:annotation>
- <xs:documentation>
- The aggregate for the measure that is used to rollup in aggregated facts.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="format_string">
- <xs:annotation>
- <xs:documentation>
- The string format that can should be used to format the number shown to user. For example:
- formatting with respect to precision upto 3 decimals, can be specified as
- format_number(%s,"##################.###")
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:dateTime" name="start_time">
- <xs:annotation>
- <xs:documentation>
- The start time from when the measure is available for querying
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:dateTime" name="end_time">
- <xs:annotation>
- <xs:documentation>
- The end time till when the measure is available for querying
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="unit">
- <xs:annotation>
- <xs:documentation>
- Specify the unit of the measure. For example, currency in dollars or rupees.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:double" name="min">
- <xs:annotation>
- <xs:documentation>
- The minimum value the measure can take. This is only indicative value for user to know what
- vaues it can take. Lens does not do any validation based on this value.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:double" name="max">
- <xs:annotation>
- <xs:documentation>
- The maximum value the measure can take. This is only indicative value for user to know what
- vaues it can take. Lens does not do any validation based on this value.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
+ <xs:complexContent>
+ <xs:extension base="x_field">
+ <xs:attribute type="x_measure_type" name="type" use="required"/>
+ <xs:attribute type="xs:string" name="default_aggr">
+ <xs:annotation>
+ <xs:documentation>
+ The aggregate for the measure that is used to rollup in aggregated facts.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="format_string">
+ <xs:annotation>
+ <xs:documentation>
+ The string format that can should be used to format the number shown to user. For example:
+ formatting with respect to precision upto 3 decimals, can be specified as
+ format_number(%s,"##################.###")
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:dateTime" name="start_time">
+ <xs:annotation>
+ <xs:documentation>
+ The start time from when the measure is available for querying
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:dateTime" name="end_time">
+ <xs:annotation>
+ <xs:documentation>
+ The end time till when the measure is available for querying
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:string" name="unit">
+ <xs:annotation>
+ <xs:documentation>
+ Specify the unit of the measure. For example, currency in dollars or rupees.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:double" name="min">
+ <xs:annotation>
+ <xs:documentation>
+ The minimum value the measure can take. This is only indicative value for user to know what
+ vaues it can take. Lens does not do any validation based on this value.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:double" name="max">
+ <xs:annotation>
+ <xs:documentation>
+ The maximum value the measure can take. This is only indicative value for user to know what
+ vaues it can take. Lens does not do any validation based on this value.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
</xs:complexType>
+ <xs:element name="x_measures" type="x_measures"/>
+
<xs:complexType name="x_measures">
<xs:annotation>
<xs:documentation>
@@ -281,35 +312,29 @@
An expression column
</xs:documentation>
</xs:annotation>
- <xs:sequence>
- <xs:annotation>
- <xs:documentation>
- All the expressions associated with expression column.
- </xs:documentation>
- </xs:annotation>
- <xs:element type="x_expr_spec" name="expr_spec" maxOccurs="unbounded" minOccurs="1"/>
- </xs:sequence>
- <xs:attribute type="xs:string" name="name" use="required" />
- <xs:attribute type="xs:string" name="type" use="required">
- <xs:annotation>
- <xs:documentation>
- The type indicating what the evaluation of expression will produce. Allowed types are BOOLEAN, TINYINT,
- SMALLINT, INT, BIGINT, FLOAT, DOUBLE, DECIMAL, STRING, CHAR, VARCHAR, DATE, TIMESTAMP, BINARY, ARRAY, MAP,
- STRUCT, UNION
- See hive represenation for specifying complex types -
- https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-ComplexTypes
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="description" />
- <xs:attribute type="xs:string" name="display_string">
- <xs:annotation>
- <xs:documentation>
- Display string that should be shown to end users. Can be comma separated. It gives UI systems
- built on top to use this value to show the field to end user.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
+ <xs:complexContent>
+ <xs:extension base="x_field">
+ <xs:sequence>
+ <xs:annotation>
+ <xs:documentation>
+ All the expressions associated with expression column.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:element type="x_expr_spec" name="expr_spec" maxOccurs="unbounded" minOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="type" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The type indicating what the evaluation of expression will produce. Allowed types are BOOLEAN, TINYINT,
+ SMALLINT, INT, BIGINT, FLOAT, DOUBLE, DECIMAL, STRING, CHAR, VARCHAR, DATE, TIMESTAMP, BINARY, ARRAY, MAP,
+ STRUCT, UNION
+ See hive represenation for specifying complex types -
+ https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-ComplexTypes
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
</xs:complexType>
<xs:complexType name="x_expr_spec">
@@ -345,6 +370,8 @@
</xs:attribute>
</xs:complexType>
+ <xs:element name="x_expressions" type="x_expressions"/>
+
<xs:complexType name="x_expressions">
<xs:annotation>
<xs:documentation>
@@ -362,81 +389,78 @@
A dim attribute.
</xs:documentation>
</xs:annotation>
- <xs:sequence>
- <xs:element name="ref_spec" maxOccurs="1" minOccurs="0">
- <xs:annotation>
- <xs:documentation>
- Reference specifiction needs to be specified if the attribute is a reference attribute. It
- can either be table reference or a chained column
-
- ref_spec can be specified as a list of table references to
- which the attribute is refering to.
- For ex : userid refers user.id, xuser.id, yuser.id, zuser.id.
-
- Alternately, ref_spec could be a chained column specifed with chain name and column name.
- </xs:documentation>
- </xs:annotation>
- <xs:complexType>
- <xs:choice maxOccurs="1" minOccurs="1">
- <xs:element type="x_table_references" name="table_references" maxOccurs="1" minOccurs="1" />
- <xs:element type="x_chain_column" name="chain_ref_column" maxOccurs="1" minOccurs="1" />
- </xs:choice>
- </xs:complexType>
- </xs:element>
- </xs:sequence>
- <xs:attribute type="xs:string" name="name" use="required" />
- <xs:attribute type="xs:string" name="type" use="required">
- <xs:annotation>
- <xs:documentation>
- The type indicating what the evaluation of expression will produce. Allowed types are BOOLEAN,TINYINT,
- SMALLINT, INT, BIGINT, FLOAT, DOUBLE, DECIMAL, STRING, CHAR, VARCHAR, DATE, TIMESTAMP, BINARY, ARRAY, MAP,
- STRUCT, UNION
- See hive represenation for specifying complex types -
- https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-ComplexTypes
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:string" name="description" />
- <xs:attribute type="xs:string" name="display_string">
- <xs:annotation>
- <xs:documentation>
- Display string that should be shown to end users. Can be comma separated. It gives UI systems
- built on top to use this value to show the field to end user.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:dateTime" name="start_time">
- <xs:annotation>
- <xs:documentation>
- The start time from when the attribute is available for querying.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:dateTime" name="end_time">
- <xs:annotation>
- <xs:documentation>
- The end time till when the attribute is available for querying.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:long" name="num_distinct_values" use="optional">
- <xs:annotation>
- <xs:documentation>
- Specifies an indicative value of how many distinct values the dim attribute can take.
- This would give an idea of how big the grouping will be when an attribute is chosen for groupby expressions.
- This is just an approximate value.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
- <xs:attribute type="xs:boolean" name="join_key" default="false">
- <xs:annotation>
- <xs:documentation>
- This flag will tell whether the attribute can be used as a join key or not
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
+ <xs:complexContent>
+ <xs:extension base="x_field">
+ <xs:sequence>
+ <xs:element name="ref_spec" maxOccurs="1" minOccurs="0">
+ <xs:annotation>
+ <xs:documentation>
+ Reference specifiction needs to be specified if the attribute is a reference attribute. It
+ can either be table reference or a chained column
+
+ ref_spec can be specified as a list of table references to
+ which the attribute is refering to.
+ For ex : userid refers user.id, xuser.id, yuser.id, zuser.id.
+
+ Alternately, ref_spec could be a chained column specifed with chain name and column name.
+ </xs:documentation>
+ </xs:annotation>
+ <xs:complexType>
+ <xs:choice maxOccurs="1" minOccurs="1">
+ <xs:element type="x_table_references" name="table_references" maxOccurs="1" minOccurs="1"/>
+ <xs:element type="x_chain_column" name="chain_ref_column" maxOccurs="1" minOccurs="1"/>
+ </xs:choice>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="type" use="required">
+ <xs:annotation>
+ <xs:documentation>
+ The type indicating what the evaluation of expression will produce. Allowed types are BOOLEAN,TINYINT,
+ SMALLINT, INT, BIGINT, FLOAT, DOUBLE, DECIMAL, STRING, CHAR, VARCHAR, DATE, TIMESTAMP, BINARY, ARRAY, MAP,
+ STRUCT, UNION
+ See hive represenation for specifying complex types -
+ https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-ComplexTypes
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:dateTime" name="start_time">
+ <xs:annotation>
+ <xs:documentation>
+ The start time from when the attribute is available for querying.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:dateTime" name="end_time">
+ <xs:annotation>
+ <xs:documentation>
+ The end time till when the attribute is available for querying.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:long" name="num_distinct_values" use="optional">
+ <xs:annotation>
+ <xs:documentation>
+ Specifies an indicative value of how many distinct values the dim attribute can take.
+ This would give an idea of how big the grouping will be when an attribute is chosen for groupby
+ expressions.
+ This is just an approximate value.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ <xs:attribute type="xs:boolean" name="join_key" default="false">
+ <xs:annotation>
+ <xs:documentation>
+ This flag will tell whether the attribute can be used as a join key or not
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
</xs:complexType>
+ <xs:element name="x_dim_attributes" type="x_dim_attributes"/>
+
<xs:complexType name="x_dim_attributes">
<xs:annotation>
<xs:documentation>
@@ -460,8 +484,8 @@
</xs:complexType>
<xs:complexType name="x_chain_column">
- <xs:attribute type="xs:string" name="chain_name" use="required" />
- <xs:attribute type="xs:string" name="ref_col" use="required" />
+ <xs:attribute type="xs:string" name="chain_name" use="required"/>
+ <xs:attribute type="xs:string" name="ref_col" use="required"/>
<xs:attribute type="xs:string" name="dest_table">
<xs:annotation>
<xs:documentation>
@@ -472,8 +496,8 @@
</xs:complexType>
<xs:complexType name="x_table_reference">
- <xs:attribute type="xs:string" name="table" use="required" />
- <xs:attribute type="xs:string" name="column" use="required" />
+ <xs:attribute type="xs:string" name="table" use="required"/>
+ <xs:attribute type="xs:string" name="column" use="required"/>
</xs:complexType>
<xs:complexType name="x_table_references">
@@ -487,6 +511,8 @@
</xs:sequence>
</xs:complexType>
+ <xs:element name="x_join_chains" type="x_join_chains"/>
+
<xs:complexType name="x_join_chains">
<xs:annotation>
<xs:documentation>
@@ -513,19 +539,20 @@
SalesCube.productionStateid -> State.id, State.countryid ->Country.id will be named differently.
</xs:documentation>
</xs:annotation>
- <xs:sequence>
- <xs:element type="x_join_paths" name="paths" maxOccurs="1" minOccurs="1" />
- </xs:sequence>
- <xs:attribute type="xs:string" name="name" use="required" />
- <xs:attribute type="xs:string" name="description" />
- <xs:attribute type="xs:string" name="display_string" />
- <xs:attribute type="xs:string" name="dest_table">
- <xs:annotation>
- <xs:documentation>
- This will be the destination table of the chain. LENS will set and return, need not be set by end-user.
- </xs:documentation>
- </xs:annotation>
- </xs:attribute>
+ <xs:complexContent>
+ <xs:extension base="x_field">
+ <xs:sequence>
+ <xs:element type="x_join_paths" name="paths" maxOccurs="1" minOccurs="1"/>
+ </xs:sequence>
+ <xs:attribute type="xs:string" name="dest_table">
+ <xs:annotation>
+ <xs:documentation>
+ This will be the destination table of the chain. LENS will set and return, need not be set by end-user.
+ </xs:documentation>
+ </xs:annotation>
+ </xs:attribute>
+ </xs:extension>
+ </xs:complexContent>
</xs:complexType>
<xs:complexType name="x_join_path">
@@ -535,7 +562,7 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element type="x_join_edges" name="edges" maxOccurs="1" minOccurs="1" />
+ <xs:element type="x_join_edges" name="edges" maxOccurs="1" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
@@ -557,8 +584,8 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element type="x_table_reference" name="from" maxOccurs="1" minOccurs="1" />
- <xs:element type="x_table_reference" name="to" maxOccurs="1" minOccurs="1" />
+ <xs:element type="x_table_reference" name="from" maxOccurs="1" minOccurs="1"/>
+ <xs:element type="x_table_reference" name="to" maxOccurs="1" minOccurs="1"/>
</xs:sequence>
</xs:complexType>
@@ -596,10 +623,10 @@
<xs:annotation>
<xs:documentation>
Dimension table properties. The properties that should be set are:
- 1. dimtable.{dim_table_name}.part.cols = comma separated list of partition columns of this dimtable.
- This would basically be union of all partition columns of all storage tables of the dimtable.
- Setting this makes that partition column queryable.
- Time part columns can be skipped as they will generally not be queried.
+ 1. dimtable.{dim_table_name}.part.cols = comma separated list of partition columns of this dimtable.
+ This would basically be union of all partition columns of all storage tables of the dimtable.
+ Setting this makes that partition column queryable.
+ Time part columns can be skipped as they will generally not be queried.
</xs:documentation>
</xs:annotation>
</xs:element>
@@ -659,7 +686,7 @@
Column in table.
</xs:documentation>
</xs:annotation>
- <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute type="xs:string" name="type" use="required">
<xs:annotation>
<xs:documentation>
@@ -670,8 +697,8 @@
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+Types#LanguageManualTypes-ComplexTypes
</xs:documentation>
</xs:annotation>
- </xs:attribute>
- <xs:attribute name="comment" type="xs:string" />
+ </xs:attribute>
+ <xs:attribute name="comment" type="xs:string"/>
</xs:complexType>
<xs:simpleType name="x_measure_type">
@@ -681,13 +708,13 @@
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
- <xs:enumeration value="TINYINT" />
- <xs:enumeration value="SMALLINT" />
- <xs:enumeration value="INT" />
- <xs:enumeration value="BIGINT" />
- <xs:enumeration value="FLOAT" />
- <xs:enumeration value="DOUBLE" />
- <xs:enumeration value="DECIMAL" />
+ <xs:enumeration value="TINYINT"/>
+ <xs:enumeration value="SMALLINT"/>
+ <xs:enumeration value="INT"/>
+ <xs:enumeration value="BIGINT"/>
+ <xs:enumeration value="FLOAT"/>
+ <xs:enumeration value="DOUBLE"/>
+ <xs:enumeration value="DECIMAL"/>
</xs:restriction>
</xs:simpleType>
@@ -698,18 +725,18 @@
</xs:documentation>
</xs:annotation>
<xs:restriction base="xs:string">
- <xs:enumeration value="SECONDLY" />
- <xs:enumeration value="MINUTELY" />
- <xs:enumeration value="HOURLY" />
- <xs:enumeration value="DAILY" />
- <xs:enumeration value="WEEKLY" />
- <xs:enumeration value="MONTHLY" />
- <xs:enumeration value="QUARTERLY" />
- <xs:enumeration value="YEARLY" />
+ <xs:enumeration value="SECONDLY"/>
+ <xs:enumeration value="MINUTELY"/>
+ <xs:enumeration value="HOURLY"/>
+ <xs:enumeration value="DAILY"/>
+ <xs:enumeration value="WEEKLY"/>
+ <xs:enumeration value="MONTHLY"/>
+ <xs:enumeration value="QUARTERLY"/>
+ <xs:enumeration value="YEARLY"/>
</xs:restriction>
</xs:simpleType>
- <xs:element name="x_storage" type="x_storage" />
+ <xs:element name="x_storage" type="x_storage"/>
<xs:complexType name="x_storage">
<xs:annotation>
<xs:documentation>
@@ -725,7 +752,7 @@
</xs:annotation>
</xs:element>
</xs:sequence>
- <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="name" type="xs:string" use="required"/>
<xs:attribute name="classname" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>
@@ -738,7 +765,7 @@
</xs:attribute>
</xs:complexType>
- <xs:element name="x_storage_table_desc" type="x_storage_table_desc" />
+ <xs:element name="x_storage_table_desc" type="x_storage_table_desc"/>
<xs:complexType name="x_storage_table_desc">
<xs:annotation>
<xs:documentation>
@@ -907,9 +934,9 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="col_names" type="xs:string" maxOccurs="unbounded" minOccurs="0" />
- <xs:element name="col_values" type="x_skew_col_list" maxOccurs="unbounded" minOccurs="0" />
- <xs:element name="value_location_map" type="x_skewed_value_location" maxOccurs="unbounded" minOccurs="0" />
+ <xs:element name="col_names" type="xs:string" maxOccurs="unbounded" minOccurs="0"/>
+ <xs:element name="col_values" type="x_skew_col_list" maxOccurs="unbounded" minOccurs="0"/>
+ <xs:element name="value_location_map" type="x_skewed_value_location" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
@@ -920,7 +947,7 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="elements" type="xs:string" maxOccurs="unbounded" minOccurs="0" />
+ <xs:element name="elements" type="xs:string" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
@@ -931,12 +958,12 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="value" type="x_skew_col_list" minOccurs="1" maxOccurs="1" />
+ <xs:element name="value" type="x_skew_col_list" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
- <xs:attribute type="xs:string" name="location" use="required" />
+ <xs:attribute type="xs:string" name="location" use="required"/>
</xs:complexType>
- <xs:element name="x_storage_table_element" type="x_storage_table_element" />
+ <xs:element name="x_storage_table_element" type="x_storage_table_element"/>
<xs:complexType name="x_storage_table_element">
<xs:annotation>
@@ -945,9 +972,9 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="update_periods" type="x_update_periods" maxOccurs="1" minOccurs="0" />
- <xs:element name="storage_name" type="xs:string" />
- <xs:element type="x_storage_table_desc" name="table_desc" />
+ <xs:element name="update_periods" type="x_update_periods" maxOccurs="1" minOccurs="0"/>
+ <xs:element name="storage_name" type="xs:string"/>
+ <xs:element type="x_storage_table_desc" name="table_desc"/>
</xs:sequence>
</xs:complexType>
@@ -958,11 +985,11 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="storage_table" minOccurs="1" maxOccurs="unbounded" type="x_storage_table_element" />
+ <xs:element name="storage_table" minOccurs="1" maxOccurs="unbounded" type="x_storage_table_element"/>
</xs:sequence>
</xs:complexType>
- <xs:element name="x_partition_list" type="x_partition_list" />
+ <xs:element name="x_partition_list" type="x_partition_list"/>
<xs:complexType name="x_partition_list">
<xs:annotation>
<xs:documentation>
@@ -970,11 +997,11 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="partition" type="x_partition" maxOccurs="unbounded" minOccurs="0" />
+ <xs:element name="partition" type="x_partition" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
- <xs:element name="x_partition" type="x_partition" />
+ <xs:element name="x_partition" type="x_partition"/>
<xs:complexType name="x_partition">
<xs:annotation>
@@ -983,21 +1010,21 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="non_time_partition_spec" maxOccurs="1" minOccurs="0" type ="x_part_spec" >
+ <xs:element name="non_time_partition_spec" maxOccurs="1" minOccurs="0" type="x_part_spec">
<xs:annotation>
<xs:documentation>
Non time partition specification with partition columns and values.
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="time_partition_spec" maxOccurs="1" minOccurs="0" type = "x_time_part_spec" >
+ <xs:element name="time_partition_spec" maxOccurs="1" minOccurs="0" type="x_time_part_spec">
<xs:annotation>
<xs:documentation>
Time partition specification with partition columns and date values.
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="full_partition_spec" maxOccurs="1" minOccurs="0" type ="x_part_spec" >
+ <xs:element name="full_partition_spec" maxOccurs="1" minOccurs="0" type="x_part_spec">
<xs:annotation>
<xs:documentation>
LENS would use this type to retun the specification elements. Should not be used directly by end-user.
@@ -1078,8 +1105,8 @@
Partition column name and its value.
</xs:documentation>
</xs:annotation>
- <xs:attribute type="xs:string" name="key" use="required" />
- <xs:attribute type="xs:string" name="value" use="required" />
+ <xs:attribute type="xs:string" name="key" use="required"/>
+ <xs:attribute type="xs:string" name="value" use="required"/>
</xs:complexType>
<xs:complexType name="x_part_spec">
@@ -1094,8 +1121,8 @@
Time partition column name and its value as date-time.
</xs:documentation>
</xs:annotation>
- <xs:attribute type="xs:string" name="key" use="required" />
- <xs:attribute type="xs:dateTime" name="value" use="required" />
+ <xs:attribute type="xs:string" name="key" use="required"/>
+ <xs:attribute type="xs:dateTime" name="value" use="required"/>
</xs:complexType>
<xs:complexType name="x_time_part_spec">
@@ -1104,7 +1131,7 @@
</xs:sequence>
</xs:complexType>
- <xs:element name="x_fact_table" type="x_fact_table" />
+ <xs:element name="x_fact_table" type="x_fact_table"/>
<xs:complexType name="x_fact_table">
<xs:annotation>
@@ -1127,26 +1154,26 @@
Properties that can be set for a fact are
1. cube.fact.{fact-name}.valid.columns.size : This should be set to number of
- cube.fact.{fact-name}.valid.columns strings.
+ cube.fact.{fact-name}.valid.columns strings.
2. cube.fact.{fact-name}.valid.columns{i} : This should be set to comma separated column names which are
- valid in the fact, such that 0 <= i < cube.fact.{fact-name}.valid.columns.size and each of
- cube.fact.{fact-name}.valid.columns{i} has maximum length of 3999.
+ valid in the fact, such that 0 <= i < cube.fact.{fact-name}.valid.columns.size and each of
+ cube.fact.{fact-name}.valid.columns{i} has maximum length of 3999.
3. cube.fact.is.aggregated : Defaults to true. If the fact is a raw fact, this should be set to false,
- otherwise true.
+ otherwise true.
4. cube.timedim.relation.{time_dim1}: See the same property in cube. Fact tables can override the property.
5. cube.fact.absolute.start.time: start time of the fact. For queries that ask for time before this,
- this fact is not a candidate. Time format can be as you would specify in the time_range_in clause.
- i.e. yyyy[-mm[-dd[-hh[:MM[:ss[,SSS]]]]]]
+ this fact is not a candidate. Time format can be as you would specify in the time_range_in clause.
+ i.e. yyyy[-mm[-dd[-hh[:MM[:ss[,SSS]]]]]]
6. cube.fact.relative.start.time: Here you can specify fact's relative validity relative to current time.
- Useful if you want to specify e.g. this fact is valid for today - 90 days. Can be specified as just
- a time difference e.g. "-90 days". Or can be specified in relative syntax.
- e.g. now.year or now.day - 6 hour etc.
+ Useful if you want to specify e.g. this fact is valid for today - 90 days. Can be specified as just
+ a time difference e.g. "-90 days". Or can be specified in relative syntax.
+ e.g. now.year or now.day - 6 hour etc.
7. cube.fact.absolute.end.time: If you're deprecating this fact, put the final date till which the data of
- the fact will be valid here. Format same as absolute start time.
+ the fact will be valid here. Format same as absolute start time.
</xs:documentation>
</xs:annotation>
</xs:element>
- <xs:element name="storage_tables" type = "x_storage_tables" maxOccurs="1" minOccurs="0"/>
+ <xs:element name="storage_tables" type="x_storage_tables" maxOccurs="1" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string" use="required">
<xs:annotation>
@@ -1177,7 +1204,7 @@
</xs:attribute>
</xs:complexType>
- <xs:element name="x_native_table" type="x_native_table" />
+ <xs:element name="x_native_table" type="x_native_table"/>
<xs:complexType name="x_native_table">
<xs:annotation>
<xs:documentation>
@@ -1246,7 +1273,7 @@
</xs:attribute>
</xs:complexType>
- <xs:element name="x_flattened_columns" type="x_flattened_columns" />
+ <xs:element name="x_flattened_columns" type="x_flattened_columns"/>
<xs:complexType name="x_flattened_columns">
<xs:annotation>
<xs:documentation>
@@ -1255,16 +1282,16 @@
</xs:documentation>
</xs:annotation>
<xs:sequence>
- <xs:element name="flattened_column" type="x_flattened_column" maxOccurs="unbounded" minOccurs="0" />
+ <xs:element name="flattened_column" type="x_flattened_column" maxOccurs="unbounded" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="x_flattened_column">
<xs:choice maxOccurs="1" minOccurs="1">
- <xs:element name="measure" type="x_measure" />
- <xs:element name="expression" type="x_expr_column" />
- <xs:element name="dim_attribute" type="x_dim_attribute" />
+ <xs:element name="measure" type="x_measure"/>
+ <xs:element name="expression" type="x_expr_column"/>
+ <xs:element name="dim_attribute" type="x_dim_attribute"/>
</xs:choice>
- <xs:attribute name="table_name" type="xs:string" use="required" />
+ <xs:attribute name="table_name" type="xs:string" use="required"/>
<xs:attribute name="chain_name" type="xs:string">
<xs:annotation>
<xs:documentation>
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/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
deleted file mode 100644
index 208081d..0000000
--- a/lens-cli/src/main/java/org/apache/lens/cli/commands/LensCRUDStoragePartitionCommand.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * 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, false, true)).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, false, true)).toString().toLowerCase();
- }
-
- public String addPartitions(String tableName, String storageName, String path) {
- return doAddPartitions(tableName, storageName, getValidPath(path, false, true)).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/ff31ad96/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 d05d7a5..6ba702f 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
@@ -35,7 +35,7 @@ import org.springframework.stereotype.Component;
@Component
@UserDocumentation(title = "OLAP Data cube metadata management",
description = "These commands provide CRUD for cubes")
-public class LensCubeCommands extends LensCRUDCommand<XCube> {
+public class LensCubeCommands extends LogicalTableCrudCommand<XCube> {
/**
* Show cubes.
@@ -106,12 +106,29 @@ public class LensCubeCommands extends LensCRUDCommand<XCube> {
help = "get latest date of data available in cube <cube_name> for time dimension <time_dimension_name>. "
+ " Instead of time dimension, partition column can be directly passed as <time_dimension>")
public String getLatest(
- @CliOption(key = {"", "cube"}, mandatory = true, help = "<cube_name>") String cube,
+ @CliOption(key = {"", "name"}, mandatory = true, help = "<cube_name>") String cube,
@CliOption(key = {"", "time_dimension"}, mandatory = true, help = "<time_dimension>") String timeDim) {
Date dt = getClient().getLatestDateOfCube(cube, timeDim);
return dt == null ? "No Data Available" : formatDate(dt);
}
+ @CliCommand(value = "cube show fields",
+ help = "Show queryable fields of the given cube <cube_name>. "
+ + "Optionally specify <flattened> to include chained fields")
+ public String showQueryableFields(
+ @CliOption(key = {"", "name"}, mandatory = true, help = "<cube_name>") String table,
+ @CliOption(key = {"flattened"}, mandatory = false, unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true", help = "<flattened>") boolean flattened) {
+ return getAllFields(table, flattened);
+ }
+
+ @CliCommand(value = "cube show joinchains",
+ help = "Show joinchains of the given cube <cube_name>. ")
+ public String showJoinChains(
+ @CliOption(key = {"", "name"}, mandatory = true, help = "<cube_name>") String table) {
+ return getAllJoinChains(table);
+ }
+
@Override
public List<String> getAll() {
return getClient().getAllCubes();
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/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 84ae6c3..de022c1 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
@@ -34,7 +34,7 @@ import org.springframework.stereotype.Component;
*/
@Component
@UserDocumentation(title = "Dimension Management", description = "These commands provide CRUD for Dimensions")
-public class LensDimensionCommands extends LensCRUDCommand<XDimension> {
+public class LensDimensionCommands extends LogicalTableCrudCommand<XDimension> {
/**
* Show dimensions.
@@ -103,6 +103,23 @@ public class LensDimensionCommands extends LensCRUDCommand<XDimension> {
return drop(name, false);
}
+ @CliCommand(value = "dimension show fields",
+ help = "Show queryable fields of the given dimension <dimension_name>. "
+ + "Optionally specify <flattened> to include chained fields")
+ public String showQueryableFields(
+ @CliOption(key = {"", "name"}, mandatory = true, help = "<dimension_name>") String table,
+ @CliOption(key = {"flattened"}, mandatory = false, unspecifiedDefaultValue = "false",
+ specifiedDefaultValue = "true", help = "<flattened>") boolean flattened) {
+ return getAllFields(table, flattened);
+ }
+
+ @CliCommand(value = "dimension show joinchains",
+ help = "Show joinchains of the given dimension <dimension_name>. ")
+ public String showJoinChains(
+ @CliOption(key = {"", "name"}, mandatory = true, help = "<dimension_name>") String table) {
+ return getAllJoinChains(table);
+ }
+
@Override
public List<String> getAll() {
return getClient().getAllDimensions();
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/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 40380b7..6a93393 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
@@ -37,7 +37,7 @@ import org.springframework.stereotype.Component;
@Component
@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>
+public class LensDimensionTableCommands extends PhysicalTableCrudCommand<XDimensionTable>
implements CommandMarker {
/**
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/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 24992b9..bdb9c38 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
@@ -36,7 +36,7 @@ import org.springframework.stereotype.Component;
@Component
@UserDocumentation(title = "Management of Facts",
description = "These command provide CRUD for facts, associated storages, and fact partitions")
-public class LensFactCommands extends LensCRUDStoragePartitionCommand<XFactTable> {
+public class LensFactCommands extends PhysicalTableCrudCommand<XFactTable> {
/**
* Show facts.
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/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 1eb7ed6..928531e 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
@@ -271,7 +271,7 @@ public class LensQueryCommands extends BaseLensCommand {
@CliOption(key = {"", "query_handle"}, mandatory = true, help = "<query_handle>") String qh,
@CliOption(key = {"save_location"}, mandatory = false, help = "<save_location>") String location,
@CliOption(key = {"async"}, mandatory = false, unspecifiedDefaultValue = "true",
- help = "<async>") boolean async) {
+ help = "<async>") boolean async) {
QueryHandle queryHandle = new QueryHandle(UUID.fromString(qh));
LensClient.LensClientResultSetWithStats results;
try {
@@ -459,5 +459,4 @@ public class LensQueryCommands extends BaseLensCommand {
planStr.append("\n").append("Prepare handle:").append(plan.getPrepareHandle());
return planStr.toString();
}
-
}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java
new file mode 100644
index 0000000..3c78e43
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/LogicalTableCrudCommand.java
@@ -0,0 +1,31 @@
+/**
+ * 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 org.apache.lens.cli.table.XFlattenedColumnTable;
+import org.apache.lens.cli.table.XJoinChainTable;
+
+public abstract class LogicalTableCrudCommand<T> extends LensCRUDCommand<T> {
+ public String getAllFields(String table, boolean flattened) {
+ return new XFlattenedColumnTable(getClient().getQueryableFields(table, flattened), table).toString();
+ }
+ public String getAllJoinChains(String table) {
+ return new XJoinChainTable(getClient().getJoinChains(table)).toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.java b/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.java
new file mode 100644
index 0000000..a479c14
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/commands/PhysicalTableCrudCommand.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 PhysicalTableCrudCommand<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, false, true)).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, false, true)).toString().toLowerCase();
+ }
+
+ public String addPartitions(String tableName, String storageName, String path) {
+ return doAddPartitions(tableName, storageName, getValidPath(path, false, true)).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/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/skel/LensBanner.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/skel/LensBanner.java b/lens-cli/src/main/java/org/apache/lens/cli/skel/LensBanner.java
index 86099d3..f577509 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/skel/LensBanner.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/skel/LensBanner.java
@@ -47,4 +47,9 @@ public class LensBanner extends DefaultBannerProvider {
public String getWelcomeMessage() {
return "Welcome to Lens Client";
}
+
+ @Override
+ public String getVersion() {
+ return getClass().getPackage().getImplementationVersion() + " built with spring shell " + super.getVersion();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/skel/LensHistoryFileProvider.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/skel/LensHistoryFileProvider.java b/lens-cli/src/main/java/org/apache/lens/cli/skel/LensHistoryFileProvider.java
index b599d6e..905a019 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/skel/LensHistoryFileProvider.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/skel/LensHistoryFileProvider.java
@@ -40,7 +40,7 @@ public class LensHistoryFileProvider extends DefaultHistoryFileNameProvider {
* @see org.springframework.shell.plugin.support.DefaultHistoryFileNameProvider#name()
*/
@Override
- public String name() {
+ public String getProviderName() {
return "lens client history provider";
}
}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/skel/LensPromptProvider.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/skel/LensPromptProvider.java b/lens-cli/src/main/java/org/apache/lens/cli/skel/LensPromptProvider.java
index e5524bd..3729bc7 100644
--- a/lens-cli/src/main/java/org/apache/lens/cli/skel/LensPromptProvider.java
+++ b/lens-cli/src/main/java/org/apache/lens/cli/skel/LensPromptProvider.java
@@ -41,7 +41,7 @@ public class LensPromptProvider extends DefaultPromptProvider {
* @see org.springframework.shell.plugin.support.DefaultPromptProvider#name()
*/
@Override
- public String name() {
+ public String getProviderName() {
return "lens prompt provider";
}
}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTable.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTable.java b/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTable.java
new file mode 100644
index 0000000..2f46c3b
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTable.java
@@ -0,0 +1,59 @@
+/**
+ * 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.table;
+
+
+import java.util.Collection;
+
+import org.springframework.shell.support.table.Table;
+import org.springframework.shell.support.table.TableHeader;
+import org.springframework.shell.support.table.TableRenderer;
+
+import lombok.Data;
+
+@Data
+public class CollectionTable<T> {
+ private final Collection<T> collection;
+ private final RowProvider<T> provider;
+ private final String[] header;
+
+ public CollectionTable(Collection<T> collection, RowProvider<T> provider, String... header) {
+ this.collection = collection;
+ this.provider = provider;
+ this.header = header;
+ }
+
+ interface RowProvider<T> {
+ String[][] getRows(T element);
+ }
+
+ @Override
+ public String toString() {
+ Table table = new Table();
+ for (int i = 0; i < header.length; i++) {
+ table.addHeader(i + 1, new TableHeader(header[i]));
+ }
+ for (T element : collection) {
+ for (String[] row : provider.getRows(element)) {
+ table.addRow(row);
+ }
+ }
+ return TableRenderer.renderTextTable(table);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTableFactory.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTableFactory.java b/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTableFactory.java
new file mode 100644
index 0000000..bcc44a6
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/table/CollectionTableFactory.java
@@ -0,0 +1,158 @@
+/**
+ * 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.table;
+
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.lens.api.metastore.*;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+public class CollectionTableFactory {
+ private CollectionTableFactory() {}
+
+ public static CollectionTable<XFlattenedColumn> getCollectionTable(Class<? extends XField> claz, final String table) {
+ if (claz == XExprColumn.class) {
+ return new CollectionTable<>(Sets.newTreeSet(new Comparator<XFlattenedColumn>() {
+ @Override
+ public int compare(XFlattenedColumn o1, XFlattenedColumn o2) {
+ return o1.getExpression().getName().compareTo(o2.getExpression().getName());
+ }
+ }),
+ new CollectionTable.RowProvider<XFlattenedColumn>() {
+ @Override
+ public String[][] getRows(XFlattenedColumn element) {
+ return new String[][]{
+ {
+ nulltoBlank(element.getExpression().getName()),
+ nulltoBlank(element.getExpression().getDisplayString()),
+ nulltoBlank(element.getExpression().getDescription()),
+ expressionsAsString(element.getExpression().getExprSpec()),
+ },
+ };
+ }
+
+ private String expressionsAsString(List<XExprSpec> exprSpec) {
+ StringBuilder sb = new StringBuilder();
+ String sep = "";
+ for (XExprSpec spec : exprSpec) {
+ sb.append(sep);
+ sep = ", ";
+ List<String> clauses = Lists.newArrayList();
+ if (spec.getStartTime() != null) {
+ clauses.add("after " + spec.getStartTime());
+ }
+ if (spec.getEndTime() != null) {
+ clauses.add("before " + spec.getEndTime());
+ }
+ String sep1 = "";
+ if (clauses.isEmpty()) {
+ clauses.add("always valid");
+ }
+ for (String clause : clauses) {
+ sb.append(sep1).append(clause);
+ sep1 = " and ";
+ }
+ sb.append(": ");
+ sb.append(spec.getExpr());
+ }
+ return sb.toString();
+ }
+ }, "Name", "Display String", "Description", "Expr Specs");
+ } else if (claz == XDimAttribute.class) {
+ return new CollectionTable<>(Sets.newTreeSet(new Comparator<XFlattenedColumn>() {
+ @Override
+ public int compare(XFlattenedColumn o1, XFlattenedColumn o2) {
+ if (o1 == null || o1.getDimAttribute() == null) {
+ return -1;
+ } else if (o2 == null || o2.getDimAttribute() == null) {
+ return 1;
+ } else if (table.equals(o1.getTableName()) && !table.equals(o2.getTableName())) {
+ return -1;
+ } else if (table.equals(o2.getTableName()) && !table.equals(o1.getTableName())) {
+ return 1;
+ } else {
+ if (o1.getTableName() == null) {
+ o1.setTableName("");
+ }
+ if (o2.getTableName() == null) {
+ o2.setTableName("");
+ }
+ if (o1.getChainName() == null) {
+ o1.setChainName("");
+ }
+ if (o2.getChainName() == null) {
+ o2.setChainName("");
+ }
+ int cmp = o1.getTableName().compareTo(o2.getTableName());
+ if (cmp != 0) {
+ return cmp;
+ }
+ cmp = o1.getChainName().compareTo(o2.getChainName());
+ if (cmp != 0) {
+ return cmp;
+ }
+ return o1.getDimAttribute().getName().compareTo(o2.getDimAttribute().getName());
+ }
+ }
+ }),
+ new CollectionTable.RowProvider<XFlattenedColumn>() {
+ @Override
+ public String[][] getRows(XFlattenedColumn element) {
+ String prefix = XFlattenedColumnTable.firstNonNull(element.getChainName(), element.getTableName());
+ return new String[][]{
+ {
+ (prefix == null || prefix.isEmpty() || prefix.equalsIgnoreCase(table) ? "" : (prefix + "."))
+ + nulltoBlank(element.getDimAttribute().getName()),
+ nulltoBlank(element.getDimAttribute().getDisplayString()),
+ nulltoBlank(element.getDimAttribute().getDescription()),
+ },
+ };
+ }
+ }, "Name", "Display String", "Description");
+ } else if (claz == XMeasure.class) {
+ return new CollectionTable<>(Sets.newTreeSet(new Comparator<XFlattenedColumn>() {
+ @Override
+ public int compare(XFlattenedColumn o1, XFlattenedColumn o2) {
+ return o1.getMeasure().getName().compareTo(o2.getMeasure().getName());
+ }
+ }),
+ new CollectionTable.RowProvider<XFlattenedColumn>() {
+ @Override
+ public String[][] getRows(XFlattenedColumn element) {
+ return new String[][]{
+ {
+ nulltoBlank(element.getMeasure().getName()),
+ nulltoBlank(element.getMeasure().getDisplayString()),
+ nulltoBlank(element.getMeasure().getDescription()),
+ },
+ };
+ }
+ }, "Name", "Display String", "Description");
+ } else {
+ return null;
+ }
+ }
+
+ public static String nulltoBlank(String s) {
+ return s == null ? "" : s;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/table/XFlattenedColumnTable.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/table/XFlattenedColumnTable.java b/lens-cli/src/main/java/org/apache/lens/cli/table/XFlattenedColumnTable.java
new file mode 100644
index 0000000..d4208c1
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/table/XFlattenedColumnTable.java
@@ -0,0 +1,97 @@
+/**
+ * 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.table;
+
+
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlType;
+
+import org.apache.lens.api.metastore.XField;
+import org.apache.lens.api.metastore.XFlattenedColumn;
+import org.apache.lens.api.metastore.XFlattenedColumns;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+public class XFlattenedColumnTable {
+ private final String table;
+ Map<Class<? extends XField>, CollectionTable<XFlattenedColumn>> tables = Maps.newLinkedHashMap();
+ List<String> chainNames = Lists.newArrayList();
+ List<String> tableNames = Lists.newArrayList();
+
+ public XFlattenedColumnTable(XFlattenedColumns flattenedColumns, String table) {
+ this.table = table;
+ for (XFlattenedColumn column : flattenedColumns.getFlattenedColumn()) {
+ XField field = firstNonNull(column.getDimAttribute(), column.getMeasure(), column.getExpression());
+ if (field != null) {
+ if (!tables.containsKey(field.getClass())) {
+ tables.put(field.getClass(), CollectionTableFactory.getCollectionTable(field.getClass(), table));
+ }
+ tables.get(field.getClass()).getCollection().add(column);
+ } else {
+ if (column.getChainName() != null) {
+ chainNames.add(column.getChainName());
+ }
+ if (column.getTableName() != null) {
+ tableNames.add(column.getTableName());
+ }
+ }
+ }
+ }
+
+ public static <T> T firstNonNull(T... args) {
+ for (T arg : args) {
+ if (arg != null) {
+ return arg;
+ }
+ }
+ return null;
+ }
+
+
+ @Override
+ public String toString() {
+ String sep = "=============================";
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<Class<? extends XField>, CollectionTable<XFlattenedColumn>> entry : tables.entrySet()) {
+ String title =
+ entry.getKey().getAnnotation(XmlType.class).name().replaceAll("^x_", "").replaceAll("_", " ") + "s";
+ sb.append(title).append("\n").append(sep).append("\n").append(entry.getValue()).append("\n");
+ }
+ String sep1 = "";
+ if (!chainNames.isEmpty()) {
+ sb.append("Accessible Join Chains\n").append(sep).append("\n");
+ for (String chain : chainNames) {
+ sb.append(sep1).append(chain);
+ sep1 = "\n";
+ }
+ }
+ sep1 = "";
+ if (!tableNames.isEmpty()) {
+ sb.append("Accessible Tables\n").append(sep).append("\n");
+ for (String table : tableNames) {
+ sb.append(sep1).append(table);
+ sep1 = "\n";
+ }
+ }
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/main/java/org/apache/lens/cli/table/XJoinChainTable.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/main/java/org/apache/lens/cli/table/XJoinChainTable.java b/lens-cli/src/main/java/org/apache/lens/cli/table/XJoinChainTable.java
new file mode 100644
index 0000000..8082215
--- /dev/null
+++ b/lens-cli/src/main/java/org/apache/lens/cli/table/XJoinChainTable.java
@@ -0,0 +1,77 @@
+/**
+ * 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.table;
+
+
+import static org.apache.lens.cli.table.CollectionTableFactory.nulltoBlank;
+
+import org.apache.lens.api.metastore.*;
+
+public class XJoinChainTable {
+
+ private XJoinChains xJoinChains;
+
+ public XJoinChainTable(XJoinChains xJoinChains) {
+ this.xJoinChains = xJoinChains;
+ }
+
+ @Override
+ public String toString() {
+ return new CollectionTable<>(xJoinChains.getJoinChain(), new CollectionTable.RowProvider<XJoinChain>() {
+ @Override
+ public String[][] getRows(XJoinChain element) {
+ int size = element.getPaths().getPath().size();
+ String[][] ret = new String[size][5];
+ for (int i = 0; i < size; i++) {
+ if (i == 0) {
+ ret[i][0] = nulltoBlank(element.getName());
+ ret[i][1] = nulltoBlank(element.getDisplayString());
+ ret[i][2] = nulltoBlank(element.getDescription());
+ ret[i][3] = nulltoBlank(element.getDestTable());
+ } else {
+ ret[i][0] = "";
+ ret[i][1] = "";
+ ret[i][2] = "";
+ ret[i][3] = "";
+ }
+ ret[i][4] = pathAsString(element.getPaths().getPath().get(i));
+ }
+ return ret;
+ }
+
+ private String pathAsString(XJoinPath path) {
+ StringBuilder sb = new StringBuilder();
+ String sep1 = "";
+ for (XJoinEdge edge : path.getEdges().getEdge()) {
+ sb.append(sep1)
+ .append(edge.getFrom().getTable()).append(".").append(edge.getFrom().getColumn())
+ .append("=")
+ .append(edge.getTo().getTable()).append(".").append(edge.getTo().getColumn());
+ sep1 = "->";
+ }
+ return sb.toString();
+ }
+ }
+
+ , "Name", "Display String", "Description", "Destination Table", "Path").
+
+ toString();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-lens/blob/ff31ad96/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
----------------------------------------------------------------------
diff --git a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
index ae39a2a..73661e1 100644
--- a/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
+++ b/lens-cli/src/test/java/org/apache/lens/cli/TestLensCubeCommands.java
@@ -18,15 +18,19 @@
*/
package org.apache.lens.cli;
+import static org.testng.Assert.*;
+
import java.io.*;
import java.net.URL;
+import java.util.Arrays;
+import org.apache.lens.api.metastore.XJoinChains;
import org.apache.lens.cli.commands.LensCubeCommands;
+import org.apache.lens.cli.table.XJoinChainTable;
import org.apache.lens.client.LensClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.testng.Assert;
import org.testng.annotations.Test;
/**
@@ -51,22 +55,38 @@ public class TestLensCubeCommands extends LensCliApplicationTest {
LOG.debug("Starting to test cube commands");
URL cubeSpec = TestLensCubeCommands.class.getClassLoader().getResource("sample-cube.xml");
String cubeList = command.showCubes();
- Assert.assertFalse(cubeList.contains("sample_cube"));
+ assertFalse(cubeList.contains("sample_cube"));
command.createCube(new File(cubeSpec.toURI()).getAbsolutePath());
cubeList = command.showCubes();
- Assert.assertEquals(command.getLatest("sample_cube", "dt"), "No Data Available");
- Assert.assertTrue(cubeList.contains("sample_cube"));
-
+ assertEquals(command.getLatest("sample_cube", "dt"), "No Data Available");
+ assertTrue(cubeList.contains("sample_cube"));
+ testJoinChains(command);
+ testFields(command);
testUpdateCommand(new File(cubeSpec.toURI()), command);
command.dropCube("sample_cube");
try {
command.getLatest("sample_cube", "dt");
- Assert.fail("should have failed as cube doesn't exist");
+ fail("should have failed as cube doesn't exist");
} catch (Exception e) {
//pass
}
cubeList = command.showCubes();
- Assert.assertFalse(cubeList.contains("sample_cube"));
+ assertFalse(cubeList.contains("sample_cube"));
+ }
+
+ private void testJoinChains(LensCubeCommands command) {
+ String joinChains = command.showJoinChains("sample_cube");
+ assertEquals(joinChains, new XJoinChainTable(new XJoinChains()).toString());
+ }
+
+ private void testFields(LensCubeCommands command) {
+ String fields = command.showQueryableFields("sample_cube", true);
+ for (String field : Arrays
+ .asList("dim1", "dim2", "dim3", "measure1", "measure2", "measure3", "measure4", "expr_msr5")) {
+ assertTrue(fields.contains(field));
+ }
+ assertTrue(fields.contains("measure3 + measure4 + 0.01"));
+ assertTrue(fields.replace("measure3 + measure4 + 0.01", "blah").contains("measure3 + measure4"));
}
/**
@@ -105,13 +125,13 @@ public class TestLensCubeCommands extends LensCliApplicationTest {
String propString = "name : sample_cube.prop value : sample";
String propString1 = "name : sample_cube.prop1 value : sample1";
- Assert.assertTrue(desc.contains(propString));
+ assertTrue(desc.contains(propString));
command.updateCube("sample_cube", "/tmp/sample_cube1.xml");
desc = command.describeCube("sample_cube");
LOG.debug(desc);
- Assert.assertTrue(desc.contains(propString));
- Assert.assertTrue(desc.contains(propString1));
+ assertTrue(desc.contains(propString));
+ assertTrue(desc.contains(propString1));
} finally {
newFile.delete();
}