diff --git a/avrohugger-core/src/main/scala/format/specific/converters/JavaConverter.scala b/avrohugger-core/src/main/scala/format/specific/converters/JavaConverter.scala index 343c064d..892d9ed7 100644 --- a/avrohugger-core/src/main/scala/format/specific/converters/JavaConverter.scala +++ b/avrohugger-core/src/main/scala/format/specific/converters/JavaConverter.scala @@ -155,6 +155,18 @@ object JavaConverter { case JavaSqlTimestamp => BLOCK(tree.DOT("getTime").APPLY()) case JavaTimeInstant => BLOCK(tree.DOT("toEpochMilli")) } + case _: LogicalTypes.TimestampMicros => (typeMatcher.avroScalaTypes.timestampMicros match { + case JavaTimeZonedDateTime => BLOCK(tree.DOT("toEpochSecond").INFIX("*", LIT(1000000L)).INFIX("+", tree.DOT("getNano").INFIX("/", LIT(1000L)))) + }) withComment "avro timestamp-micros long stores the number of microseconds from the unix epoch, 1 January 1970 00:00:00.000000 UTC" + case _: LogicalTypes.LocalTimestampMillis => (typeMatcher.avroScalaTypes.localTimestampMillis match { + case JavaTimeLocalDateTime => BLOCK(tree.DOT("toEpochSecond").APPLY(RootClass.newClass("java.time.ZoneOffset").DOT("UTC")).INFIX("*", LIT(1000L)).INFIX("+", tree.DOT("getNano").INFIX("/", LIT(1000000L)))) + }) withComment "avro local-timestamp-millis long stores the number of millis, from 1 January 1970 00:00:00.000000" + case _: LogicalTypes.LocalTimestampMicros => (typeMatcher.avroScalaTypes.localTimestampMicros match { + case JavaTimeLocalDateTime => BLOCK(tree.DOT("toEpochSecond").APPLY(RootClass.newClass("java.time.ZoneOffset").DOT("UTC")).INFIX("*", LIT(1000000L)).INFIX("+", tree.DOT("getNano").INFIX("/", LIT(1000L)))) + }) withComment "avro local-timestamp-micros long stores the number of microseconds, from 1 January 1970 00:00:00.000000" + case _: LogicalTypes.TimeMicros => (typeMatcher.avroScalaTypes.timeMicros match { + case JavaTimeLocalTime => BLOCK(tree.DOT("toNanoOfDay").INFIX("/", LIT(1000L))) + }) withComment "avro time-micros long stores the number of microseconds after midnight, 00:00:00.000000" case _ => tree } case Schema.Type.INT => schema.getLogicalType match { diff --git a/avrohugger-core/src/main/scala/format/specific/converters/ScalaConverter.scala b/avrohugger-core/src/main/scala/format/specific/converters/ScalaConverter.scala index 78266b39..e0087f84 100644 --- a/avrohugger-core/src/main/scala/format/specific/converters/ScalaConverter.scala +++ b/avrohugger-core/src/main/scala/format/specific/converters/ScalaConverter.scala @@ -197,9 +197,17 @@ object ScalaConverter { } } case Schema.Type.LONG => { + val caseLWithTypeLong = CASE(ID("l") withType (LongClass)) Option(schema.getLogicalType()) match { case Some(logicalType) => { - if (logicalType.getName == "timestamp-millis") { + if (logicalType.getName == "time-micros") { + (typeMatcher.avroScalaTypes.timeMicros match { + case JavaTimeLocalTime => + val LocalTimeClass = RootClass.newClass("java.time.LocalTime") + val resultExpr = BLOCK(LocalTimeClass.DOT("ofNanoOfDay").APPLY(REF("l").INFIX("*", LIT(1000L)))) + tree MATCH caseLWithTypeLong ==> resultExpr + }) withComment "avro time-micros long stores the number of microseconds after midnight, 00:00:00.000000" + } else if (logicalType.getName == "timestamp-millis") { typeMatcher.avroScalaTypes.timestampMillis match { case JavaSqlTimestamp => { val TimestampClass = RootClass.newClass("java.sql.Timestamp") @@ -214,6 +222,44 @@ object ScalaConverter { tree MATCH longConversion } } + } else if (logicalType.getName == "timestamp-micros") { + (typeMatcher.avroScalaTypes.timestampMicros match { + case JavaTimeZonedDateTime => + val ZonedDateTime = RootClass.newClass("java.time.ZonedDateTime") + val LocalDateTime = RootClass.newClass("java.time.LocalDateTime") + val ZoneOffset = RootClass.newClass("java.time.ZoneOffset") + val ZoneId = RootClass.newClass("java.time.ZoneId") + val resultExpr = BLOCK(ZonedDateTime.DOT("of").APPLY(LocalDateTime DOT "ofEpochSecond" APPLY( + REF("l").INFIX("/", LIT(1000000L)), + PAREN(REF("l").INFIX("%", LIT(1000000L))) DOT "toInt" INFIX("*", LIT(1000)), + ZoneOffset DOT "UTC" + ), ZoneId DOT "of" APPLY LIT("UTC"))) + tree MATCH CASE(ID("l") withType (LongClass)) ==> resultExpr + }) withComment "avro timestamp-micros long stores the number of microseconds from the unix epoch, 1 January 1970 00:00:00.000000 UTC" + } else if (logicalType.getName == "local-timestamp-millis") { + (typeMatcher.avroScalaTypes.localTimestampMillis match { + case JavaTimeLocalDateTime => + val LocalDateTime = RootClass.newClass("java.time.LocalDateTime") + val ZoneOffset = RootClass.newClass("java.time.ZoneOffset") + val resultExpr = BLOCK(LocalDateTime DOT "ofEpochSecond" APPLY( + REF("l").INFIX("/", LIT(1000L)), + PAREN(REF("l").INFIX("%", LIT(1000L))) DOT "toInt" INFIX("*", LIT(1000000)), + ZoneOffset DOT "UTC" + )) + tree MATCH CASE(ID("l") withType (LongClass)) ==> resultExpr + }) withComment "avro local-timestamp-millis long stores the number of millis, from 1 January 1970 00:00:00.000000" + } else if (logicalType.getName == "local-timestamp-micros") { + (typeMatcher.avroScalaTypes.localTimestampMicros match { + case JavaTimeLocalDateTime => + val LocalDateTime = RootClass.newClass("java.time.LocalDateTime") + val ZoneOffset = RootClass.newClass("java.time.ZoneOffset") + val resultExpr = BLOCK(LocalDateTime DOT "ofEpochSecond" APPLY( + REF("l").INFIX("/", LIT(1000000L)), + PAREN(REF("l").INFIX("%", LIT(1000000L))) DOT "toInt" INFIX("*", LIT(1000)), + ZoneOffset DOT "UTC" + )) + tree MATCH CASE(ID("l") withType (LongClass)) ==> resultExpr + }) withComment "avro local-timestamp-micros long stores the number of microseconds, from 1 January 1970 00:00:00.000000" } else tree } diff --git a/avrohugger-core/src/main/scala/matchers/DefaultParamMatcher.scala b/avrohugger-core/src/main/scala/matchers/DefaultParamMatcher.scala index 4b77be83..12088ff9 100644 --- a/avrohugger-core/src/main/scala/matchers/DefaultParamMatcher.scala +++ b/avrohugger-core/src/main/scala/matchers/DefaultParamMatcher.scala @@ -42,6 +42,18 @@ object DefaultParamMatcher { case TimestampMillis => CustomDefaultParamMatcher.checkCustomTimestampMillisType( typeMatcher.avroScalaTypes.timestampMillis) + case TimestampMicros => + CustomDefaultParamMatcher.checkCustomTimestampMicrosType( + typeMatcher.avroScalaTypes.timestampMicros) + case LocalTimestampMillis => + CustomDefaultParamMatcher.checkCustomLocalTimestampMillisType( + typeMatcher.avroScalaTypes.localTimestampMillis) + case LocalTimestampMicros => + CustomDefaultParamMatcher.checkCustomLocalTimestampMicrosType( + typeMatcher.avroScalaTypes.localTimestampMicros) + case TimeMicros => + CustomDefaultParamMatcher.checkCustomTimeMicrosType( + typeMatcher.avroScalaTypes.timeMicros) } case Schema.Type.FLOAT => LIT(0F) case Schema.Type.DOUBLE => LIT(0D) diff --git a/avrohugger-core/src/main/scala/matchers/TypeMatcher.scala b/avrohugger-core/src/main/scala/matchers/TypeMatcher.scala index a4090b4b..9e4829da 100644 --- a/avrohugger-core/src/main/scala/matchers/TypeMatcher.scala +++ b/avrohugger-core/src/main/scala/matchers/TypeMatcher.scala @@ -49,6 +49,10 @@ class TypeMatcher( schema = schema, default = CustomTypeMatcher.checkCustomNumberType(avroScalaTypes.long)) { case TimestampMillis => CustomTypeMatcher.checkCustomTimestampMillisType(avroScalaTypes.timestampMillis) + case TimestampMicros => CustomTypeMatcher.checkCustomTimestampMicrosType(avroScalaTypes.timestampMicros) + case LocalTimestampMicros => CustomTypeMatcher.checkCustomLocalTimestampMicrosType(avroScalaTypes.localTimestampMicros) + case LocalTimestampMillis => CustomTypeMatcher.checkCustomLocalTimestampMillisType(avroScalaTypes.localTimestampMillis) + case TimeMicros => CustomTypeMatcher.checkCustomTimeMicrosType(avroScalaTypes.timeMicros) } case Schema.Type.INT => LogicalType.foldLogicalTypes( diff --git a/avrohugger-core/src/main/scala/matchers/custom/CustomDefaultParamMatcher.scala b/avrohugger-core/src/main/scala/matchers/custom/CustomDefaultParamMatcher.scala index a3aebb74..2f53fb5e 100644 --- a/avrohugger-core/src/main/scala/matchers/custom/CustomDefaultParamMatcher.scala +++ b/avrohugger-core/src/main/scala/matchers/custom/CustomDefaultParamMatcher.scala @@ -58,4 +58,24 @@ object CustomDefaultParamMatcher { case JavaSqlTime => NEW(REF("java.sql.Time"), LIT(0L)) case JavaTimeLocalTime => REF("java.time.LocalTime.now") } + + def checkCustomTimeMicrosType(timeMillisType: AvroScalaTimeType): Tree = + timeMillisType match { + case JavaTimeLocalTime => REF("java.time.LocalTime.MIDNIGHT") + } + + def checkCustomTimestampMicrosType(timeMillisType: AvroScalaTimestampType): Tree = + timeMillisType match { + case JavaTimeZonedDateTime => REF("java.time.ZonedDateTime.of").APPLY(REF("java.time.LocalDateTime") DOT "MIN", REF("java.time.ZoneId") DOT "of" APPLY LIT("UTC")) + } + + def checkCustomLocalTimestampMillisType(timeMillisType: AvroScalaLocalTimestampType): Tree = + timeMillisType match { + case JavaTimeLocalDateTime => REF("java.time.LocalDateTime") DOT "MIN" + } + + def checkCustomLocalTimestampMicrosType(timeMillisType: AvroScalaLocalTimestampType): Tree = + timeMillisType match { + case JavaTimeLocalDateTime => REF("java.time.LocalDateTime") DOT "MIN" + } } \ No newline at end of file diff --git a/avrohugger-core/src/main/scala/matchers/custom/CustomTypeMatcher.scala b/avrohugger-core/src/main/scala/matchers/custom/CustomTypeMatcher.scala index bd1f88d7..290cc16c 100644 --- a/avrohugger-core/src/main/scala/matchers/custom/CustomTypeMatcher.scala +++ b/avrohugger-core/src/main/scala/matchers/custom/CustomTypeMatcher.scala @@ -62,4 +62,20 @@ object CustomTypeMatcher { case ScalaBigDecimalWithPrecision(_) => decimalTaggedType(precision, scale) } } + + def checkCustomTimeMicrosType(timeType: AvroScalaTimeType) = timeType match { + case JavaTimeLocalTime => RootClass.newClass(nme.createNameType("java.time.LocalTime")) + } + + def checkCustomTimestampMicrosType(timeType: AvroScalaTimestampType) = timeType match { + case JavaTimeZonedDateTime => RootClass.newClass(nme.createNameType("java.time.ZonedDateTime")) + } + + def checkCustomLocalTimestampMicrosType(timeType: AvroScalaLocalTimestampType) = timeType match { + case JavaTimeLocalDateTime => RootClass.newClass(nme.createNameType("java.time.LocalDateTime")) + } + + def checkCustomLocalTimestampMillisType(timeType: AvroScalaLocalTimestampType) = timeType match { + case JavaTimeLocalDateTime => RootClass.newClass(nme.createNameType("java.time.LocalDateTime")) + } } \ No newline at end of file diff --git a/avrohugger-core/src/main/scala/types/AvroScalaTypes.scala b/avrohugger-core/src/main/scala/types/AvroScalaTypes.scala index 9baf3e6e..ac13b78f 100644 --- a/avrohugger-core/src/main/scala/types/AvroScalaTypes.scala +++ b/avrohugger-core/src/main/scala/types/AvroScalaTypes.scala @@ -24,6 +24,10 @@ case class AvroScalaTypes( date: AvroScalaDateType = JavaTimeLocalDate, timestampMillis: AvroScalaTimestampMillisType = JavaTimeInstant, timeMillis: AvroScalaTimeMillisType = JavaTimeLocalTime, + timeMicros: AvroScalaTimeType = JavaTimeLocalTime, + timestampMicros: AvroScalaTimestampType = JavaTimeZonedDateTime, + localTimestampMillis: AvroScalaLocalTimestampType = JavaTimeLocalDateTime, + localTimestampMicros: AvroScalaLocalTimestampType = JavaTimeLocalDateTime, uuid: AvroUuidType = JavaUuid ) diff --git a/avrohugger-core/src/main/scala/types/LogicalAvroScalaTypes.scala b/avrohugger-core/src/main/scala/types/LogicalAvroScalaTypes.scala index 6ebde529..733d0022 100644 --- a/avrohugger-core/src/main/scala/types/LogicalAvroScalaTypes.scala +++ b/avrohugger-core/src/main/scala/types/LogicalAvroScalaTypes.scala @@ -18,14 +18,25 @@ case object JavaTimeInstant extends AvroScalaTimestampMillisType sealed trait AvroUuidType extends Product with Serializable case object JavaUuid extends AvroUuidType +sealed trait AvroScalaTimeType extends Serializable sealed trait AvroScalaTimeMillisType extends Product with Serializable case object JavaSqlTime extends AvroScalaTimeMillisType -case object JavaTimeLocalTime extends AvroScalaTimeMillisType +case object JavaTimeLocalTime extends AvroScalaTimeType with AvroScalaTimeMillisType + +sealed trait AvroScalaTimestampType extends Serializable +case object JavaTimeZonedDateTime extends AvroScalaTimestampType + +sealed trait AvroScalaLocalTimestampType extends Serializable +case object JavaTimeLocalDateTime extends AvroScalaLocalTimestampType sealed abstract class LogicalType(name: String) case class Decimal(precision: Int, scale: Int) extends LogicalType("decimal") case object Date extends LogicalType("date") case object TimestampMillis extends LogicalType("timestamp-millis") +case object TimestampMicros extends LogicalType("timestamp-micros") +case object LocalTimestampMicros extends LogicalType("local-timestamp-micros") +case object LocalTimestampMillis extends LogicalType("local-timestamp-millis") +case object TimeMicros extends LogicalType("timestamp-millis") case object TimeMillis extends LogicalType("time-millis") case object UUID extends LogicalType("uuid") @@ -35,6 +46,10 @@ object LogicalType { case d: org.apache.avro.LogicalTypes.Decimal => Some(Decimal(d.getPrecision, d.getScale)) case _: org.apache.avro.LogicalTypes.Date => Some(Date) case _: org.apache.avro.LogicalTypes.TimestampMillis => Some(TimestampMillis) + case _: org.apache.avro.LogicalTypes.TimestampMicros => Some(TimestampMicros) + case _: org.apache.avro.LogicalTypes.LocalTimestampMillis => Some(LocalTimestampMillis) + case _: org.apache.avro.LogicalTypes.LocalTimestampMicros => Some(LocalTimestampMicros) + case _: org.apache.avro.LogicalTypes.TimeMicros => Some(TimeMicros) case _: org.apache.avro.LogicalTypes.TimeMillis => Some(TimeMillis) case _ if logicalType.getName == "uuid" => Some(UUID) case _ => None diff --git a/avrohugger-core/src/test/avro/logical.avsc b/avrohugger-core/src/test/avro/logical.avsc index 623c04e6..e85e3d16 100644 --- a/avrohugger-core/src/test/avro/logical.avsc +++ b/avrohugger-core/src/test/avro/logical.avsc @@ -59,6 +59,34 @@ "type": "int", "logicalType": "time-millis" } + }, + { + "name": "timeMicros", + "type": { + "type": "long", + "logicalType": "time-micros" + } + }, + { + "name": "timestampMicros", + "type": { + "type": "long", + "logicalType": "timestamp-micros" + } + }, + { + "name": "localTimestampMicros", + "type": { + "type": "long", + "logicalType": "local-timestamp-micros" + } + }, + { + "name": "localTimestampMillis", + "type": { + "type": "long", + "logicalType": "local-timestamp-millis" + } } ] } diff --git a/avrohugger-core/src/test/expected/specific/example/logical/LogicalSc.scala b/avrohugger-core/src/test/expected/specific/example/logical/LogicalSc.scala index f8548da9..af86be0b 100644 --- a/avrohugger-core/src/test/expected/specific/example/logical/LogicalSc.scala +++ b/avrohugger-core/src/test/expected/specific/example/logical/LogicalSc.scala @@ -3,8 +3,8 @@ package example.logical import scala.annotation.switch -final case class LogicalSc(var data: BigDecimal, var fxField: fxType, var ts: java.time.Instant, var dt: java.time.LocalDate, var uuid: java.util.UUID, var dataBig: BigDecimal) extends org.apache.avro.specific.SpecificRecordBase { - def this() = this(scala.math.BigDecimal(0), fxType(scala.math.BigDecimal(0)), java.time.Instant.now, java.time.LocalDate.now, java.util.UUID.randomUUID, scala.math.BigDecimal(0)) +final case class LogicalSc(var data: BigDecimal, var fxField: fxType, var ts: java.time.Instant, var dt: java.time.LocalDate, var uuid: java.util.UUID, var dataBig: BigDecimal, var tm: java.time.LocalTime, var timeMicros: java.time.LocalTime, var timestampMicros: java.time.ZonedDateTime, var localTimestampMicros: java.time.LocalDateTime, var localTimestampMillis: java.time.LocalDateTime) extends org.apache.avro.specific.SpecificRecordBase { + def this() = this(scala.math.BigDecimal(0), fxType(scala.math.BigDecimal(0)), java.time.Instant.now, java.time.LocalDate.now, java.util.UUID.randomUUID, scala.math.BigDecimal(0), java.time.LocalTime.now, java.time.LocalTime.MIDNIGHT, java.time.ZonedDateTime.of(java.time.LocalDateTime.MIN, java.time.ZoneId.of("UTC")), java.time.LocalDateTime.MIN, java.time.LocalDateTime.MIN) def get(field$: Int): AnyRef = { (field$: @switch) match { case 0 => { @@ -19,7 +19,7 @@ final case class LogicalSc(var data: BigDecimal, var fxField: fxType, var ts: ja val schema = getSchema.getFields().get(field$).schema() val decimalType = schema.getLogicalType().asInstanceOf[org.apache.avro.LogicalTypes.Decimal] val scale = decimalType.getScale() - val scaledValue = fxField.bigDecimal.setScale(scale) + val scaledValue = fxField.bytes.setScale(scale) val bigDecimal = scaledValue.bigDecimal LogicalSc.decimalConversion.toFixed(bigDecimal, schema, decimalType) }.asInstanceOf[AnyRef] @@ -40,6 +40,33 @@ final case class LogicalSc(var data: BigDecimal, var fxField: fxType, var ts: ja val bigDecimal = scaledValue.bigDecimal LogicalSc.decimalConversion.toBytes(bigDecimal, schema, decimalType) }.asInstanceOf[AnyRef] + case 6 => { + tm.get(java.time.temporal.ChronoField.MILLI_OF_DAY) + }.asInstanceOf[AnyRef] + case 7 => { + // avro time-micros long stores the number of microseconds after midnight, 00:00:00.000000 + { + timeMicros.toNanoOfDay / 1000L + } + }.asInstanceOf[AnyRef] + case 8 => { + // avro timestamp-micros long stores the number of microseconds from the unix epoch, 1 January 1970 00:00:00.000000 UTC + { + timestampMicros.toEpochSecond * 1000000L + (timestampMicros.getNano / 1000L) + } + }.asInstanceOf[AnyRef] + case 9 => { + // avro local-timestamp-micros long stores the number of microseconds, from 1 January 1970 00:00:00.000000 + { + localTimestampMicros.toEpochSecond(java.time.ZoneOffset.UTC) * 1000000L + (localTimestampMicros.getNano / 1000L) + } + }.asInstanceOf[AnyRef] + case 10 => { + // avro local-timestamp-millis long stores the number of millis, from 1 January 1970 00:00:00.000000 + { + localTimestampMillis.toEpochSecond(java.time.ZoneOffset.UTC) * 1000L + (localTimestampMillis.getNano / 1000000L) + } + }.asInstanceOf[AnyRef] case _ => new org.apache.avro.AvroRuntimeException("Bad index") } } @@ -55,14 +82,8 @@ final case class LogicalSc(var data: BigDecimal, var fxField: fxType, var ts: ja } }.asInstanceOf[BigDecimal] case 1 => this.fxField = { - value match { - case (buffer: java.nio.ByteBuffer) => { - val schema = getSchema.getFields().get(field$).schema() - val decimalType = schema.getLogicalType().asInstanceOf[org.apache.avro.LogicalTypes.Decimal] - example.logical.fxType(BigDecimal(LogicalSc.decimalConversion.fromBytes(buffer, schema, decimalType))) - } - } - }.asInstanceOf[fxType.type] + value + }.asInstanceOf[fxType] case 2 => this.ts = { value match { case (l: Long) => { @@ -93,14 +114,53 @@ final case class LogicalSc(var data: BigDecimal, var fxField: fxType, var ts: ja } } }.asInstanceOf[BigDecimal] + case 6 => this.tm = { + value match { + case (i: Integer) => { + java.time.LocalTime.ofNanoOfDay(i * 1000000L) + } + } + }.asInstanceOf[java.time.LocalTime] + case 7 => this.timeMicros = { + // avro time-micros long stores the number of microseconds after midnight, 00:00:00.000000 + value match { + case (l: Long) => { + java.time.LocalTime.ofNanoOfDay(l * 1000L) + } + } + }.asInstanceOf[java.time.LocalTime] + case 8 => this.timestampMicros = { + // avro timestamp-micros long stores the number of microseconds from the unix epoch, 1 January 1970 00:00:00.000000 UTC + value match { + case (l: Long) => { + java.time.ZonedDateTime.of(java.time.LocalDateTime.ofEpochSecond(l / 1000000L, (l % 1000000L).toInt * 1000, java.time.ZoneOffset.UTC), java.time.ZoneId.of("UTC")) + } + } + }.asInstanceOf[java.time.ZonedDateTime] + case 9 => this.localTimestampMicros = { + // avro local-timestamp-micros long stores the number of microseconds, from 1 January 1970 00:00:00.000000 + value match { + case (l: Long) => { + java.time.LocalDateTime.ofEpochSecond(l / 1000000L, (l % 1000000L).toInt * 1000, java.time.ZoneOffset.UTC) + } + } + }.asInstanceOf[java.time.LocalDateTime] + case 10 => this.localTimestampMillis = { + // avro local-timestamp-millis long stores the number of millis, from 1 January 1970 00:00:00.000000 + value match { + case (l: Long) => { + java.time.LocalDateTime.ofEpochSecond(l / 1000L, (l % 1000L).toInt * 1000000, java.time.ZoneOffset.UTC) + } + } + }.asInstanceOf[java.time.LocalDateTime] case _ => new org.apache.avro.AvroRuntimeException("Bad index") } () } - def getSchema: org.apache.avro.Schema = LogicalSc.SCHEMA$ + def getSchema: org.apache.avro.Schema = example.logical.LogicalSc.SCHEMA$ } object LogicalSc { - val SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"LogicalSc\",\"namespace\":\"example.logical\",\"fields\":[{\"name\":\"data\",\"type\":{\"type\":\"bytes\",\"logicalType\":\"decimal\",\"precision\":9,\"scale\":2}},{\"name\":\"fxField\",\"type\":{\"type\":\"fixed\",\"name\":\"fxType\",\"size\":12,\"logicalType\":\"decimal\",\"precision\":5,\"scale\":2}},{\"name\":\"ts\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}},{\"name\":\"dt\",\"type\":{\"type\":\"int\",\"logicalType\":\"date\"}},{\"name\":\"uuid\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"dataBig\",\"type\":{\"type\":\"bytes\",\"logicalType\":\"decimal\",\"precision\":20,\"scale\":12}}]}") + val SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"LogicalSc\",\"namespace\":\"example.logical\",\"fields\":[{\"name\":\"data\",\"type\":{\"type\":\"bytes\",\"logicalType\":\"decimal\",\"precision\":9,\"scale\":2}},{\"name\":\"fxField\",\"type\":{\"type\":\"fixed\",\"name\":\"fxType\",\"size\":2,\"logicalType\":\"decimal\",\"precision\":2,\"scale\":1}},{\"name\":\"ts\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-millis\"}},{\"name\":\"dt\",\"type\":{\"type\":\"int\",\"logicalType\":\"date\"}},{\"name\":\"uuid\",\"type\":{\"type\":\"string\",\"logicalType\":\"uuid\"}},{\"name\":\"dataBig\",\"type\":{\"type\":\"bytes\",\"logicalType\":\"decimal\",\"precision\":20,\"scale\":12}},{\"name\":\"tm\",\"type\":{\"type\":\"int\",\"logicalType\":\"time-millis\"}},{\"name\":\"timeMicros\",\"type\":{\"type\":\"long\",\"logicalType\":\"time-micros\"}},{\"name\":\"timestampMicros\",\"type\":{\"type\":\"long\",\"logicalType\":\"timestamp-micros\"}},{\"name\":\"localTimestampMicros\",\"type\":{\"type\":\"long\",\"logicalType\":\"local-timestamp-micros\"}},{\"name\":\"localTimestampMillis\",\"type\":{\"type\":\"long\",\"logicalType\":\"local-timestamp-millis\"}}]}") val decimalConversion = new org.apache.avro.Conversions.DecimalConversion } \ No newline at end of file diff --git a/avrohugger-core/src/test/expected/standard-tagged/example/logical/LogicalSc.scala b/avrohugger-core/src/test/expected/standard-tagged/example/logical/LogicalSc.scala index 703d43cc..1134732f 100644 --- a/avrohugger-core/src/test/expected/standard-tagged/example/logical/LogicalSc.scala +++ b/avrohugger-core/src/test/expected/standard-tagged/example/logical/LogicalSc.scala @@ -3,4 +3,4 @@ package example.logical import shapeless.tag.@@ -final case class LogicalSc(data: @@[scala.math.BigDecimal, (shapeless.Nat._9, shapeless.Nat._2)], fxField: fxType, ts: java.time.Instant, dt: java.time.LocalDate, uuid: java.util.UUID, dataBig: @@[scala.math.BigDecimal, ((shapeless.Nat._2, shapeless.Nat._0), (shapeless.Nat._1, shapeless.Nat._2))], tm: java.time.LocalTime) \ No newline at end of file +final case class LogicalSc(data: @@[scala.math.BigDecimal, (shapeless.Nat._9, shapeless.Nat._2)], fxField: fxType, ts: java.time.Instant, dt: java.time.LocalDate, uuid: java.util.UUID, dataBig: @@[scala.math.BigDecimal, ((shapeless.Nat._2, shapeless.Nat._0), (shapeless.Nat._1, shapeless.Nat._2))], tm: java.time.LocalTime, timeMicros: java.time.LocalTime, timestampMicros: java.time.ZonedDateTime, localTimestampMicros: java.time.LocalDateTime, localTimestampMillis: java.time.LocalDateTime) \ No newline at end of file diff --git a/avrohugger-core/src/test/expected/standard/example/logical/LogicalSc.scala b/avrohugger-core/src/test/expected/standard/example/logical/LogicalSc.scala index f50c0e58..c490a52b 100644 --- a/avrohugger-core/src/test/expected/standard/example/logical/LogicalSc.scala +++ b/avrohugger-core/src/test/expected/standard/example/logical/LogicalSc.scala @@ -1,4 +1,4 @@ /** MACHINE-GENERATED FROM AVRO SCHEMA. DO NOT EDIT DIRECTLY */ package example.logical -final case class LogicalSc(data: BigDecimal, fxField: fxType, ts: java.time.Instant, dt: java.time.LocalDate, uuid: java.util.UUID, dataBig: BigDecimal, tm: java.time.LocalTime) \ No newline at end of file +final case class LogicalSc(data: BigDecimal, fxField: fxType, ts: java.time.Instant, dt: java.time.LocalDate, uuid: java.util.UUID, dataBig: BigDecimal, tm: java.time.LocalTime, timeMicros: java.time.LocalTime, timestampMicros: java.time.ZonedDateTime, localTimestampMicros: java.time.LocalDateTime, localTimestampMillis: java.time.LocalDateTime) \ No newline at end of file diff --git a/avrohugger-core/src/test/scala/specific/SpecificFileToFileSpec.scala b/avrohugger-core/src/test/scala/specific/SpecificFileToFileSpec.scala index a170daeb..eccda949 100644 --- a/avrohugger-core/src/test/scala/specific/SpecificFileToFileSpec.scala +++ b/avrohugger-core/src/test/scala/specific/SpecificFileToFileSpec.scala @@ -371,7 +371,7 @@ class SpecificFileToFileSpec extends Specification { val source1 = util.Util.readFile("target/generated-sources/specific/example/logical/LogicalSc.scala") val source2 = util.Util.readFile("target/generated-sources/specific/example/logical/fxType.scala") - source1 === util.Util.readFile("avrohugger-core/src/test/expected/specific/example/logical/LogicalSc.scala") + source1 === util.Util.readFile("avrohugger-core/src/test/expected/specific/example/logical/LogicalSc.scala") and source2 === util.Util.readFile("avrohugger-core/src/test/expected/specific/example/logical/fxType.scala") }