| /* |
| * 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.drill.exec.store.pojo; |
| |
| import io.netty.buffer.DrillBuf; |
| |
| import java.math.BigDecimal; |
| import java.sql.Timestamp; |
| |
| import org.apache.drill.common.exceptions.ExecutionSetupException; |
| import org.apache.drill.common.types.TypeProtos.MinorType; |
| import org.apache.drill.common.types.Types; |
| import org.apache.drill.exec.expr.holders.NullableVarCharHolder; |
| import org.apache.drill.exec.vector.BigIntVector; |
| import org.apache.drill.exec.vector.BitVector; |
| import org.apache.drill.exec.vector.Float4Vector; |
| import org.apache.drill.exec.vector.Float8Vector; |
| import org.apache.drill.exec.vector.IntVector; |
| import org.apache.drill.exec.vector.NullableBigIntVector; |
| import org.apache.drill.exec.vector.NullableBitVector; |
| import org.apache.drill.exec.vector.NullableFloat4Vector; |
| import org.apache.drill.exec.vector.NullableFloat8Vector; |
| import org.apache.drill.exec.vector.NullableIntVector; |
| import org.apache.drill.exec.vector.NullableTimeStampVector; |
| import org.apache.drill.exec.vector.NullableVarCharVector; |
| |
| import com.google.common.base.Charsets; |
| import org.apache.drill.exec.vector.VarDecimalVector; |
| |
| public class PojoWriters { |
| |
| /** |
| * Creates matching writer to the given field type. |
| * |
| * @param type field type |
| * @param fieldName field name |
| * @param buffer drill buffer |
| * @return pojo writer |
| * @throws ExecutionSetupException in case if writer was not found for the given type |
| */ |
| public static PojoWriter getWriter(Class<?> type, String fieldName, DrillBuf buffer) throws ExecutionSetupException { |
| |
| if (type == Integer.class) { |
| return new NIntWriter(fieldName); |
| } else if (type == Long.class) { |
| return new NBigIntWriter(fieldName); |
| } else if (type == Boolean.class) { |
| return new NBooleanWriter(fieldName); |
| } else if (type == Float.class) { |
| return new NFloatWriter(fieldName); |
| } else if (type == Double.class) { |
| return new NDoubleWriter(fieldName); |
| } else if (type.isEnum()) { |
| return new EnumWriter(fieldName, buffer); |
| } else if (type == String.class) { |
| return new StringWriter(fieldName, buffer); |
| } else if (type == BigDecimal.class) { |
| return new DecimalWriter(fieldName); |
| } else if (type == Timestamp.class) { |
| return new NTimeStampWriter(fieldName); |
| // primitives |
| } else if (type == int.class) { |
| return new IntWriter(fieldName); |
| } else if (type == float.class) { |
| return new FloatWriter(fieldName); |
| } else if (type == double.class) { |
| return new DoubleWriter(fieldName); |
| } else if (type == boolean.class) { |
| return new BitWriter(fieldName); |
| } else if (type == long.class) { |
| return new LongWriter(fieldName); |
| } |
| |
| throw new ExecutionSetupException(String.format("PojoRecordReader doesn't yet support conversions from the type [%s].", type)); |
| } |
| |
| /** |
| * Pojo writer for int. Does not expect to write null value. |
| */ |
| public static class IntWriter extends AbstractPojoWriter<IntVector> { |
| |
| public IntWriter(String fieldName) { |
| super(fieldName, Types.required(MinorType.INT)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| vector.getMutator().setSafe(outboundIndex, (int) value); |
| } |
| } |
| |
| /** |
| * Pojo writer for boolean. Does not expect to write null value. |
| */ |
| public static class BitWriter extends AbstractPojoWriter<BitVector> { |
| |
| public BitWriter(String fieldName) { |
| super(fieldName, Types.required(MinorType.BIT)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| vector.getMutator().setSafe(outboundIndex, (boolean) value ? 1 : 0); |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for long. Does not expect to write null value. |
| */ |
| public static class LongWriter extends AbstractPojoWriter<BigIntVector> { |
| |
| public LongWriter(String fieldName) { |
| super(fieldName, Types.required(MinorType.BIGINT)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| vector.getMutator().setSafe(outboundIndex, (long) value); |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for float. Does not expect to write null value. |
| */ |
| public static class FloatWriter extends AbstractPojoWriter<Float4Vector> { |
| |
| public FloatWriter(String fieldName) { |
| super(fieldName, Types.required(MinorType.FLOAT4)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| vector.getMutator().setSafe(outboundIndex, (float) value); |
| } |
| |
| } |
| /** |
| * Pojo writer for double. Does not expect to write null value. |
| */ |
| public static class DoubleWriter extends AbstractPojoWriter<Float8Vector> { |
| |
| public DoubleWriter(String fieldName) { |
| super(fieldName, Types.required(MinorType.FLOAT8)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| vector.getMutator().setSafe(outboundIndex, (double) value); |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for decimal. If null is encountered does not write it. |
| */ |
| public static class DecimalWriter extends AbstractPojoWriter<VarDecimalVector> { |
| |
| public DecimalWriter(String fieldName) { |
| super(fieldName, Types.optional(MinorType.VARDECIMAL)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| vector.getMutator().setSafe(outboundIndex, (BigDecimal) value); |
| } |
| } |
| |
| } |
| |
| /** |
| * Parent class for String and Enum writers. Writes data using nullable varchar holder. |
| */ |
| private abstract static class AbstractStringWriter extends AbstractPojoWriter<NullableVarCharVector> { |
| private DrillBuf data; |
| private final NullableVarCharHolder holder = new NullableVarCharHolder(); |
| |
| public AbstractStringWriter(String fieldName, DrillBuf managedBuf) { |
| super(fieldName, Types.optional(MinorType.VARCHAR)); |
| this.data = managedBuf; |
| ensureLength(100); |
| } |
| |
| void ensureLength(int len) { |
| data = data.reallocIfNeeded(len); |
| } |
| |
| public void writeString(String s, int outboundIndex) { |
| holder.isSet = 1; |
| byte[] bytes = s.getBytes(Charsets.UTF_8); |
| ensureLength(bytes.length); |
| data.clear(); |
| data.writeBytes(bytes); |
| holder.buffer = data; |
| holder.start = 0; |
| holder.end = bytes.length; |
| vector.getMutator().setSafe(outboundIndex, holder); |
| } |
| } |
| |
| /** |
| * Pojo writer for Enum. If null is encountered does not write it. |
| */ |
| public static class EnumWriter extends AbstractStringWriter{ |
| public EnumWriter(String fieldName, DrillBuf managedBuf) { |
| super(fieldName, managedBuf); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value == null) { |
| return; |
| } |
| writeString(((Enum<?>) value).name(), outboundIndex); |
| } |
| } |
| |
| /** |
| * Pojo writer for String. If null is encountered does not write it. |
| */ |
| public static class StringWriter extends AbstractStringWriter { |
| public StringWriter(String fieldName, DrillBuf managedBuf) { |
| super(fieldName, managedBuf); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| writeString((String) value, outboundIndex); |
| } |
| } |
| } |
| |
| /** |
| * Pojo writer for Integer. If null is encountered does not write it. |
| */ |
| public static class NIntWriter extends AbstractPojoWriter<NullableIntVector> { |
| |
| public NIntWriter(String fieldName) { |
| super(fieldName, Types.optional(MinorType.INT)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| vector.getMutator().setSafe(outboundIndex, (Integer) value); |
| } |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for Long. If null is encountered does not write it. |
| */ |
| public static class NBigIntWriter extends AbstractPojoWriter<NullableBigIntVector> { |
| |
| public NBigIntWriter(String fieldName) { |
| super(fieldName, Types.optional(MinorType.BIGINT)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| vector.getMutator().setSafe(outboundIndex, (Long) value); |
| } |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for Boolean. If null is encountered does not write it. |
| */ |
| public static class NBooleanWriter extends AbstractPojoWriter<NullableBitVector> { |
| |
| public NBooleanWriter(String fieldName) { |
| super(fieldName, Types.optional(MinorType.BIT)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| vector.getMutator().setSafe(outboundIndex, (Boolean) value ? 1 : 0); |
| } |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for Float. If null is encountered does not write it. |
| */ |
| public static class NFloatWriter extends AbstractPojoWriter<NullableFloat4Vector> { |
| |
| public NFloatWriter(String fieldName) { |
| super(fieldName, Types.optional(MinorType.FLOAT4)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| vector.getMutator().setSafe(outboundIndex, (Float) value); |
| } |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for Double. If null is encountered does not write it. |
| */ |
| public static class NDoubleWriter extends AbstractPojoWriter<NullableFloat8Vector> { |
| |
| public NDoubleWriter(String fieldName) { |
| super(fieldName, Types.optional(MinorType.FLOAT8)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| vector.getMutator().setSafe(outboundIndex, (Double) value); |
| } |
| } |
| |
| } |
| |
| /** |
| * Pojo writer for Timestamp. If null is encountered does not write it. |
| */ |
| public static class NTimeStampWriter extends AbstractPojoWriter<NullableTimeStampVector> { |
| |
| public NTimeStampWriter(String fieldName) { |
| super(fieldName, Types.optional(MinorType.TIMESTAMP)); |
| } |
| |
| @Override |
| public void writeField(Object value, int outboundIndex) { |
| if (value != null) { |
| vector.getMutator().setSafe(outboundIndex, ((Timestamp) value).getTime()); |
| } |
| } |
| } |
| } |