You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lens.apache.org by pr...@apache.org on 2015/12/11 14:11:40 UTC
[4/4] lens git commit: LENS-885: Cleanup of Cube test cases
LENS-885: Cleanup of Cube test cases
Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/7c7c86da
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/7c7c86da
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/7c7c86da
Branch: refs/heads/master
Commit: 7c7c86daed2e9907bda92f5ed29e73ed99a9a726
Parents: 7e9e47e
Author: Rajat Khandelwal <pr...@apache.org>
Authored: Fri Dec 11 18:40:59 2015 +0530
Committer: Rajat Khandelwal <ra...@gmail.com>
Committed: Fri Dec 11 18:41:00 2015 +0530
----------------------------------------------------------------------
.../apache/lens/cube/metadata/CubeColumn.java | 1 -
.../lens/cube/metadata/CubeFactTable.java | 1 -
.../org/apache/lens/cube/metadata/DateUtil.java | 396 ++++++++++++++++
.../lens/cube/metadata/TimePartitionRange.java | 1 -
.../apache/lens/cube/metadata/TimeRange.java | 219 +++++++++
.../apache/lens/cube/metadata/UpdatePeriod.java | 84 +++-
.../timeline/EndsAndHolesPartitionTimeline.java | 2 +-
.../apache/lens/cube/parse/CandidateFact.java | 5 +-
.../cube/parse/CandidateTablePruneCause.java | 2 +
.../org/apache/lens/cube/parse/DateUtil.java | 456 ------------------
.../lens/cube/parse/ExpressionResolver.java | 11 +-
.../lens/cube/parse/SingleFactHQLContext.java | 2 +-
.../lens/cube/parse/StorageTableResolver.java | 2 +-
.../org/apache/lens/cube/parse/TimeRange.java | 220 ---------
.../lens/cube/parse/TimerangeResolver.java | 5 +-
.../lens/cube/metadata/CubeFactTableTest.java | 1 -
.../apache/lens/cube/metadata/DateFactory.java | 196 ++++++++
.../cube/metadata/TestCubeMetastoreClient.java | 115 ++---
.../apache/lens/cube/metadata/TestDateUtil.java | 297 ++++++++++++
.../apache/lens/cube/parse/CubeTestSetup.java | 191 ++------
.../FieldsCannotBeQueriedTogetherTest.java | 8 +-
.../lens/cube/parse/TestAggregateResolver.java | 1 +
.../lens/cube/parse/TestBaseCubeQueries.java | 5 +-
.../cube/parse/TestBetweenTimeRangeWriter.java | 25 +-
.../lens/cube/parse/TestCubeRewriter.java | 459 +++++++++----------
.../apache/lens/cube/parse/TestDateUtil.java | 299 ------------
.../cube/parse/TestDenormalizationResolver.java | 28 +-
.../lens/cube/parse/TestExpressionContext.java | 4 +-
.../lens/cube/parse/TestExpressionResolver.java | 1 +
.../lens/cube/parse/TestJoinResolver.java | 1 +
.../lens/cube/parse/TestORTimeRangeWriter.java | 40 +-
.../lens/cube/parse/TestQueryMetrics.java | 2 +-
.../lens/cube/parse/TestRewriterPlan.java | 2 +-
.../apache/lens/cube/parse/TestStorageUtil.java | 98 ++--
.../lens/cube/parse/TestTimeRangeExtractor.java | 33 +-
.../lens/cube/parse/TestTimeRangeResolver.java | 2 +-
.../lens/cube/parse/TestTimeRangeWriter.java | 48 +-
.../parse/TestTimeRangeWriterWithQuery.java | 134 +++---
.../lens/server/query/QueryResultPurger.java | 2 +-
39 files changed, 1693 insertions(+), 1706 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeColumn.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeColumn.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeColumn.java
index a2a00d2..b04532f 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeColumn.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeColumn.java
@@ -24,7 +24,6 @@ import java.util.Date;
import java.util.Map;
import java.util.TimeZone;
-import org.apache.lens.cube.parse.TimeRange;
import com.google.common.base.Optional;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeFactTable.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeFactTable.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeFactTable.java
index d6bfb79..dd0adb7 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeFactTable.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/CubeFactTable.java
@@ -21,7 +21,6 @@ package org.apache.lens.cube.metadata;
import java.util.*;
import org.apache.lens.cube.metadata.UpdatePeriod.UpdatePeriodComparator;
-import org.apache.lens.cube.parse.DateUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.hive.metastore.api.FieldSchema;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/metadata/DateUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/DateUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/DateUtil.java
new file mode 100644
index 0000000..b76c567
--- /dev/null
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/DateUtil.java
@@ -0,0 +1,396 @@
+/**
+ * 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.cube.metadata;
+
+import static java.util.Calendar.MONTH;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.lens.cube.error.LensCubeErrorCode;
+import org.apache.lens.server.api.error.LensException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.time.DateUtils;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public final class DateUtil {
+ private DateUtil() {
+
+ }
+
+ /*
+ * NOW -> new java.util.Date() NOW-7DAY -> a date one week earlier NOW (+-)
+ * <NUM>UNIT or Hardcoded dates in DD-MM-YYYY hh:mm:ss,sss
+ */
+ public static final String UNIT;
+
+ static {
+ StringBuilder sb = new StringBuilder();
+ String sep = "";
+ for (UpdatePeriod up : UpdatePeriod.values()) {
+ sb.append(sep).append(up.getUnitName());
+ sep = "|";
+ }
+ UNIT = sb.toString();
+ }
+
+ public static final String GRANULARITY = "\\.(" + UNIT + ")";
+ public static final String RELATIVE = "(now)(" + GRANULARITY + ")?";
+ public static final Pattern P_RELATIVE = Pattern.compile(RELATIVE, Pattern.CASE_INSENSITIVE);
+
+ public static final String WSPACE = "\\s+";
+ public static final String OPTIONAL_WSPACE = "\\s*";
+
+ public static final String SIGNAGE = "\\+|\\-";
+ public static final Pattern P_SIGNAGE = Pattern.compile(SIGNAGE);
+
+ public static final String QUANTITY = "\\d+";
+ public static final Pattern P_QUANTITY = Pattern.compile(QUANTITY);
+
+ public static final Pattern P_UNIT = Pattern.compile(UNIT, Pattern.CASE_INSENSITIVE);
+
+ public static final String RELDATE_VALIDATOR_STR = RELATIVE + OPTIONAL_WSPACE + "((" + SIGNAGE + ")" + "("
+ + WSPACE + ")?" + "(" + QUANTITY + ")" + OPTIONAL_WSPACE + "(" + UNIT + "))?" + "(s?)";
+
+ public static final Pattern RELDATE_VALIDATOR = Pattern.compile(RELDATE_VALIDATOR_STR, Pattern.CASE_INSENSITIVE);
+
+ public static final String YEAR_FMT = "[0-9]{4}";
+ public static final String MONTH_FMT = YEAR_FMT + "-[0-9]{2}";
+ public static final String DAY_FMT = MONTH_FMT + "-[0-9]{2}";
+ public static final String HOUR_FMT = DAY_FMT + "-[0-9]{2}";
+ public static final String MINUTE_FMT = HOUR_FMT + ":[0-9]{2}";
+ public static final String SECOND_FMT = MINUTE_FMT + ":[0-9]{2}";
+ public static final String MILLISECOND_FMT = SECOND_FMT + ",[0-9]{3}";
+ public static final String ABSDATE_FMT = "yyyy-MM-dd-HH:mm:ss,SSS";
+ public static final String HIVE_QUERY_DATE_FMT = "yyyy-MM-dd HH:mm:ss";
+
+ public static final ThreadLocal<DateFormat> ABSDATE_PARSER =
+ new ThreadLocal<DateFormat>() {
+ @Override
+ protected SimpleDateFormat initialValue() {
+ return new SimpleDateFormat(ABSDATE_FMT);
+ }
+ };
+ public static final ThreadLocal<DateFormat> HIVE_QUERY_DATE_PARSER =
+ new ThreadLocal<DateFormat>() {
+ @Override
+ protected SimpleDateFormat initialValue() {
+ return new SimpleDateFormat(HIVE_QUERY_DATE_FMT);
+ }
+ };
+
+ public static String getAbsDateFormatString(String str) {
+ if (str.matches(YEAR_FMT)) {
+ return str + "-01-01-00:00:00,000";
+ } else if (str.matches(MONTH_FMT)) {
+ return str + "-01-00:00:00,000";
+ } else if (str.matches(DAY_FMT)) {
+ return str + "-00:00:00,000";
+ } else if (str.matches(HOUR_FMT)) {
+ return str + ":00:00,000";
+ } else if (str.matches(MINUTE_FMT)) {
+ return str + ":00,000";
+ } else if (str.matches(SECOND_FMT)) {
+ return str + ",000";
+ } else if (str.matches(MILLISECOND_FMT)) {
+ return str;
+ }
+ throw new IllegalArgumentException("Unsupported formatting for date" + str);
+ }
+
+ public static Date resolveDate(String str, Date now) throws LensException {
+ if (RELDATE_VALIDATOR.matcher(str).matches()) {
+ return resolveRelativeDate(str, now);
+ } else {
+ return resolveAbsoluteDate(str);
+ }
+ }
+
+ public static String relativeToAbsolute(String relative) throws LensException {
+ return relativeToAbsolute(relative, new Date());
+ }
+
+ public static String relativeToAbsolute(String relative, Date now) throws LensException {
+ if (RELDATE_VALIDATOR.matcher(relative).matches()) {
+ return ABSDATE_PARSER.get().format(resolveRelativeDate(relative, now));
+ } else {
+ return relative;
+ }
+ }
+
+ static Cache<String, Date> stringToDateCache = CacheBuilder.newBuilder()
+ .expireAfterWrite(2, TimeUnit.HOURS).maximumSize(100).build();
+
+ public static Date resolveAbsoluteDate(final String str) throws LensException {
+ try {
+ return stringToDateCache.get(str, new Callable<Date>() {
+ @Override
+ public Date call() throws ParseException {
+ return ABSDATE_PARSER.get().parse(getAbsDateFormatString(str));
+ }
+ });
+ } catch (Exception e) {
+ log.error("Invalid date format. expected only {} date provided:{}", ABSDATE_FMT, str, e);
+ throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getLensErrorInfo(), ABSDATE_FMT, str);
+ }
+ }
+
+ public static Date resolveRelativeDate(String str, Date now) throws LensException {
+ if (StringUtils.isBlank(str)) {
+ throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getLensErrorInfo());
+ }
+
+ // Resolve NOW with proper granularity
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTime(now);
+
+ str = str.toLowerCase();
+ Matcher relativeMatcher = P_RELATIVE.matcher(str);
+ if (relativeMatcher.find()) {
+ String nowWithGranularity = relativeMatcher.group();
+ nowWithGranularity = nowWithGranularity.replaceAll("now", "");
+ nowWithGranularity = nowWithGranularity.replaceAll("\\.", "");
+
+ Matcher granularityMatcher = P_UNIT.matcher(nowWithGranularity);
+ if (granularityMatcher.find()) {
+ calendar = UpdatePeriod.fromUnitName(granularityMatcher.group().toLowerCase()).truncate(calendar);
+ }
+ }
+
+ // Get rid of 'now' part and whitespace
+ String diffStr = str.replaceAll(RELATIVE, "").replace(WSPACE, "");
+ TimeDiff diff = TimeDiff.parseFrom(diffStr);
+ return diff.offsetFrom(calendar.getTime());
+ }
+
+ public static Date getCeilDate(Date date, UpdatePeriod interval) {
+ return interval.getCeilDate(date);
+ }
+
+ public static Date getFloorDate(Date date, UpdatePeriod interval) {
+ return interval.getFloorDate(date);
+ }
+
+ public static CoveringInfo getMonthlyCoveringInfo(Date from, Date to) {
+ // Move 'from' to end of month, unless its the first day of month
+ boolean coverable = true;
+ if (!from.equals(DateUtils.truncate(from, MONTH))) {
+ from = DateUtils.addMonths(DateUtils.truncate(from, MONTH), 1);
+ coverable = false;
+ }
+
+ // Move 'to' to beginning of next month, unless its the first day of the month
+ if (!to.equals(DateUtils.truncate(to, MONTH))) {
+ to = DateUtils.truncate(to, MONTH);
+ coverable = false;
+ }
+
+ int months = 0;
+ while (from.before(to)) {
+ from = DateUtils.addMonths(from, 1);
+ months++;
+ }
+ return new CoveringInfo(months, coverable);
+ }
+
+ public static CoveringInfo getQuarterlyCoveringInfo(Date from, Date to) {
+ CoveringInfo monthlyCoveringInfo = getMonthlyCoveringInfo(from, to);
+ if (monthlyCoveringInfo.getCountBetween() < 3) {
+ return new CoveringInfo(0, false);
+ }
+ boolean coverable = monthlyCoveringInfo.isCoverable();
+ if (!from.equals(DateUtils.truncate(from, MONTH))) {
+ from = DateUtils.addMonths(DateUtils.truncate(from, MONTH), 1);
+ coverable = false;
+ }
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(from);
+ int fromMonth = cal.get(MONTH);
+
+ // Get the start date of the quarter
+ int beginOffset = (3 - fromMonth % 3) % 3;
+ int endOffset = (monthlyCoveringInfo.getCountBetween() - beginOffset) % 3;
+ if (beginOffset > 0 || endOffset > 0) {
+ coverable = false;
+ }
+ return new CoveringInfo((monthlyCoveringInfo.getCountBetween() - beginOffset - endOffset) / 3, coverable);
+ }
+
+
+ public static CoveringInfo getYearlyCoveringInfo(Date from, Date to) {
+ CoveringInfo monthlyCoveringInfo = getMonthlyCoveringInfo(from, to);
+ if (monthlyCoveringInfo.getCountBetween() < 12) {
+ return new CoveringInfo(0, false);
+ }
+ boolean coverable = monthlyCoveringInfo.isCoverable();
+ if (!from.equals(DateUtils.truncate(from, MONTH))) {
+ from = DateUtils.addMonths(DateUtils.truncate(from, MONTH), 1);
+ coverable = false;
+ }
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(from);
+ int fromMonth = cal.get(MONTH);
+ int beginOffset = (12 - fromMonth % 12) % 12;
+ int endOffset = (monthlyCoveringInfo.getCountBetween() - beginOffset) % 12;
+ if (beginOffset > 0 || endOffset > 0) {
+ coverable = false;
+ }
+ return new CoveringInfo((monthlyCoveringInfo.getCountBetween() - beginOffset - endOffset) / 12, coverable);
+ }
+
+ public static CoveringInfo getWeeklyCoveringInfo(Date from, Date to) {
+ int dayDiff = 0;
+ Date tmpFrom = from;
+ while (tmpFrom.before(to)) {
+ tmpFrom = DateUtils.addDays(tmpFrom, 1);
+ dayDiff++;
+ }
+
+ if (dayDiff < 7) {
+ return new CoveringInfo(0, false);
+ }
+
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(from);
+ int fromDay = cal.get(Calendar.DAY_OF_WEEK);
+ cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
+ Date fromWeekStartDate = cal.getTime();
+ boolean coverable = dayDiff % 7 == 0;
+ if (fromWeekStartDate.before(from)) {
+ // Count from the start of next week
+ dayDiff -= (cal.getActualMaximum(Calendar.DAY_OF_WEEK) - (fromDay - Calendar.SUNDAY));
+ coverable = false;
+ }
+
+ return new CoveringInfo(dayDiff / 7, coverable);
+ }
+
+ static CoveringInfo getCoveringInfo(Date from, Date to, UpdatePeriod interval) {
+ switch (interval) {
+ case SECONDLY:
+ case CONTINUOUS:
+ return getMilliSecondCoveringInfo(from, to, 1000);
+ case MINUTELY:
+ case HOURLY:
+ case DAILY:
+ return getMilliSecondCoveringInfo(from, to, interval.weight());
+ case WEEKLY:
+ return getWeeklyCoveringInfo(from, to);
+ case MONTHLY:
+ return getMonthlyCoveringInfo(from, to);
+ case QUARTERLY:
+ return getQuarterlyCoveringInfo(from, to);
+ case YEARLY:
+ return getYearlyCoveringInfo(from, to);
+ default:
+ return new CoveringInfo(0, false);
+ }
+ }
+
+ private static CoveringInfo getMilliSecondCoveringInfo(Date from, Date to, long millisInInterval) {
+ long diff = to.getTime() - from.getTime();
+ return new CoveringInfo((int) (diff / millisInInterval), diff % millisInInterval == 0);
+ }
+
+ static boolean isCoverableBy(Date from, Date to, Set<UpdatePeriod> intervals) {
+ for (UpdatePeriod period : intervals) {
+ if (getCoveringInfo(from, to, period).isCoverable()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static int getTimeDiff(Date fromDate, Date toDate, UpdatePeriod updatePeriod) {
+ if (fromDate.before(toDate)) {
+ return getCoveringInfo(fromDate, toDate, updatePeriod).getCountBetween();
+ } else {
+ return -getCoveringInfo(toDate, fromDate, updatePeriod).getCountBetween();
+ }
+ }
+
+ @Data
+ public static class CoveringInfo {
+ int countBetween;
+ boolean coverable;
+
+ public CoveringInfo(int countBetween, boolean coverable) {
+ this.countBetween = countBetween;
+ this.coverable = coverable;
+ }
+ }
+
+ @EqualsAndHashCode
+ public static class TimeDiff {
+ int quantity;
+ UpdatePeriod updatePeriod;
+
+ private TimeDiff(int quantity, UpdatePeriod updatePeriod) {
+ this.quantity = quantity;
+ this.updatePeriod = updatePeriod;
+ }
+
+ public static TimeDiff parseFrom(String diffStr) throws LensException {
+ // Get the relative diff part to get eventual date based on now.
+ Matcher qtyMatcher = P_QUANTITY.matcher(diffStr);
+ int qty = 1;
+ if (qtyMatcher.find()) {
+ qty = Integer.parseInt(qtyMatcher.group());
+ }
+
+ Matcher signageMatcher = P_SIGNAGE.matcher(diffStr);
+ if (signageMatcher.find()) {
+ String sign = signageMatcher.group();
+ if ("-".equals(sign)) {
+ qty = -qty;
+ }
+ }
+
+ Matcher unitMatcher = P_UNIT.matcher(diffStr);
+ if (unitMatcher.find()) {
+ return new TimeDiff(qty, UpdatePeriod.fromUnitName(unitMatcher.group().toLowerCase()));
+ }
+ return new TimeDiff(0, UpdatePeriod.CONTINUOUS);
+ }
+
+ public Date offsetFrom(Date time) {
+ return DateUtils.add(time, updatePeriod.calendarField(), quantity);
+ }
+
+ public Date negativeOffsetFrom(Date time) {
+ return DateUtils.add(time, updatePeriod.calendarField(), -quantity);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
index 01069a5..2e85111 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimePartitionRange.java
@@ -21,7 +21,6 @@ package org.apache.lens.cube.metadata;
import java.util.Date;
import java.util.Iterator;
-import org.apache.lens.cube.parse.DateUtil;
import org.apache.lens.server.api.error.LensException;
import lombok.Data;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimeRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimeRange.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimeRange.java
new file mode 100644
index 0000000..bf6cc5c
--- /dev/null
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/TimeRange.java
@@ -0,0 +1,219 @@
+/**
+ * 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.cube.metadata;
+
+import static org.apache.lens.cube.metadata.DateUtil.ABSDATE_PARSER;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TreeSet;
+
+import org.apache.lens.cube.error.LensCubeErrorCode;
+import org.apache.lens.server.api.error.LensException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.hive.ql.parse.ASTNode;
+
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+
+import lombok.Data;
+import lombok.Getter;
+
+/**
+ * Timerange data structure
+ */
+@JsonIgnoreProperties({"astNode", "parent"})
+@Data
+public class TimeRange {
+ private String partitionColumn;
+ private Date toDate;
+ private Date fromDate;
+ private ASTNode astNode;
+ private ASTNode parent;
+ private int childIndex;
+
+ public boolean isCoverableBy(TreeSet<UpdatePeriod> updatePeriods) {
+ return DateUtil.isCoverableBy(fromDate, toDate, updatePeriods);
+ }
+
+
+ public static class TimeRangeBuilder {
+ private final TimeRange range;
+
+ public TimeRangeBuilder() {
+ this.range = new TimeRange();
+ }
+
+ public TimeRangeBuilder partitionColumn(String col) {
+ range.partitionColumn = col;
+ return this;
+ }
+
+ public TimeRangeBuilder toDate(Date to) {
+ range.toDate = to;
+ return this;
+ }
+
+ public TimeRangeBuilder fromDate(Date from) {
+ range.fromDate = from;
+ return this;
+ }
+
+ public TimeRangeBuilder astNode(ASTNode node) {
+ range.astNode = node;
+ return this;
+ }
+
+ public TimeRangeBuilder parent(ASTNode parent) {
+ range.parent = parent;
+ return this;
+ }
+
+ public TimeRangeBuilder childIndex(int childIndex) {
+ range.childIndex = childIndex;
+ return this;
+ }
+
+ public TimeRange build() {
+ return range;
+ }
+ }
+
+ public static TimeRangeBuilder getBuilder() {
+ return new TimeRangeBuilder();
+ }
+
+ private TimeRange() {
+
+ }
+
+ public void validate() throws LensException {
+ if (partitionColumn == null || fromDate == null || toDate == null || fromDate.equals(toDate)) {
+ throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo());
+ }
+
+ if (fromDate.after(toDate)) {
+ throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo(),
+ fromDate.toString(), toDate.toString());
+ }
+ }
+
+ public String toTimeDimWhereClause() {
+ return toTimeDimWhereClause(null, partitionColumn);
+ }
+
+ public String toTimeDimWhereClause(String prefix, String column) {
+ if (StringUtils.isNotBlank(column)) {
+ column = prefix + "." + column;
+ }
+ return new StringBuilder()
+ .append(column).append(" >= '").append(DateUtil.HIVE_QUERY_DATE_PARSER.get().format(fromDate)).append("'")
+ .append(" AND ")
+ .append(column).append(" < '").append(DateUtil.HIVE_QUERY_DATE_PARSER.get().format(toDate)).append("'")
+ .toString();
+ }
+
+ @Override
+ public String toString() {
+ return partitionColumn + " [" + ABSDATE_PARSER.get().format(fromDate) + " to "
+ + ABSDATE_PARSER.get().format(toDate) + ")";
+ }
+
+ /** iterable from fromDate(including) to toDate(excluding) incrementing increment units of updatePeriod */
+ public static Iterable iterable(Date fromDate, Date toDate, UpdatePeriod updatePeriod, int increment) {
+ return TimeRange.getBuilder().fromDate(fromDate).toDate(toDate).build().iterable(updatePeriod, increment);
+ }
+
+ /** iterable from fromDate(including) incrementing increment units of updatePeriod. Do this numIters times */
+ public static Iterable iterable(Date fromDate, int numIters, UpdatePeriod updatePeriod, int increment) {
+ return TimeRange.getBuilder().fromDate(fromDate).build().iterable(updatePeriod, numIters, increment);
+ }
+
+ private Iterable iterable(UpdatePeriod updatePeriod, int numIters, int increment) {
+ return new Iterable(updatePeriod, numIters, increment);
+ }
+
+ public Iterable iterable(UpdatePeriod updatePeriod, int increment) {
+ if (increment == 0) {
+ throw new UnsupportedOperationException("Can't iterate if iteration increment is zero");
+ }
+ long numIters = DateUtil.getTimeDiff(fromDate, toDate, updatePeriod) / increment;
+ return new Iterable(updatePeriod, numIters, increment);
+ }
+
+ /** Iterable so that foreach is supported */
+ public class Iterable implements java.lang.Iterable<Date> {
+ private UpdatePeriod updatePeriod;
+ private long numIters;
+ private int increment;
+
+ public Iterable(UpdatePeriod updatePeriod, long numIters, int increment) {
+ this.updatePeriod = updatePeriod;
+ this.numIters = numIters;
+ if (this.numIters < 0) {
+ this.numIters = 0;
+ }
+ this.increment = increment;
+ }
+
+ @Override
+ public Iterator iterator() {
+ return new Iterator();
+ }
+
+ public class Iterator implements java.util.Iterator<Date> {
+ Calendar calendar;
+ // Tracks the index of the item returned after the last next() call.
+ // Index here refers to the index if the iterator were iterated and converted into a list.
+ @Getter
+ int counter = -1;
+
+ public Iterator() {
+ calendar = Calendar.getInstance();
+ calendar.setTime(fromDate);
+ }
+
+ @Override
+ public boolean hasNext() {
+ return counter < numIters - 1;
+ }
+
+ @Override
+ public Date next() {
+ Date cur = calendar.getTime();
+ updatePeriod.increment(calendar, increment);
+ counter++;
+ return cur;
+ }
+
+ public Date peekNext() {
+ return calendar.getTime();
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("remove from timerange iterator");
+ }
+
+ public long getNumIters() {
+ return numIters;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
index 4c76a69..4238066 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/UpdatePeriod.java
@@ -278,7 +278,7 @@ public enum UpdatePeriod implements Named {
return cal.getTime();
case QUARTERLY:
Date dt = DateUtils.truncate(date, this.calendarField());
- dt.setMonth(dt.getMonth() - dt.getMonth() % 3);
+ dt.setMonth(dt.getMonth() - (dt.getMonth() % 3));
return dt;
default:
return DateUtils.truncate(date, this.calendarField());
@@ -299,6 +299,86 @@ public enum UpdatePeriod implements Named {
calendar.add(calendarField(), increment);
}
+ public Date getCeilDate(Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ boolean hasFraction = false;
+ switch (this) {
+ case YEARLY:
+ if (cal.get(MONTH) != 0) {
+ hasFraction = true;
+ break;
+ }
+ case MONTHLY:
+ if (cal.get(DAY_OF_MONTH) != 1) {
+ hasFraction = true;
+ break;
+ }
+ case DAILY:
+ if (cal.get(Calendar.HOUR_OF_DAY) != 0) {
+ hasFraction = true;
+ break;
+ }
+ case HOURLY:
+ if (cal.get(Calendar.MINUTE) != 0) {
+ hasFraction = true;
+ break;
+ }
+ case MINUTELY:
+ if (cal.get(Calendar.SECOND) != 0) {
+ hasFraction = true;
+ break;
+ }
+ case SECONDLY:
+ case CONTINUOUS:
+ if (cal.get(Calendar.MILLISECOND) != 0) {
+ hasFraction = true;
+ }
+ break;
+ case WEEKLY:
+ if (cal.get(Calendar.DAY_OF_WEEK) != 1) {
+ hasFraction = true;
+ break;
+ }
+ }
+
+ if (hasFraction) {
+ cal.add(this.calendarField(), 1);
+ return getFloorDate(cal.getTime());
+ } else {
+ return date;
+ }
+ }
+
+ public Date getFloorDate(Date date) {
+ Calendar cal = Calendar.getInstance();
+ cal.setTime(date);
+ switch(this) {
+ case WEEKLY:
+ cal.set(Calendar.DAY_OF_WEEK, 1);
+ break;
+ }
+ switch (this) {
+ case YEARLY:
+ cal.set(MONTH, 0);
+ case MONTHLY:
+ cal.set(DAY_OF_MONTH, 1);
+ case WEEKLY:
+ // Already covered, only here for fall through cases
+ case DAILY:
+ cal.set(Calendar.HOUR_OF_DAY, 0);
+ case HOURLY:
+ cal.set(Calendar.MINUTE, 0);
+ case MINUTELY:
+ cal.set(Calendar.SECOND, 0);
+ case SECONDLY:
+ case CONTINUOUS:
+ cal.set(Calendar.MILLISECOND, 0);
+ break;
+ }
+ return cal.getTime();
+ }
+
public static class UpdatePeriodComparator implements Comparator<UpdatePeriod> {
@Override
public int compare(UpdatePeriod o1, UpdatePeriod o2) {
@@ -306,7 +386,7 @@ public enum UpdatePeriod implements Named {
return -1;
} else if (o1 != null && o2 == null) {
return 1;
- } else if (o1 == null && o2 == null) {
+ } else if (o1 == null) {
return 0;
} else {
if (o1.weight > o2.weight) {
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/EndsAndHolesPartitionTimeline.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/EndsAndHolesPartitionTimeline.java b/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/EndsAndHolesPartitionTimeline.java
index 9d5e264..c588dc7 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/EndsAndHolesPartitionTimeline.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/metadata/timeline/EndsAndHolesPartitionTimeline.java
@@ -23,8 +23,8 @@ import java.util.*;
import org.apache.lens.cube.metadata.MetastoreUtil;
import org.apache.lens.cube.metadata.TimePartition;
+import org.apache.lens.cube.metadata.TimeRange;
import org.apache.lens.cube.metadata.UpdatePeriod;
-import org.apache.lens.cube.parse.TimeRange;
import org.apache.lens.server.api.error.LensException;
import com.google.common.base.Strings;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
index 7f81461..1884bde 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateFact.java
@@ -22,10 +22,7 @@ import static org.apache.hadoop.hive.ql.parse.HiveParser.*;
import java.util.*;
-import org.apache.lens.cube.metadata.AbstractCubeTable;
-import org.apache.lens.cube.metadata.CubeFactTable;
-import org.apache.lens.cube.metadata.CubeInterface;
-import org.apache.lens.cube.metadata.FactPartition;
+import org.apache.lens.cube.metadata.*;
import org.apache.lens.cube.parse.HQLParser.ASTNodeVisitor;
import org.apache.lens.cube.parse.HQLParser.TreeNode;
import org.apache.lens.server.api.error.LensException;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTablePruneCause.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTablePruneCause.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTablePruneCause.java
index 9c8b5b9..78fb21d 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTablePruneCause.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/CandidateTablePruneCause.java
@@ -22,6 +22,8 @@ import static org.apache.lens.cube.parse.CandidateTablePruneCause.CandidateTable
import java.util.*;
+import org.apache.lens.cube.metadata.TimeRange;
+
import org.codehaus.jackson.annotate.JsonWriteNullProperties;
import com.google.common.collect.Lists;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
deleted file mode 100644
index cd05c68..0000000
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/DateUtil.java
+++ /dev/null
@@ -1,456 +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.cube.parse;
-
-import static java.util.Calendar.*;
-
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.apache.lens.cube.error.LensCubeErrorCode;
-import org.apache.lens.cube.metadata.UpdatePeriod;
-import org.apache.lens.server.api.error.LensException;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.commons.lang.time.DateUtils;
-
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public final class DateUtil {
- private DateUtil() {
-
- }
- /*
- * NOW -> new java.util.Date() NOW-7DAY -> a date one week earlier NOW (+-)
- * <NUM>UNIT or Hardcoded dates in DD-MM-YYYY hh:mm:ss,sss
- */
- public static final String UNIT;
-
- static {
- StringBuilder sb = new StringBuilder();
- String sep = "";
- for (UpdatePeriod up : UpdatePeriod.values()) {
- sb.append(sep).append(up.getUnitName());
- sep = "|";
- }
- UNIT = sb.toString();
- }
-
- public static final String GRANULARITY = "\\.(" + UNIT + ")";
- public static final String RELATIVE = "(now)(" + GRANULARITY + ")?";
- public static final Pattern P_RELATIVE = Pattern.compile(RELATIVE, Pattern.CASE_INSENSITIVE);
-
- public static final String WSPACE = "\\s+";
- public static final String OPTIONAL_WSPACE = "\\s*";
-
- public static final String SIGNAGE = "\\+|\\-";
- public static final Pattern P_SIGNAGE = Pattern.compile(SIGNAGE);
-
- public static final String QUANTITY = "\\d+";
- public static final Pattern P_QUANTITY = Pattern.compile(QUANTITY);
-
- public static final Pattern P_UNIT = Pattern.compile(UNIT, Pattern.CASE_INSENSITIVE);
-
- public static final String RELDATE_VALIDATOR_STR = RELATIVE + OPTIONAL_WSPACE + "((" + SIGNAGE + ")" + "("
- + WSPACE + ")?" + "(" + QUANTITY + ")" + OPTIONAL_WSPACE + "(" + UNIT + "))?" + "(s?)";
-
- public static final Pattern RELDATE_VALIDATOR = Pattern.compile(RELDATE_VALIDATOR_STR, Pattern.CASE_INSENSITIVE);
-
- public static final String YEAR_FMT = "[0-9]{4}";
- public static final String MONTH_FMT = YEAR_FMT + "-[0-9]{2}";
- public static final String DAY_FMT = MONTH_FMT + "-[0-9]{2}";
- public static final String HOUR_FMT = DAY_FMT + "-[0-9]{2}";
- public static final String MINUTE_FMT = HOUR_FMT + ":[0-9]{2}";
- public static final String SECOND_FMT = MINUTE_FMT + ":[0-9]{2}";
- public static final String MILLISECOND_FMT = SECOND_FMT + ",[0-9]{3}";
- public static final String ABSDATE_FMT = "yyyy-MM-dd-HH:mm:ss,SSS";
- public static final String HIVE_QUERY_DATE_FMT = "yyyy-MM-dd HH:mm:ss";
-
- public static final ThreadLocal<DateFormat> ABSDATE_PARSER =
- new ThreadLocal<DateFormat>() {
- @Override
- protected SimpleDateFormat initialValue() {
- return new SimpleDateFormat(ABSDATE_FMT);
- }
- };
- public static final ThreadLocal<DateFormat> HIVE_QUERY_DATE_PARSER =
- new ThreadLocal<DateFormat>() {
- @Override
- protected SimpleDateFormat initialValue() {
- return new SimpleDateFormat(HIVE_QUERY_DATE_FMT);
- }
- };
-
- public static String getAbsDateFormatString(String str) {
- if (str.matches(YEAR_FMT)) {
- return str + "-01-01-00:00:00,000";
- } else if (str.matches(MONTH_FMT)) {
- return str + "-01-00:00:00,000";
- } else if (str.matches(DAY_FMT)) {
- return str + "-00:00:00,000";
- } else if (str.matches(HOUR_FMT)) {
- return str + ":00:00,000";
- } else if (str.matches(MINUTE_FMT)) {
- return str + ":00,000";
- } else if (str.matches(SECOND_FMT)) {
- return str + ",000";
- } else if (str.matches(MILLISECOND_FMT)) {
- return str;
- }
- throw new IllegalArgumentException("Unsupported formatting for date" + str);
- }
-
- public static Date resolveDate(String str, Date now) throws LensException {
- if (RELDATE_VALIDATOR.matcher(str).matches()) {
- return resolveRelativeDate(str, now);
- } else {
- return resolveAbsoluteDate(str);
- }
- }
-
- public static String relativeToAbsolute(String relative) throws LensException {
- return relativeToAbsolute(relative, new Date());
- }
-
- public static String relativeToAbsolute(String relative, Date now) throws LensException {
- if (RELDATE_VALIDATOR.matcher(relative).matches()) {
- return ABSDATE_PARSER.get().format(resolveRelativeDate(relative, now));
- } else {
- return relative;
- }
- }
-
- public static Date resolveAbsoluteDate(String str) throws LensException {
- try {
- return ABSDATE_PARSER.get().parse(getAbsDateFormatString(str));
- } catch (ParseException e) {
- log.error("Invalid date format. expected only {} date provided:{}", ABSDATE_FMT, str, e);
- throw new LensException(LensCubeErrorCode.WRONG_TIME_RANGE_FORMAT.getLensErrorInfo(), ABSDATE_FMT, str);
- }
- }
-
- public static Date resolveRelativeDate(String str, Date now) throws LensException {
- if (StringUtils.isBlank(str)) {
- throw new LensException(LensCubeErrorCode.NULL_DATE_VALUE.getLensErrorInfo());
- }
-
- // Resolve NOW with proper granularity
- Calendar calendar = Calendar.getInstance();
- calendar.setTime(now);
-
- str = str.toLowerCase();
- Matcher relativeMatcher = P_RELATIVE.matcher(str);
- if (relativeMatcher.find()) {
- String nowWithGranularity = relativeMatcher.group();
- nowWithGranularity = nowWithGranularity.replaceAll("now", "");
- nowWithGranularity = nowWithGranularity.replaceAll("\\.", "");
-
- Matcher granularityMatcher = P_UNIT.matcher(nowWithGranularity);
- if (granularityMatcher.find()) {
- calendar = UpdatePeriod.fromUnitName(granularityMatcher.group().toLowerCase()).truncate(calendar);
- }
- }
-
- // Get rid of 'now' part and whitespace
- String diffStr = str.replaceAll(RELATIVE, "").replace(WSPACE, "");
- TimeDiff diff = TimeDiff.parseFrom(diffStr);
- return diff.offsetFrom(calendar.getTime());
- }
-
- public static Date getCeilDate(Date fromDate, UpdatePeriod interval) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(fromDate);
- boolean hasFraction = false;
- switch (interval) {
- case YEARLY:
- if (cal.get(MONTH) != 0) {
- hasFraction = true;
- break;
- }
- case MONTHLY:
- if (cal.get(DAY_OF_MONTH) != 1) {
- hasFraction = true;
- break;
- }
- case DAILY:
- if (cal.get(Calendar.HOUR_OF_DAY) != 0) {
- hasFraction = true;
- break;
- }
- case HOURLY:
- if (cal.get(Calendar.MINUTE) != 0) {
- hasFraction = true;
- break;
- }
- case MINUTELY:
- if (cal.get(Calendar.SECOND) != 0) {
- hasFraction = true;
- break;
- }
- case SECONDLY:
- case CONTINUOUS:
- if (cal.get(Calendar.MILLISECOND) != 0) {
- hasFraction = true;
- }
- break;
- case WEEKLY:
- if (cal.get(Calendar.DAY_OF_WEEK) != 1) {
- hasFraction = true;
- break;
- }
- }
-
- if (hasFraction) {
- cal.add(interval.calendarField(), 1);
- return getFloorDate(cal.getTime(), interval);
- } else {
- return fromDate;
- }
- }
-
- public static Date getFloorDate(Date toDate, UpdatePeriod interval) {
- Calendar cal = Calendar.getInstance();
- cal.setTime(toDate);
- switch (interval) {
- case YEARLY:
- cal.set(MONTH, 0);
- case MONTHLY:
- cal.set(DAY_OF_MONTH, 1);
- case DAILY:
- cal.set(Calendar.HOUR_OF_DAY, 0);
- case HOURLY:
- cal.set(Calendar.MINUTE, 0);
- case MINUTELY:
- cal.set(Calendar.SECOND, 0);
- case SECONDLY:
- case CONTINUOUS:
- cal.set(Calendar.MILLISECOND, 0);
- break;
- case WEEKLY:
- cal.set(Calendar.DAY_OF_WEEK, 1);
- cal.set(Calendar.HOUR_OF_DAY, 0);
- cal.set(Calendar.MINUTE, 0);
- cal.set(Calendar.SECOND, 0);
- cal.set(Calendar.MILLISECOND, 0);
- break;
- }
- return cal.getTime();
- }
-
- public static CoveringInfo getMonthlyCoveringInfo(Date from, Date to) {
- // Move 'from' to end of month, unless its the first day of month
- boolean coverable = true;
- if (!from.equals(DateUtils.truncate(from, MONTH))) {
- from = DateUtils.addMonths(DateUtils.truncate(from, MONTH), 1);
- coverable = false;
- }
-
- // Move 'to' to beginning of next month, unless its the first day of the month
- if (!to.equals(DateUtils.truncate(to, MONTH))) {
- to = DateUtils.truncate(to, MONTH);
- coverable = false;
- }
-
- int months = 0;
- while (from.before(to)) {
- from = DateUtils.addMonths(from, 1);
- months++;
- }
- return new CoveringInfo(months, coverable);
- }
-
- public static CoveringInfo getQuarterlyCoveringInfo(Date from, Date to) {
- CoveringInfo monthlyCoveringInfo = getMonthlyCoveringInfo(from, to);
- if (monthlyCoveringInfo.getCountBetween() < 3) {
- return new CoveringInfo(0, false);
- }
- boolean coverable = monthlyCoveringInfo.isCoverable();
- if (!from.equals(DateUtils.truncate(from, MONTH))) {
- from = DateUtils.addMonths(DateUtils.truncate(from, MONTH), 1);
- coverable = false;
- }
- Calendar cal = Calendar.getInstance();
- cal.setTime(from);
- int fromMonth = cal.get(MONTH);
-
- // Get the start date of the quarter
- int beginOffset = (3 - fromMonth % 3) % 3;
- int endOffset = (monthlyCoveringInfo.getCountBetween() - beginOffset) % 3;
- if (beginOffset > 0 || endOffset > 0) {
- coverable = false;
- }
- return new CoveringInfo((monthlyCoveringInfo.getCountBetween() - beginOffset - endOffset) / 3, coverable);
- }
-
-
- public static CoveringInfo getYearlyCoveringInfo(Date from, Date to) {
- CoveringInfo monthlyCoveringInfo = getMonthlyCoveringInfo(from, to);
- if (monthlyCoveringInfo.getCountBetween() < 12) {
- return new CoveringInfo(0, false);
- }
- boolean coverable = monthlyCoveringInfo.isCoverable();
- if (!from.equals(DateUtils.truncate(from, MONTH))) {
- from = DateUtils.addMonths(DateUtils.truncate(from, MONTH), 1);
- coverable = false;
- }
- Calendar cal = Calendar.getInstance();
- cal.setTime(from);
- int fromMonth = cal.get(MONTH);
- int beginOffset = (12 - fromMonth % 12) % 12;
- int endOffset = (monthlyCoveringInfo.getCountBetween() - beginOffset) % 12;
- if (beginOffset > 0 || endOffset > 0) {
- coverable = false;
- }
- return new CoveringInfo((monthlyCoveringInfo.getCountBetween() - beginOffset - endOffset) / 12, coverable);
- }
-
- public static CoveringInfo getWeeklyCoveringInfo(Date from, Date to) {
- int dayDiff = 0;
- Date tmpFrom = from;
- while (tmpFrom.before(to)) {
- tmpFrom = DateUtils.addDays(tmpFrom, 1);
- dayDiff++;
- }
-
- if (dayDiff < 7) {
- return new CoveringInfo(0, false);
- }
-
- Calendar cal = Calendar.getInstance();
- cal.setTime(from);
- int fromDay = cal.get(Calendar.DAY_OF_WEEK);
- cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
- Date fromWeekStartDate = cal.getTime();
- boolean coverable = dayDiff % 7 == 0;
- if (fromWeekStartDate.before(from)) {
- // Count from the start of next week
- dayDiff -= (cal.getActualMaximum(Calendar.DAY_OF_WEEK) - (fromDay - Calendar.SUNDAY));
- coverable = false;
- }
-
- return new CoveringInfo(dayDiff / 7, coverable);
- }
-
- static CoveringInfo getCoveringInfo(Date from, Date to, UpdatePeriod interval) {
- switch (interval) {
- case SECONDLY:
- case CONTINUOUS:
- return getMilliSecondCoveringInfo(from, to, 1000);
- case MINUTELY:
- case HOURLY:
- case DAILY:
- return getMilliSecondCoveringInfo(from, to, interval.weight());
- case WEEKLY:
- return getWeeklyCoveringInfo(from, to);
- case MONTHLY:
- return getMonthlyCoveringInfo(from, to);
- case QUARTERLY:
- return getQuarterlyCoveringInfo(from, to);
- case YEARLY:
- return getYearlyCoveringInfo(from, to);
- default:
- return new CoveringInfo(0, false);
- }
- }
-
- private static CoveringInfo getMilliSecondCoveringInfo(Date from, Date to, long millisInInterval) {
- long diff = to.getTime() - from.getTime();
- return new CoveringInfo((int) (diff / millisInInterval), diff % millisInInterval == 0);
- }
-
- static boolean isCoverableBy(Date from, Date to, Set<UpdatePeriod> intervals) {
- for (UpdatePeriod period : intervals) {
- if (getCoveringInfo(from, to, period).isCoverable()) {
- return true;
- }
- }
- return false;
- }
-
- public static int getTimeDiff(Date fromDate, Date toDate, UpdatePeriod updatePeriod) {
- if (fromDate.before(toDate)) {
- return getCoveringInfo(fromDate, toDate, updatePeriod).getCountBetween();
- } else {
- return -getCoveringInfo(toDate, fromDate, updatePeriod).getCountBetween();
- }
- }
-
- @Data
- public static class CoveringInfo {
- int countBetween;
- boolean coverable;
-
- public CoveringInfo(int countBetween, boolean coverable) {
- this.countBetween = countBetween;
- this.coverable = coverable;
- }
- }
-
- @EqualsAndHashCode
- public static class TimeDiff {
- int quantity;
- UpdatePeriod updatePeriod;
-
- private TimeDiff(int quantity, UpdatePeriod updatePeriod) {
- this.quantity = quantity;
- this.updatePeriod = updatePeriod;
- }
-
- public static TimeDiff parseFrom(String diffStr) throws LensException {
- // Get the relative diff part to get eventual date based on now.
- Matcher qtyMatcher = P_QUANTITY.matcher(diffStr);
- int qty = 1;
- if (qtyMatcher.find()) {
- qty = Integer.parseInt(qtyMatcher.group());
- }
-
- Matcher signageMatcher = P_SIGNAGE.matcher(diffStr);
- if (signageMatcher.find()) {
- String sign = signageMatcher.group();
- if ("-".equals(sign)) {
- qty = -qty;
- }
- }
-
- Matcher unitMatcher = P_UNIT.matcher(diffStr);
- if (unitMatcher.find()) {
- return new TimeDiff(qty, UpdatePeriod.fromUnitName(unitMatcher.group().toLowerCase()));
- }
- return new TimeDiff(0, UpdatePeriod.CONTINUOUS);
- }
-
- public Date offsetFrom(Date time) {
- return DateUtils.add(time, updatePeriod.calendarField(), quantity);
- }
-
- public Date negativeOffsetFrom(Date time) {
- return DateUtils.add(time, updatePeriod.calendarField(), -quantity);
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
index 200a48c..776021d 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/ExpressionResolver.java
@@ -19,18 +19,11 @@
package org.apache.lens.cube.parse;
-import static org.apache.hadoop.hive.ql.parse.HiveParser.DOT;
-import static org.apache.hadoop.hive.ql.parse.HiveParser.Identifier;
-import static org.apache.hadoop.hive.ql.parse.HiveParser.TOK_TABLE_OR_COL;
+import static org.apache.hadoop.hive.ql.parse.HiveParser.*;
import java.util.*;
-import org.apache.lens.cube.metadata.AbstractBaseTable;
-import org.apache.lens.cube.metadata.AbstractCubeTable;
-import org.apache.lens.cube.metadata.CubeColumn;
-import org.apache.lens.cube.metadata.CubeInterface;
-import org.apache.lens.cube.metadata.Dimension;
-import org.apache.lens.cube.metadata.ExprColumn;
+import org.apache.lens.cube.metadata.*;
import org.apache.lens.cube.metadata.ExprColumn.ExprSpec;
import org.apache.lens.cube.parse.CandidateTablePruneCause.CandidateTablePruneCode;
import org.apache.lens.cube.parse.HQLParser.ASTNodeVisitor;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactHQLContext.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactHQLContext.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactHQLContext.java
index 60b2dde..f7271e5 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactHQLContext.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/SingleFactHQLContext.java
@@ -21,7 +21,7 @@ package org.apache.lens.cube.parse;
import java.util.Map;
import org.apache.lens.cube.metadata.Dimension;
-
+import org.apache.lens.cube.metadata.TimeRange;
import org.apache.lens.server.api.error.LensException;
import org.apache.commons.lang.StringUtils;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
index cc8e68c..62cc071 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/StorageTableResolver.java
@@ -18,6 +18,7 @@
*/
package org.apache.lens.cube.parse;
+import static org.apache.lens.cube.metadata.DateUtil.WSPACE;
import static org.apache.lens.cube.metadata.MetastoreUtil.getFactOrDimtableStorageTableName;
import static org.apache.lens.cube.metadata.MetastoreUtil.getStoragetableEndTimesKey;
import static org.apache.lens.cube.metadata.MetastoreUtil.getStoragetableStartTimesKey;
@@ -25,7 +26,6 @@ import static org.apache.lens.cube.parse.CandidateTablePruneCause.*;
import static org.apache.lens.cube.parse.CandidateTablePruneCause.CandidateTablePruneCode.*;
import static org.apache.lens.cube.parse.CandidateTablePruneCause.SkipStorageCode.PART_COL_DOES_NOT_EXIST;
import static org.apache.lens.cube.parse.CandidateTablePruneCause.SkipStorageCode.RANGE_NOT_ANSWERABLE;
-import static org.apache.lens.cube.parse.DateUtil.WSPACE;
import static org.apache.lens.cube.parse.StorageUtil.joinWithAnd;
import java.text.DateFormat;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
deleted file mode 100644
index 7be7ace..0000000
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimeRange.java
+++ /dev/null
@@ -1,220 +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.cube.parse;
-
-import static org.apache.lens.cube.parse.DateUtil.ABSDATE_PARSER;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TreeSet;
-
-import org.apache.lens.cube.error.LensCubeErrorCode;
-import org.apache.lens.cube.metadata.UpdatePeriod;
-import org.apache.lens.server.api.error.LensException;
-
-import org.apache.commons.lang.StringUtils;
-import org.apache.hadoop.hive.ql.parse.ASTNode;
-
-import org.codehaus.jackson.annotate.JsonIgnoreProperties;
-
-import lombok.Data;
-import lombok.Getter;
-
-/**
- * Timerange data structure
- */
-@JsonIgnoreProperties({"astNode", "parent"})
-@Data
-public class TimeRange {
- private String partitionColumn;
- private Date toDate;
- private Date fromDate;
- private ASTNode astNode;
- private ASTNode parent;
- private int childIndex;
-
- public boolean isCoverableBy(TreeSet<UpdatePeriod> updatePeriods) {
- return DateUtil.isCoverableBy(fromDate, toDate, updatePeriods);
- }
-
-
- public static class TimeRangeBuilder {
- private final TimeRange range;
-
- public TimeRangeBuilder() {
- this.range = new TimeRange();
- }
-
- public TimeRangeBuilder partitionColumn(String col) {
- range.partitionColumn = col;
- return this;
- }
-
- public TimeRangeBuilder toDate(Date to) {
- range.toDate = to;
- return this;
- }
-
- public TimeRangeBuilder fromDate(Date from) {
- range.fromDate = from;
- return this;
- }
-
- public TimeRangeBuilder astNode(ASTNode node) {
- range.astNode = node;
- return this;
- }
-
- public TimeRangeBuilder parent(ASTNode parent) {
- range.parent = parent;
- return this;
- }
-
- public TimeRangeBuilder childIndex(int childIndex) {
- range.childIndex = childIndex;
- return this;
- }
-
- public TimeRange build() {
- return range;
- }
- }
-
- public static TimeRangeBuilder getBuilder() {
- return new TimeRangeBuilder();
- }
-
- private TimeRange() {
-
- }
-
- public void validate() throws LensException {
- if (partitionColumn == null || fromDate == null || toDate == null || fromDate.equals(toDate)) {
- throw new LensException(LensCubeErrorCode.INVALID_TIME_RANGE.getLensErrorInfo());
- }
-
- if (fromDate.after(toDate)) {
- throw new LensException(LensCubeErrorCode.FROM_AFTER_TO.getLensErrorInfo(),
- fromDate.toString(), toDate.toString());
- }
- }
-
- public String toTimeDimWhereClause() {
- return toTimeDimWhereClause(null, partitionColumn);
- }
-
- public String toTimeDimWhereClause(String prefix, String column) {
- if (StringUtils.isNotBlank(column)) {
- column = prefix + "." + column;
- }
- return new StringBuilder()
- .append(column).append(" >= '").append(DateUtil.HIVE_QUERY_DATE_PARSER.get().format(fromDate)).append("'")
- .append(" AND ")
- .append(column).append(" < '").append(DateUtil.HIVE_QUERY_DATE_PARSER.get().format(toDate)).append("'")
- .toString();
- }
-
- @Override
- public String toString() {
- return partitionColumn + " [" + ABSDATE_PARSER.get().format(fromDate) + " to "
- + ABSDATE_PARSER.get().format(toDate) + ")";
- }
-
- /** iterable from fromDate(including) to toDate(excluding) incrementing increment units of updatePeriod */
- public static Iterable iterable(Date fromDate, Date toDate, UpdatePeriod updatePeriod, int increment) {
- return TimeRange.getBuilder().fromDate(fromDate).toDate(toDate).build().iterable(updatePeriod, increment);
- }
-
- /** iterable from fromDate(including) incrementing increment units of updatePeriod. Do this numIters times */
- public static Iterable iterable(Date fromDate, int numIters, UpdatePeriod updatePeriod, int increment) {
- return TimeRange.getBuilder().fromDate(fromDate).build().iterable(updatePeriod, numIters, increment);
- }
-
- private Iterable iterable(UpdatePeriod updatePeriod, int numIters, int increment) {
- return new Iterable(updatePeriod, numIters, increment);
- }
-
- public Iterable iterable(UpdatePeriod updatePeriod, int increment) {
- if (increment == 0) {
- throw new UnsupportedOperationException("Can't iterate if iteration increment is zero");
- }
- long numIters = DateUtil.getTimeDiff(fromDate, toDate, updatePeriod) / increment;
- return new Iterable(updatePeriod, numIters, increment);
- }
-
- /** Iterable so that foreach is supported */
- public class Iterable implements java.lang.Iterable<Date> {
- private UpdatePeriod updatePeriod;
- private long numIters;
- private int increment;
-
- public Iterable(UpdatePeriod updatePeriod, long numIters, int increment) {
- this.updatePeriod = updatePeriod;
- this.numIters = numIters;
- if (this.numIters < 0) {
- this.numIters = 0;
- }
- this.increment = increment;
- }
-
- @Override
- public Iterator iterator() {
- return new Iterator();
- }
-
- public class Iterator implements java.util.Iterator<Date> {
- Calendar calendar;
- // Tracks the index of the item returned after the last next() call.
- // Index here refers to the index if the iterator were iterated and converted into a list.
- @Getter
- int counter = -1;
-
- public Iterator() {
- calendar = Calendar.getInstance();
- calendar.setTime(fromDate);
- }
-
- @Override
- public boolean hasNext() {
- return counter < numIters - 1;
- }
-
- @Override
- public Date next() {
- Date cur = calendar.getTime();
- updatePeriod.increment(calendar, increment);
- counter++;
- return cur;
- }
-
- public Date peekNext() {
- return calendar.getTime();
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("remove from timerange iterator");
- }
-
- public long getNumIters() {
- return numIters;
- }
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
index f772279..1a83d09 100644
--- a/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
+++ b/lens-cube/src/main/java/org/apache/lens/cube/parse/TimerangeResolver.java
@@ -27,10 +27,7 @@ import java.util.*;
import org.apache.lens.cube.error.ColUnAvailableInTimeRange;
import org.apache.lens.cube.error.ColUnAvailableInTimeRangeException;
import org.apache.lens.cube.error.LensCubeErrorCode;
-import org.apache.lens.cube.metadata.AbstractCubeTable;
-import org.apache.lens.cube.metadata.CubeColumn;
-import org.apache.lens.cube.metadata.Dimension;
-import org.apache.lens.cube.metadata.SchemaGraph;
+import org.apache.lens.cube.metadata.*;
import org.apache.lens.cube.parse.DenormalizationResolver.ReferencedQueriedColumn;
import org.apache.lens.server.api.error.LensException;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/test/java/org/apache/lens/cube/metadata/CubeFactTableTest.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/metadata/CubeFactTableTest.java b/lens-cube/src/test/java/org/apache/lens/cube/metadata/CubeFactTableTest.java
index 2abc6d0..25eaaef 100644
--- a/lens-cube/src/test/java/org/apache/lens/cube/metadata/CubeFactTableTest.java
+++ b/lens-cube/src/test/java/org/apache/lens/cube/metadata/CubeFactTableTest.java
@@ -26,7 +26,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.Map;
-import org.apache.lens.cube.parse.DateUtil;
import org.apache.lens.server.api.error.LensException;
import org.testng.annotations.DataProvider;
http://git-wip-us.apache.org/repos/asf/lens/blob/7c7c86da/lens-cube/src/test/java/org/apache/lens/cube/metadata/DateFactory.java
----------------------------------------------------------------------
diff --git a/lens-cube/src/test/java/org/apache/lens/cube/metadata/DateFactory.java b/lens-cube/src/test/java/org/apache/lens/cube/metadata/DateFactory.java
new file mode 100644
index 0000000..87e4ce3
--- /dev/null
+++ b/lens-cube/src/test/java/org/apache/lens/cube/metadata/DateFactory.java
@@ -0,0 +1,196 @@
+/**
+ * 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.cube.metadata;
+
+
+import static org.apache.lens.cube.metadata.UpdatePeriod.*;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+
+public class DateFactory {
+ private DateFactory() {
+
+ }
+
+ public static class DateOffsetProvider extends HashMap<Integer, Date> {
+ private final UpdatePeriod updatePeriod;
+ Calendar calendar = Calendar.getInstance();
+
+ public DateOffsetProvider(UpdatePeriod updatePeriod) {
+ this(updatePeriod, false);
+ }
+
+ public DateOffsetProvider(UpdatePeriod updatePeriod, boolean truncate) {
+ this.updatePeriod = updatePeriod;
+ Date date = calendar.getTime();
+ if (truncate) {
+ date = updatePeriod.truncate(date);
+ calendar.setTime(date);
+ }
+ put(0, date);
+ }
+
+ @Override
+ public Date get(Object key) {
+ if (!containsKey(key) && key instanceof Integer) {
+ calendar.setTime(super.get(0));
+ calendar.add(updatePeriod.calendarField(), (Integer) key);
+ put((Integer) key, calendar.getTime());
+ }
+ return super.get(key);
+ }
+ }
+
+ public static class GeneralDateOffsetProvider extends HashMap<UpdatePeriod, DateOffsetProvider> {
+ @Override
+ public DateOffsetProvider get(Object key) {
+ if (!containsKey(key) && key instanceof UpdatePeriod) {
+ UpdatePeriod up = (UpdatePeriod) key;
+ put(up, new DateOffsetProvider(up));
+ }
+ return super.get(key);
+ }
+
+ public Date get(UpdatePeriod updatePeriod, int offset) {
+ return get(updatePeriod).get(offset);
+ }
+ }
+
+ public static final GeneralDateOffsetProvider GENERAL_DATE_OFFSET_PROVIDER = new GeneralDateOffsetProvider();
+
+
+ public static Date getDateWithOffset(UpdatePeriod up, int offset) {
+ return GENERAL_DATE_OFFSET_PROVIDER.get(up, offset);
+ }
+
+ public static String getDateStringWithOffset(UpdatePeriod up, int offset) {
+ return getDateStringWithOffset(up, offset, up);
+ }
+
+ public static String getDateStringWithOffset(UpdatePeriod up, int offset, UpdatePeriod formatWith) {
+ return formatWith.format(GENERAL_DATE_OFFSET_PROVIDER.get(up, offset));
+ }
+
+ public static String getTimeRangeString(final String timeDim, final String startDate, final String endDate) {
+ return "time_range_in(" + timeDim + ", '" + startDate + "','" + endDate + "')";
+ }
+
+ public static String getTimeRangeString(final String timeDim, final UpdatePeriod updatePeriod,
+ final int startOffset, final int endOffset) {
+ return getTimeRangeString(timeDim,
+ getDateStringWithOffset(updatePeriod, startOffset), getDateStringWithOffset(updatePeriod, endOffset));
+ }
+
+ public static String getTimeRangeString(final String startDate, final String endDate) {
+ return getTimeRangeString("d_time", startDate, endDate);
+ }
+
+ public static String getTimeRangeString(final UpdatePeriod updatePeriod,
+ final int startOffset, final int endOffset) {
+ return getTimeRangeString("d_time", updatePeriod, startOffset, endOffset);
+ }
+
+ public static String getTimeRangeString(String partCol, UpdatePeriod updatePeriod, int startOffset, int endOffset,
+ UpdatePeriod formatWith) {
+ return getTimeRangeString(partCol,
+ formatWith.format(getDateWithOffset(updatePeriod, startOffset)),
+ formatWith.format(getDateWithOffset(updatePeriod, endOffset)));
+ }
+
+ public static String getTimeRangeString(String partCol, UpdatePeriod updatePeriod, int startOffset, int endOffset,
+ DateFormat formatWith) {
+ return getTimeRangeString(partCol,
+ formatWith.format(getDateWithOffset(updatePeriod, startOffset)),
+ formatWith.format(getDateWithOffset(updatePeriod, endOffset)));
+ }
+
+ public static String getTimeRangeString(UpdatePeriod updatePeriod, int startOffset, int endOffset,
+ UpdatePeriod formatWith) {
+ return getTimeRangeString("d_time", updatePeriod, startOffset, endOffset, formatWith);
+ }
+
+ public static String getTimeRangeString(UpdatePeriod updatePeriod, int startOffset, int endOffset,
+ DateFormat formatWith) {
+ return getTimeRangeString("d_time", updatePeriod, startOffset, endOffset, formatWith);
+ }
+
+ // Time Instances as Date Type
+ public static final Date NOW;
+ public static final Date TWODAYS_BACK;
+ public static final Date TWO_MONTHS_BACK;
+ public static final Date BEFORE_6_DAYS;
+ public static final Date BEFORE_4_DAYS;
+
+ // Time Ranges
+ public static final String LAST_HOUR_TIME_RANGE;
+ public static final String TWO_DAYS_RANGE;
+ public static final String TWO_DAYS_RANGE_TTD;
+ public static final String TWO_DAYS_RANGE_TTD_BEFORE_4_DAYS;
+ public static final String TWO_DAYS_RANGE_TTD2;
+ public static final String TWO_DAYS_RANGE_TTD2_BEFORE_4_DAYS;
+ public static final String TWO_DAYS_RANGE_IT;
+ public static final String THIS_YEAR_RANGE;
+ public static final String LAST_YEAR_RANGE;
+ public static final String TWO_MONTHS_RANGE_UPTO_MONTH;
+ public static final String TWO_MONTHS_RANGE_UPTO_HOURS;
+ public static final String TWO_DAYS_RANGE_BEFORE_4_DAYS;
+ private static boolean zerothHour;
+
+
+ public static boolean isZerothHour() {
+ return zerothHour;
+ }
+
+ static {
+ NOW = getDateWithOffset(HOURLY, 0);
+
+ // Figure out if current hour is 0th hour
+ zerothHour = getDateStringWithOffset(HOURLY, 0).endsWith("-00");
+
+ TWODAYS_BACK = getDateWithOffset(DAILY, -2);
+ System.out.println("Test TWODAYS_BACK:" + TWODAYS_BACK);
+
+ // two months back
+ TWO_MONTHS_BACK = getDateWithOffset(MONTHLY, -2);
+ System.out.println("Test TWO_MONTHS_BACK:" + TWO_MONTHS_BACK);
+
+ // Before 4days
+ BEFORE_4_DAYS = getDateWithOffset(DAILY, -4);
+ BEFORE_6_DAYS = getDateWithOffset(DAILY, -6);
+
+ TWO_DAYS_RANGE_BEFORE_4_DAYS = getTimeRangeString(DAILY, -6, -4, HOURLY);
+
+ TWO_DAYS_RANGE = getTimeRangeString(HOURLY, -48, 0);
+ TWO_DAYS_RANGE_TTD = getTimeRangeString("test_time_dim", DAILY, -2, 0, HOURLY);
+ TWO_DAYS_RANGE_TTD_BEFORE_4_DAYS = getTimeRangeString("test_time_dim", DAILY, -6, -4, HOURLY);
+ TWO_DAYS_RANGE_TTD2 = getTimeRangeString("test_time_dim2", DAILY, -2, 0, HOURLY);
+ TWO_DAYS_RANGE_TTD2_BEFORE_4_DAYS = getTimeRangeString("test_time_dim2", DAILY, -6, -4, HOURLY);
+ TWO_DAYS_RANGE_IT = getTimeRangeString("it", DAILY, -2, 0, HOURLY);
+ THIS_YEAR_RANGE = getTimeRangeString(YEARLY, 0, 1);
+ LAST_YEAR_RANGE = getTimeRangeString(YEARLY, -1, 0);
+ TWO_MONTHS_RANGE_UPTO_MONTH = getTimeRangeString(MONTHLY, -2, 0);
+ TWO_MONTHS_RANGE_UPTO_HOURS = getTimeRangeString(MONTHLY, -2, 0, HOURLY);
+
+ // calculate LAST_HOUR_TIME_RANGE
+ LAST_HOUR_TIME_RANGE = getTimeRangeString(HOURLY, -1, 0);
+ }
+}