|
1 | 1 | package me.mnedokushev.zio.apache.parquet.core.codec
|
2 | 2 |
|
3 |
| -import me.mnedokushev.zio.apache.parquet.core.Value |
| 3 | +import me.mnedokushev.zio.apache.parquet.core.{ DECIMAL_SCALE, MICROS_FACTOR, MILLIS_PER_DAY, Value } |
4 | 4 | import me.mnedokushev.zio.apache.parquet.core.Value.{ GroupValue, PrimitiveValue }
|
5 | 5 | import zio._
|
6 | 6 | import zio.schema._
|
7 | 7 |
|
8 |
| -import java.nio.ByteBuffer |
9 |
| -import java.nio.charset.StandardCharsets |
| 8 | +import java.math.{ BigDecimal, BigInteger } |
| 9 | +import java.nio.{ ByteBuffer, ByteOrder } |
| 10 | +import java.time.{ |
| 11 | + DayOfWeek, |
| 12 | + Instant, |
| 13 | + LocalDate, |
| 14 | + LocalDateTime, |
| 15 | + LocalTime, |
| 16 | + Month, |
| 17 | + MonthDay, |
| 18 | + OffsetDateTime, |
| 19 | + OffsetTime, |
| 20 | + Period, |
| 21 | + Year, |
| 22 | + YearMonth, |
| 23 | + ZoneId, |
| 24 | + ZoneOffset, |
| 25 | + ZonedDateTime |
| 26 | +} |
10 | 27 | import java.util.UUID
|
11 | 28 |
|
12 | 29 | object ValueDecoderDeriver {
|
@@ -63,32 +80,86 @@ object ValueDecoderDeriver {
|
63 | 80 | st: StandardType[A],
|
64 | 81 | summoned: => Option[ValueDecoder[A]]
|
65 | 82 | ): ValueDecoder[A] = new ValueDecoder[A] {
|
| 83 | + |
| 84 | + private def localTime(v: Int) = |
| 85 | + LocalTime.ofNanoOfDay(v * MICROS_FACTOR) |
| 86 | + |
| 87 | + private def localDateTime(v: Long) = { |
| 88 | + val epochDay = v / MILLIS_PER_DAY |
| 89 | + val nanoOfDay = (v - (epochDay * MILLIS_PER_DAY)) * MICROS_FACTOR |
| 90 | + |
| 91 | + LocalDateTime.of(LocalDate.ofEpochDay(epochDay), LocalTime.ofNanoOfDay(nanoOfDay)) |
| 92 | + } |
| 93 | + |
66 | 94 | override def decode(value: Value): A =
|
67 | 95 | (st, value) match {
|
68 |
| - case (StandardType.StringType, PrimitiveValue.BinaryValue(v)) => |
69 |
| - new String(v.getBytes, StandardCharsets.UTF_8) |
70 |
| - case (StandardType.BoolType, PrimitiveValue.BooleanValue(v)) => |
| 96 | + case (StandardType.StringType, PrimitiveValue.BinaryValue(v)) => |
| 97 | + v.toStringUsingUTF8 |
| 98 | + case (StandardType.BoolType, PrimitiveValue.BooleanValue(v)) => |
71 | 99 | v
|
72 |
| - case (StandardType.ByteType, PrimitiveValue.Int32Value(v)) => |
| 100 | + case (StandardType.ByteType, PrimitiveValue.Int32Value(v)) => |
73 | 101 | v.toByte
|
74 |
| - case (StandardType.ShortType, PrimitiveValue.Int32Value(v)) => |
| 102 | + case (StandardType.ShortType, PrimitiveValue.Int32Value(v)) => |
75 | 103 | v.toShort
|
76 |
| - case (StandardType.IntType, PrimitiveValue.Int32Value(v)) => |
| 104 | + case (StandardType.IntType, PrimitiveValue.Int32Value(v)) => |
77 | 105 | v
|
78 |
| - case (StandardType.LongType, PrimitiveValue.Int64Value(v)) => |
| 106 | + case (StandardType.LongType, PrimitiveValue.Int64Value(v)) => |
79 | 107 | v
|
80 |
| - case (StandardType.FloatType, PrimitiveValue.FloatValue(v)) => |
| 108 | + case (StandardType.FloatType, PrimitiveValue.FloatValue(v)) => |
81 | 109 | v
|
82 |
| - case (StandardType.DoubleType, PrimitiveValue.DoubleValue(v)) => |
| 110 | + case (StandardType.DoubleType, PrimitiveValue.DoubleValue(v)) => |
83 | 111 | v
|
84 |
| - case (StandardType.BinaryType, PrimitiveValue.BinaryValue(v)) => |
| 112 | + case (StandardType.BinaryType, PrimitiveValue.BinaryValue(v)) => |
85 | 113 | Chunk.fromArray(v.getBytes)
|
86 |
| - case (StandardType.CharType, PrimitiveValue.Int32Value(v)) => |
| 114 | + case (StandardType.CharType, PrimitiveValue.Int32Value(v)) => |
87 | 115 | v.toChar
|
88 |
| - case (StandardType.UUIDType, PrimitiveValue.BinaryValue(v)) => |
| 116 | + case (StandardType.UUIDType, PrimitiveValue.BinaryValue(v)) => |
89 | 117 | val bb = ByteBuffer.wrap(v.getBytes)
|
| 118 | + |
90 | 119 | new UUID(bb.getLong, bb.getLong)
|
91 |
| - case (other, _) => |
| 120 | + case (StandardType.BigDecimalType, PrimitiveValue.Int64Value(v)) => |
| 121 | + BigDecimal.valueOf(v, DECIMAL_SCALE) |
| 122 | + case (StandardType.BigIntegerType, PrimitiveValue.BinaryValue(v)) => |
| 123 | + new BigInteger(v.getBytes) |
| 124 | + case (StandardType.DayOfWeekType, PrimitiveValue.Int32Value(v)) => |
| 125 | + DayOfWeek.of(v) |
| 126 | + case (StandardType.MonthType, PrimitiveValue.Int32Value(v)) => |
| 127 | + Month.of(v) |
| 128 | + case (StandardType.MonthDayType, PrimitiveValue.BinaryValue(v)) => |
| 129 | + val bb = ByteBuffer.wrap(v.getBytes).order(ByteOrder.LITTLE_ENDIAN) |
| 130 | + |
| 131 | + MonthDay.of(bb.get.toInt, bb.get.toInt) |
| 132 | + case (StandardType.PeriodType, PrimitiveValue.BinaryValue(v)) => |
| 133 | + val bb = ByteBuffer.wrap(v.getBytes).order(ByteOrder.LITTLE_ENDIAN) |
| 134 | + |
| 135 | + Period.of(bb.getInt, bb.getInt, bb.getInt) |
| 136 | + case (StandardType.YearType, PrimitiveValue.Int32Value(v)) => |
| 137 | + Year.of(v) |
| 138 | + case (StandardType.YearMonthType, PrimitiveValue.BinaryValue(v)) => |
| 139 | + val bb = ByteBuffer.wrap(v.getBytes).order(ByteOrder.LITTLE_ENDIAN) |
| 140 | + |
| 141 | + YearMonth.of(bb.getShort.toInt, bb.getShort.toInt) |
| 142 | + case (StandardType.ZoneIdType, PrimitiveValue.BinaryValue(v)) => |
| 143 | + ZoneId.of(v.toStringUsingUTF8) |
| 144 | + case (StandardType.ZoneOffsetType, PrimitiveValue.BinaryValue(v)) => |
| 145 | + ZoneOffset.of(v.toStringUsingUTF8) |
| 146 | + case (StandardType.DurationType, PrimitiveValue.Int64Value(v)) => |
| 147 | + Duration.fromMillis(v) |
| 148 | + case (StandardType.InstantType, PrimitiveValue.Int64Value(v)) => |
| 149 | + Instant.ofEpochMilli(v) |
| 150 | + case (StandardType.LocalDateType, PrimitiveValue.Int32Value(v)) => |
| 151 | + LocalDate.ofEpochDay(v.toLong) |
| 152 | + case (StandardType.LocalTimeType, PrimitiveValue.Int32Value(v)) => |
| 153 | + localTime(v) |
| 154 | + case (StandardType.LocalDateTimeType, PrimitiveValue.Int64Value(v)) => |
| 155 | + localDateTime(v) |
| 156 | + case (StandardType.OffsetTimeType, PrimitiveValue.Int32Value(v)) => |
| 157 | + OffsetTime.of(localTime(v), ZoneOffset.UTC) |
| 158 | + case (StandardType.OffsetDateTimeType, PrimitiveValue.Int64Value(v)) => |
| 159 | + OffsetDateTime.of(localDateTime(v), ZoneOffset.UTC) |
| 160 | + case (StandardType.ZonedDateTimeType, PrimitiveValue.Int64Value(v)) => |
| 161 | + ZonedDateTime.of(localDateTime(v), ZoneId.of("Z")) |
| 162 | + case (other, _) => |
92 | 163 | throw DecoderError(s"Unsupported ZIO Schema StandartType $other")
|
93 | 164 | }
|
94 | 165 | }
|
|
0 commit comments