diff --git a/processing/src/main/java/io/druid/granularity/QueryGranularity.java b/processing/src/main/java/io/druid/granularity/QueryGranularity.java index 9af63943340..4cb653a4100 100644 --- a/processing/src/main/java/io/druid/granularity/QueryGranularity.java +++ b/processing/src/main/java/io/druid/granularity/QueryGranularity.java @@ -20,10 +20,14 @@ package io.druid.granularity; import com.fasterxml.jackson.annotation.JsonCreator; +import com.google.common.collect.ImmutableMap; import com.metamx.common.IAE; import org.joda.time.DateTime; +import org.joda.time.Period; import org.joda.time.ReadableDuration; +import java.util.Map; + public abstract class QueryGranularity { public abstract long next(long offset); @@ -39,11 +43,23 @@ public abstract class QueryGranularity public static final QueryGranularity ALL = new AllGranularity(); public static final QueryGranularity NONE = new NoneGranularity(); + private static final Map CALENDRIC_GRANULARITIES = ImmutableMap.of( + "YEAR", new PeriodGranularity(new Period("P1Y"), null, null), + "MONTH", new PeriodGranularity(new Period("P1M"), null, null), + "QUARTER", new PeriodGranularity(new Period("P3M"), null, null), + "WEEK", new PeriodGranularity(new Period("P1W"), null, null) + ); + public static final QueryGranularity MINUTE = fromString("MINUTE"); public static final QueryGranularity HOUR = fromString("HOUR"); public static final QueryGranularity DAY = fromString("DAY"); public static final QueryGranularity SECOND = fromString("SECOND"); + public static final QueryGranularity WEEK = fromString("WEEK"); + public static final QueryGranularity MONTH = fromString("MONTH"); + public static final QueryGranularity QUARTER = fromString("QUARTER"); + public static final QueryGranularity YEAR = fromString("YEAR"); + @JsonCreator public static QueryGranularity fromString(String str) { @@ -56,6 +72,10 @@ public abstract class QueryGranularity { return QueryGranularity.NONE; } + else if(CALENDRIC_GRANULARITIES.containsKey(name)) + { + return CALENDRIC_GRANULARITIES.get(name); + } return new DurationGranularity(convertValue(str), 0); } diff --git a/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java b/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java index 0166fa987b2..1369dff6468 100644 --- a/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java +++ b/processing/src/test/java/io/druid/granularity/QueryGranularityTest.java @@ -23,14 +23,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import io.druid.jackson.DefaultObjectMapper; -import org.joda.time.DateTime; -import org.joda.time.DateTimeZone; -import org.joda.time.Days; -import org.joda.time.Hours; -import org.joda.time.Minutes; -import org.joda.time.Months; -import org.joda.time.Period; -import org.joda.time.Weeks; +import org.joda.time.*; import org.junit.Assert; import org.junit.Test; @@ -180,6 +173,130 @@ public class QueryGranularityTest ); } + @Test + public void testIterableWeekSimple() + { + final DateTime baseTime = new DateTime("2011-01-03T00:00:00.000Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2011-01-03T00:00:00.000Z"), + new DateTime("2011-01-10T00:00:00.000Z"), + new DateTime("2011-01-17T00:00:00.000Z") + ), + QueryGranularity.WEEK.iterable(baseTime.getMillis(), baseTime.plus(Weeks.THREE).getMillis()) + ); + } + + @Test + public void testIterableWeekComplex() + { + final DateTime baseTime = new DateTime("2011-01-01T09:38:02.992Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2010-12-27T00:00:00.000Z"), + new DateTime("2011-01-03T00:00:00.000Z"), + new DateTime("2011-01-10T00:00:00.000Z"), + new DateTime("2011-01-17T00:00:00.000Z") + ), + QueryGranularity.WEEK.iterable(baseTime.getMillis(), baseTime.plus(Weeks.THREE).getMillis()) + ); + } + + @Test + public void testIterableMonthSimple() + { + final DateTime baseTime = new DateTime("2011-01-01T00:00:00.000Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2011-01-01T00:00:00.000Z"), + new DateTime("2011-02-01T00:00:00.000Z"), + new DateTime("2011-03-01T00:00:00.000Z") + ), + QueryGranularity.MONTH.iterable(baseTime.getMillis(), baseTime.plus(Months.THREE).getMillis()) + ); + } + + @Test + public void testIterableMonthComplex() + { + final DateTime baseTime = new DateTime("2011-01-01T09:38:00.000Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2011-01-01T00:00:00.000Z"), + new DateTime("2011-02-01T00:00:00.000Z"), + new DateTime("2011-03-01T00:00:00.000Z"), + new DateTime("2011-04-01T00:00:00.000Z") + ), + QueryGranularity.MONTH.iterable(baseTime.getMillis(), baseTime.plus(Months.THREE).getMillis()) + ); + } + + @Test + public void testIterableQuarterSimple() + { + final DateTime baseTime = new DateTime("2011-01-01T00:00:00.000Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2011-01-01T00:00:00.000Z"), + new DateTime("2011-04-01T00:00:00.000Z"), + new DateTime("2011-07-01T00:00:00.000Z") + ), + QueryGranularity.QUARTER.iterable(baseTime.getMillis(), baseTime.plus(Months.NINE).getMillis()) + ); + } + + @Test + public void testIterableQuarterComplex() + { + final DateTime baseTime = new DateTime("2011-01-01T09:38:00.000Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2011-01-01T00:00:00.000Z"), + new DateTime("2011-04-01T00:00:00.000Z"), + new DateTime("2011-07-01T00:00:00.000Z"), + new DateTime("2011-10-01T00:00:00.000Z") + ), + QueryGranularity.QUARTER.iterable(baseTime.getMillis(), baseTime.plus(Months.NINE).getMillis()) + ); + } + + @Test + public void testIterableYearSimple() + { + final DateTime baseTime = new DateTime("2011-01-01T00:00:00.000Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2011-01-01T00:00:00.000Z"), + new DateTime("2012-01-01T00:00:00.000Z"), + new DateTime("2013-01-01T00:00:00.000Z") + ), + QueryGranularity.YEAR.iterable(baseTime.getMillis(), baseTime.plus(Years.THREE).getMillis()) + ); + } + + @Test + public void testIterableYearComplex() + { + final DateTime baseTime = new DateTime("2011-01-01T09:38:00.000Z"); + + assertSame( + Lists.newArrayList( + new DateTime("2011-01-01T00:00:00.000Z"), + new DateTime("2012-01-01T00:00:00.000Z"), + new DateTime("2013-01-01T00:00:00.000Z"), + new DateTime("2014-01-01T00:00:00.000Z") + ), + QueryGranularity.YEAR.iterable(baseTime.getMillis(), baseTime.plus(Years.THREE).getMillis()) + ); + } + @Test public void testPeriodDaylightSaving() throws Exception { @@ -569,6 +686,11 @@ public class QueryGranularityTest Assert.assertEquals(QueryGranularity.HOUR, mapper.readValue("\"hour\"", QueryGranularity.class)); Assert.assertEquals(QueryGranularity.MINUTE, mapper.readValue("\"minute\"", QueryGranularity.class)); + Assert.assertEquals(QueryGranularity.WEEK, mapper.readValue("\"week\"", QueryGranularity.class)); + Assert.assertEquals(QueryGranularity.QUARTER, mapper.readValue("\"quarter\"", QueryGranularity.class)); + Assert.assertEquals(QueryGranularity.MONTH, mapper.readValue("\"month\"", QueryGranularity.class)); + Assert.assertEquals(QueryGranularity.YEAR, mapper.readValue("\"year\"", QueryGranularity.class)); + QueryGranularity gran = mapper.readValue("\"thirty_minute\"", QueryGranularity.class); Assert.assertEquals(new DurationGranularity(30 * 60 * 1000, null), gran);