From a484eb449e2ac8c4d26afc44000e699504d2359e Mon Sep 17 00:00:00 2001 From: Jonathan Shook Date: Fri, 27 Mar 2020 12:15:02 -0500 Subject: [PATCH] nosqlbench-104 Add support for DateRange bindings --- .../to_daterange/DateRangeDuring.java | 46 ++++++++++++++ .../functions/to_daterange/DateRangeFunc.java | 60 +++++++++++++++++++ .../to_daterange/DateRangeOnOrAfter.java | 48 +++++++++++++++ .../to_daterange/DateRangeOnOrBefore.java | 47 +++++++++++++++ .../to_daterange/DateRangeParser.java | 36 +++++++++++ .../to_daterange/DateRangeFuncTest.java | 59 ++++++++++++++++++ 6 files changed, 296 insertions(+) create mode 100644 activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeDuring.java create mode 100644 activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFunc.java create mode 100644 activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrAfter.java create mode 100644 activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrBefore.java create mode 100644 activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeParser.java create mode 100644 activitytype-cql/src/test/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFuncTest.java diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeDuring.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeDuring.java new file mode 100644 index 000000000..cb7218c2f --- /dev/null +++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeDuring.java @@ -0,0 +1,46 @@ +package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange; + +import com.datastax.driver.dse.search.DateRange; +import io.nosqlbench.virtdata.annotations.Example; +import io.nosqlbench.virtdata.annotations.ThreadSafeMapper; + +import java.util.Date; +import java.util.function.Function; +import java.util.function.LongFunction; + +/** + * Takes an input as a reference point in epoch time, and converts it to a DateRange, + * with the bounds set to the lower and upper timestamps which align to the + * specified precision. You can use any of these precisions to control the bounds + * around the provided timestamp: + * + */ +@ThreadSafeMapper +public class DateRangeDuring implements LongFunction { + + private final com.datastax.driver.dse.search.DateRange.DateRangeBound.Precision precision; + + @Example({"DateRangeDuring('millisecond')}","Convert the incoming millisecond to an equivalent DateRange"}) + @Example({"DateRangeDuring('minute')}","Convert the incoming millisecond to a DateRange for the minute in which the " + + "millisecond falls"}) + public DateRangeDuring(String precision) { + this.precision = com.datastax.driver.dse.search.DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase()); + } + + @Override + public DateRange apply(long value) { + Date date = new Date(value); + com.datastax.driver.dse.search.DateRange.DateRangeBound lower = com.datastax.driver.dse.search.DateRange.DateRangeBound.lowerBound(date, precision); + com.datastax.driver.dse.search.DateRange.DateRangeBound upper = com.datastax.driver.dse.search.DateRange.DateRangeBound.upperBound(date, precision); + com.datastax.driver.dse.search.DateRange dateRange = new com.datastax.driver.dse.search.DateRange(lower, upper); + return dateRange; + } +} diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFunc.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFunc.java new file mode 100644 index 000000000..1ee771640 --- /dev/null +++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFunc.java @@ -0,0 +1,60 @@ +package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange; + +import com.datastax.driver.dse.search.DateRange; +import io.nosqlbench.virtdata.annotations.Example; +import io.nosqlbench.virtdata.annotations.ThreadSafeMapper; + +import java.util.Date; +import java.util.function.Function; +import java.util.function.LongFunction; +import java.util.function.LongUnaryOperator; + +/** + * Uses the precision and the two functions provided to create a DateRange. + * You can use any of these precisions to control the bounds + * around the provided timestamp: + * + */ +@ThreadSafeMapper +public class DateRangeFunc implements LongFunction { + + private final DateRange.DateRangeBound.Precision precision; + private final LongUnaryOperator lower; + private final LongUnaryOperator upper; + + public DateRangeFunc(String precision, LongUnaryOperator lower, LongUnaryOperator upper) { + this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase()); + this.lower = lower; + this.upper = upper; + } + public DateRangeFunc(String precision, LongFunction lower, LongFunction upper) { + this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase()); + this.lower = lower::apply; + this.upper = upper::apply; + } + public DateRangeFunc(String precision, Function lower, Function upper) { + this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase()); + this.lower = lower::apply; + this.upper = upper::apply; + } + + + + @Override + public DateRange apply(long value) { + Date lowerDate = new Date(lower.applyAsLong(value)); + DateRange.DateRangeBound lower = DateRange.DateRangeBound.lowerBound(lowerDate,precision); + Date upperDate = new Date(upper.applyAsLong(value)); + DateRange.DateRangeBound upper = DateRange.DateRangeBound.upperBound(lowerDate,precision); + DateRange dateRange = new DateRange(lower, upper); + return dateRange; + } +} diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrAfter.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrAfter.java new file mode 100644 index 000000000..bb0cfe922 --- /dev/null +++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrAfter.java @@ -0,0 +1,48 @@ +package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange; + +import com.datastax.driver.dse.search.DateRange; +import io.nosqlbench.virtdata.annotations.Example; +import io.nosqlbench.virtdata.annotations.ThreadSafeMapper; + +import java.util.Date; +import java.util.function.Function; +import java.util.function.LongFunction; + +/** + * Takes an input as a reference point in epoch time, and converts it to a DateRange, + * with the lower bounds set to the lower bound of the precision and millisecond + * provided, and with no upper bound. + * You can use any of these precisions to control the bounds + * around the provided timestamp: + *
    + *
  • millisecond
  • + *
  • second
  • + *
  • minute
  • + *
  • hour
  • + *
  • day
  • + *
  • month
  • + *
  • year
  • + *
+ */ +@ThreadSafeMapper +public class DateRangeOnOrAfter implements LongFunction { + + private final DateRange.DateRangeBound.Precision precision; + + @Example({"DateRangeOnOrAfter('millisecond')}","Convert the incoming millisecond to an match any time on or after"}) + @Example({"DateRangeOnOrAfter('minute')}","Convert the incoming millisecond to mach any time on or after the" + + " minute in which the " + + "millisecond falls"}) + public DateRangeOnOrAfter(String precision) { + this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase()); + } + + @Override + public DateRange apply(long value) { + Date date = new Date(value); + DateRange.DateRangeBound lower = DateRange.DateRangeBound.lowerBound(date, precision); + DateRange.DateRangeBound upper = DateRange.DateRangeBound.UNBOUNDED; + DateRange dateRange = new DateRange(lower, upper); + return dateRange; + } +} diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrBefore.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrBefore.java new file mode 100644 index 000000000..0487c29ab --- /dev/null +++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeOnOrBefore.java @@ -0,0 +1,47 @@ +package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange; + +import com.datastax.driver.dse.search.DateRange; +import io.nosqlbench.virtdata.annotations.Example; +import io.nosqlbench.virtdata.annotations.ThreadSafeMapper; + +import java.util.Date; +import java.util.function.Function; +import java.util.function.LongFunction; + +/** + * Takes an input as a reference point in epoch time, and converts it to a DateRange, + * with the upper bound set to the upper bound of the precision and millisecond + * provided, and with no lower bound. + * You can use any of these precisions to control the bounds + * around the provided timestamp: + *
    + *
  • millisecond
  • + *
  • second
  • + *
  • minute
  • + *
  • hour
  • + *
  • day
  • + *
  • month
  • + *
  • year
  • + *
+ */ +@ThreadSafeMapper +public class DateRangeOnOrBefore implements LongFunction { + + private final DateRange.DateRangeBound.Precision precision; + + @Example({"DateRangeOnOrBefore('millisecond')}","Convert the incoming millisecond to match anything on or before it."}) + @Example({"DateRangeOnOrBefore('minute')}","Convert the incoming millisecond to match anything on or before the minute in" + + " which the millisecond falls"}) + public DateRangeOnOrBefore(String precision) { + this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase()); + } + + @Override + public DateRange apply(long value) { + Date date = new Date(value); + DateRange.DateRangeBound lower = DateRange.DateRangeBound.UNBOUNDED; + DateRange.DateRangeBound upper = DateRange.DateRangeBound.upperBound(date,precision); + DateRange dateRange = new DateRange(lower, upper); + return dateRange; + } +} diff --git a/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeParser.java b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeParser.java new file mode 100644 index 000000000..970094627 --- /dev/null +++ b/activitytype-cql/src/main/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeParser.java @@ -0,0 +1,36 @@ +package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange; + +import com.datastax.driver.dse.search.DateRange; +import io.nosqlbench.virtdata.annotations.Example; +import io.nosqlbench.virtdata.annotations.ThreadSafeMapper; + +import java.text.ParseException; +import java.util.Date; +import java.util.function.Function; + +/** + * Parses the DateRange format according to Date Range Formatting. + * When possible it is more efficient to use the other DateRange methods since they do not require parsing. + */ +@ThreadSafeMapper +public class DateRangeParser implements Function { + + private final DateRange.DateRangeBound.Precision precision; + + @Example({"DateRangeParser()}","Convert inputs like '[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]' into " + + "DateRanges" + + " "}) + public DateRangeParser(String precision) { + this.precision = DateRange.DateRangeBound.Precision.valueOf(precision.toUpperCase()); + } + + @Override + public DateRange apply(String value) { + try { + return DateRange.parse(value); + } catch (ParseException e) { + throw new RuntimeException("unable to parse date rage input '" + value + "': error:" + e.getMessage()); + } + } +} diff --git a/activitytype-cql/src/test/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFuncTest.java b/activitytype-cql/src/test/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFuncTest.java new file mode 100644 index 000000000..640f89a8e --- /dev/null +++ b/activitytype-cql/src/test/java/io/nosqlbench/activitytype/cql/datamappers/functions/to_daterange/DateRangeFuncTest.java @@ -0,0 +1,59 @@ +package io.nosqlbench.activitytype.cql.datamappers.functions.to_daterange; + +import org.junit.Test; + +import java.util.function.Function; +import java.util.function.LongFunction; +import java.util.function.LongUnaryOperator; + +import static org.assertj.core.api.Assertions.assertThat; + +public class DateRangeFuncTest { + + @Test + public void testDateRangeFuncs() { + LongFunction lf1 = value -> value; + DateRangeFunc function = new DateRangeFunc("second", lf1, lf1); + + assertThat(function.apply(42L).toString()) + .isEqualTo("[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]"); + assertThat(function.apply(42000L).toString()) + .isEqualTo("[1970-01-01T00:00:42 TO 1970-01-01T00:00:42]"); + assertThat(function.apply(42000000L).toString()) + .isEqualTo("[1970-01-01T11:40:00 TO 1970-01-01T11:40:00]"); + assertThat(function.apply(42000000000L).toString()) + .isEqualTo("[1971-05-02T02:40:00 TO 1971-05-02T02:40:00]"); + assertThat(function.apply(42000000000000L).toString()) + .isEqualTo("[3300-12-05T02:40:00 TO 3300-12-05T02:40:00]"); + + LongUnaryOperator lf2 = value -> value; + + function = new DateRangeFunc("second", lf2, lf2); + assertThat(function.apply(42L).toString()) + .isEqualTo("[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]"); + assertThat(function.apply(42000L).toString()) + .isEqualTo("[1970-01-01T00:00:42 TO 1970-01-01T00:00:42]"); + assertThat(function.apply(42000000L).toString()) + .isEqualTo("[1970-01-01T11:40:00 TO 1970-01-01T11:40:00]"); + assertThat(function.apply(42000000000L).toString()) + .isEqualTo("[1971-05-02T02:40:00 TO 1971-05-02T02:40:00]"); + assertThat(function.apply(42000000000000L).toString()) + .isEqualTo("[3300-12-05T02:40:00 TO 3300-12-05T02:40:00]"); + + Function lf3 = value -> value; + + function = new DateRangeFunc("second", lf3, lf3); + assertThat(function.apply(42L).toString()) + .isEqualTo("[1970-01-01T00:00:00 TO 1970-01-01T00:00:00]"); + assertThat(function.apply(42000L).toString()) + .isEqualTo("[1970-01-01T00:00:42 TO 1970-01-01T00:00:42]"); + assertThat(function.apply(42000000L).toString()) + .isEqualTo("[1970-01-01T11:40:00 TO 1970-01-01T11:40:00]"); + assertThat(function.apply(42000000000L).toString()) + .isEqualTo("[1971-05-02T02:40:00 TO 1971-05-02T02:40:00]"); + assertThat(function.apply(42000000000000L).toString()) + .isEqualTo("[3300-12-05T02:40:00 TO 3300-12-05T02:40:00]"); + + } + +}