Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.clickhouse.data;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Serializable;
import java.io.StringReader;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* Wrapper of a value returned from ClickHouse. It could be as simple as one
* single byte or in a complex structure like nested arrays. It also provides
* convenient methods for type conversion(e.g. use {@link #asDateTime()} to
* convert an integer to {@link java.time.LocalDateTime}).
*/
public interface ClickHouseValue extends Serializable {
/**
* Create a customized exception for unsupported type conversion.
*
* @param from type to convert from
* @param to type to convert to
* @return customized exception
*/
default UnsupportedOperationException newUnsupportedException(String from, String to) {
return new UnsupportedOperationException(
ClickHouseUtils.format("Converting [%s] to [%s] is not supported", from, to));
}
/**
* Gets a shallow copy of this value object. Same as {@code copy(false)}.
*
* @return shallow copy of this value object
*/
default ClickHouseValue copy() {
return copy(false);
}
/**
* Gets a copy of this value object.
*
* @param deep true to create a deep copy; false for a shallow copy
* @return copy of this value object
*/
ClickHouseValue copy(boolean deep);
/**
* Checks if the value is either positive or negative infinity as defined in
* {@link Double}.
*
* @return true if it's infinity; false otherwise
*/
default boolean isInfinity() {
double value = asDouble();
return value == Double.NEGATIVE_INFINITY || value == Double.POSITIVE_INFINITY;
}
/**
* Checks if the value is Not-a-Number (NaN).
*
* @return true if the value is NaN; false otherwise
*/
default boolean isNaN() {
return Double.isNaN(asDouble());
}
/**
* Checks whether the value is nullable. This always returns {@code false} for
* nested value type.
*
* @return true if the value is nullable; false otherwise
*/
default boolean isNullable() {
return true;
}
/**
* Checks if the value is null, or empty for non-null types like Array, Tuple
* and Map.
*
*
* Please pay attention that only nullability will be considered for String,
* meaning this method will return {@code false} for an empty string. This is
* because String is treated as value-based type instead of a container like
* Array.
*
* @return true if the value is null or empty; false otherwise
*/
boolean isNullOrEmpty();
/**
* Gets value as an object array.
*
* @return non-null object array
*/
default Object[] asArray() {
if (isNullOrEmpty()) {
return ClickHouseValues.EMPTY_OBJECT_ARRAY;
}
return new Object[] { asObject() };
}
/**
* Gets value as an array.
*
* @param type of the element
* @param clazz class of the element
* @return non-null array
*/
@SuppressWarnings("unchecked")
default T[] asArray(Class clazz) {
if (isNullOrEmpty()) {
return (T[]) ClickHouseValues.EMPTY_OBJECT_ARRAY;
}
T[] array = (T[]) Array.newInstance(ClickHouseChecker.nonNull(clazz, ClickHouseValues.TYPE_CLASS), 1);
array[0] = asObject(clazz);
return array;
}
/**
* Gets value as byte stream. It's caller's responsibility to close the stream
* at the end of reading.
*
* @return non-null byte stream for reading
*/
default InputStream asByteStream() {
return isNullOrEmpty() ? ClickHouseInputStream.empty() : new ByteArrayInputStream(new byte[] { asByte() });
}
/**
* Gets value as character stream. It's caller's responsibility to close the
* tream at the end of reading.
*
* @return non-null character stream for reading
*/
default Reader asCharacterStream() {
// Reader.nullReader() requires JDK 11+
return new StringReader(isNullOrEmpty() ? "" : asString());
}
/**
* Gets value as boolean.
*
* @return boolean value
*/
default boolean asBoolean() {
return !isNullOrEmpty() && ClickHouseChecker.between(asByte(), 0, 1) == 1;
}
/**
* Gets value as character.
*
* @return character value
*/
default char asCharacter() {
return (char) asShort();
}
/**
* Gets value as byte.
*
* @return byte value
*/
byte asByte();
/**
* Gets value as short.
*
* @return short value
*/
short asShort();
/**
* Gets value as integer.
*
* @return integer value
*/
int asInteger();
/**
* Gets value as long.
*
* @return long value
*/
long asLong();
/**
* Gets value as {@link java.math.BigInteger}.
*
* @return big integer, could be null
*/
BigInteger asBigInteger();
/**
* Gets value as float.
*
* @return float value
*/
float asFloat();
/**
* Gets value as double.
*
* @return double value
*/
double asDouble();
/**
* Gets value as {@link java.math.BigDecimal}, using default scale(usually 0).
*
* @return big decimal, could be null
*/
default BigDecimal asBigDecimal() {
return asBigDecimal(0);
}
/**
* Gets value as {@link java.math.BigDecimal}.
*
* @param scale scale of the decimal
* @return big decimal, could be null
*/
BigDecimal asBigDecimal(int scale);
/**
* Gets value as {@link java.time.LocalDate}.
*
* @return date, could be null
*/
default LocalDate asDate() {
if (isNullOrEmpty()) {
return null;
}
return LocalDate.ofEpochDay(asLong());
}
/**
* Gets value as {@link java.time.LocalTime}.
*
* @return time, could be null
*/
default LocalTime asTime() {
return asTime(0);
}
/**
* Gets value as {@link java.time.LocalTime}.
*
* @param scale scale of the date time, between 0 (second) and 9 (nano second)
* @return time, could be null
*/
default LocalTime asTime(int scale) {
if (isNullOrEmpty()) {
return null;
}
return asDateTime(scale).toLocalTime();
}
/**
* Gets value as {@link java.time.LocalDateTime}, using default scale(usually
* 0).
*
* @return date time, could be null
*/
default LocalDateTime asDateTime() {
return asDateTime(0);
}
/**
* Gets value as {@link java.time.Instant}, using default scale(usually
* 0).
*
* @return date time, could be null
*/
default Instant asInstant() {
return asInstant(0);
}
/**
* Gets value as {@link java.time.OffsetDateTime}, using default scale(usually
* 0).
*
* @return date time, could be null
*/
default OffsetDateTime asOffsetDateTime() {
return asOffsetDateTime(0);
}
/**
* Gets value as {@link java.time.ZonedDateTime}, using default scale(usually
* 0).
*
* @return date time, could be null
*/
default ZonedDateTime asZonedDateTime() {
return asZonedDateTime(0);
}
/**
* Gets value as {@link java.time.LocalDateTime}.
*
* @param scale scale of the date time, between 0 (second) and 9 (nano second)
* @return date time, could be null
*/
default LocalDateTime asDateTime(int scale) {
if (isNullOrEmpty()) {
return null;
}
return ClickHouseValues
.convertToDateTime(asBigDecimal(ClickHouseChecker.between(scale, ClickHouseValues.PARAM_SCALE, 0, 9)));
}
/**
* Gets value as {@link java.time.Instant}.
*
* @param scale scale of the date time, between 0 (second) and 9 (nano second)
* @return instant, could be null
*/
default Instant asInstant(int scale) {
if (isNullOrEmpty()) {
return null;
}
return ClickHouseValues
.convertToInstant(asBigDecimal(ClickHouseChecker.between(scale, ClickHouseValues.PARAM_SCALE, 0, 9)));
}
/**
* Gets value as {@link java.time.OffsetDateTime}.
*
* @param scale scale of the date time, between 0 (second) and 9 (nano second)
* @return date time, could be null
*/
default OffsetDateTime asOffsetDateTime(int scale) {
if (isNullOrEmpty()) {
return null;
}
return asDateTime(scale).atOffset(ZoneOffset.UTC);
}
/**
* Gets value as {@link java.time.ZonedDateTime}.
*
* @param scale scale of the date time, between 0 (second) and 9 (nano second)
* @return date time, could be null
*/
default ZonedDateTime asZonedDateTime(int scale) {
if (isNullOrEmpty()) {
return null;
}
return asDateTime(scale).atZone(ClickHouseValues.UTC_ZONE);
}
/**
* Gets value as enum.
*
* @param type of the enum
* @param enumType enum class
* @return enum, could be null
*/
default > T asEnum(Class enumType) {
if (isNullOrEmpty()) {
return null;
}
int value = asInteger();
for (T t : ClickHouseChecker.nonNull(enumType, ClickHouseValues.TYPE_CLASS).getEnumConstants()) {
if (t.ordinal() == value) {
return t;
}
}
throw new IllegalArgumentException(
ClickHouseUtils.format("Ordinal[%d] not found in %s", value, enumType.getName()));
}
/**
* Gets value as {@link java.net.Inet4Address}.
*
* @return IPv4 address, could be null
*/
default Inet4Address asInet4Address() {
if (isNullOrEmpty()) {
return null;
}
return ClickHouseValues.convertToIpv4(asInteger());
}
/**
* Gets value as {@link java.net.Inet6Address}.
*
* @return IPv6 address, could be null
*/
default Inet6Address asInet6Address() {
if (isNullOrEmpty()) {
return null;
}
return ClickHouseValues.convertToIpv6(asBigInteger());
}
/**
* Gets value as a map.
*
* @return non-null map value
*/
default Map