All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
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.
com.clickhouse.data.value.ClickHouseNestedValue Maven / Gradle / Ivy
package com.clickhouse.data.value;
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import com.clickhouse.data.ClickHouseChecker;
import com.clickhouse.data.ClickHouseColumn;
import com.clickhouse.data.ClickHouseValue;
import com.clickhouse.data.ClickHouseValues;
/**
* Wrapper class of Nested.
*/
public class ClickHouseNestedValue extends ClickHouseObjectValue {
/**
* Creates an empty nested value.
*
* @param columns non-null columns
* @return empty nested value
*/
public static ClickHouseNestedValue ofEmpty(List columns) {
return of(null, columns, new Object[0][]);
}
/**
* Wrap the given value.
*
* @param columns columns
* @param values values
* @return object representing the value
*/
public static ClickHouseNestedValue of(List columns, Object[][] values) {
return of(null, columns, values);
}
/**
* Update value of the given object or create a new instance if {@code ref} is
* null.
*
* @param ref object to update, could be null
* @param columns columns
* @param values values
* @return same object as {@code ref} or a new instance if it's null
*/
public static ClickHouseNestedValue of(ClickHouseValue ref, List columns, Object[][] values) {
return ref instanceof ClickHouseNestedValue
? ((ClickHouseNestedValue) ref).set(values != null ? values : ClickHouseValues.EMPTY_OBJECT_ARRAY2)
: new ClickHouseNestedValue(columns, values);
}
protected static Object[][] check(List columns, Object[][] value) {
if (columns == null || value == null) {
throw new IllegalArgumentException("Non-null columns and value are required");
}
int size = columns.size();
for (int i = 0, len = value.length; i < len; i++) {
Object[] objs = value[i];
if (objs == null || objs.length != size) {
throw new IllegalArgumentException("Columns and values should have same length");
}
}
return value;
}
private final List columns;
protected ClickHouseNestedValue(List columns, Object[][] values) {
super(check(columns, values));
this.columns = columns;
}
protected Object getSingleValue() {
Object[][] value = getValue();
if (value == null || value.length != 1 || value[0] == null || value[0].length != 1) {
throw new UnsupportedOperationException(
"Only nested object containing only one value(one column and one row) supports type conversion");
}
return value[0][0];
}
@Override
protected ClickHouseNestedValue set(Object[][] value) {
if (columns == null && getValue() == null) { // must be called from constructor
super.set(value);
} else {
super.set(check(columns, value));
}
return this;
}
/**
* Gets immutable list of nested columns.
*
* @return immutable list of columns
*/
public List getColumns() {
return Collections.unmodifiableList(columns);
}
@Override
public ClickHouseNestedValue copy(boolean deep) {
if (!deep) {
return new ClickHouseNestedValue(columns, getValue());
}
Object[][] value = getValue();
int len = value.length;
Object[][] newValue = new Object[len][];
for (int i = 0; i < len; i++) {
Object[] v = value[i];
newValue[i] = Arrays.copyOf(v, v.length);
}
return new ClickHouseNestedValue(columns, newValue);
}
@Override
public Object[] asArray() {
return getValue();
}
@Override
@SuppressWarnings("unchecked")
public T[] asArray(Class clazz) {
Object[][] v = getValue();
T[] array = (T[]) Array.newInstance(ClickHouseChecker.nonNull(clazz, ClickHouseValues.TYPE_CLASS), v.length);
int index = 0;
for (Object[] o : v) {
array[index++] = clazz.cast(o);
}
return array;
}
@Override
public Map asMap() {
Object[][] values = getValue();
int len = values.length;
if (len == 0) {
return Collections.emptyMap();
}
Map map = new LinkedHashMap<>();
for (int i = 0, size = columns.size(); i < size; i++) {
Object[] v = new Object[len];
for (int j = 0; j < len; j++) {
v[j] = values[j][i];
}
map.put(columns.get(i).getColumnName(), v);
}
// why not use Collections.unmodifiableMap(map) here?
return map;
}
@Override
public Map asMap(Class keyClass, Class valueClass) {
if (keyClass == null || valueClass == null) {
throw new IllegalArgumentException("Non-null key and value classes are required");
}
Object[][] values = getValue();
int len = values.length;
if (len == 0) {
return Collections.emptyMap();
}
Map map = new LinkedHashMap<>();
int size = columns.size();
if (len == 1 && !valueClass.isArray()) {
for (int i = 0; i < size; i++) {
map.put(keyClass.cast(columns.get(i).getColumnName()), valueClass.cast(values[i][0]));
}
} else if (!valueClass.isArray()) {
throw new IllegalArgumentException("Value class should be array");
}
Class> compClass = valueClass.getComponentType();
if (compClass == Object.class) {
for (int i = 0; i < size; i++) {
Object[] v = new Object[len];
for (int j = 0; j < len; j++) {
v[j] = values[j][i];
}
map.put(keyClass.cast(columns.get(i).getColumnName()), valueClass.cast(v));
}
} else {
for (int i = 0; i < size; i++) {
Object[] v = (Object[]) Array.newInstance(compClass, len);
for (int j = 0; j < len; j++) {
v[j] = compClass.cast(values[j][i]);
}
map.put(keyClass.cast(columns.get(i).getColumnName()), valueClass.cast(v));
}
}
// why not use Collections.unmodifiableMap(map) here?
return map;
}
@Override
public String asString() {
return Arrays.deepToString(getValue());
}
@Override
public boolean isNullable() {
return false;
}
@Override
public boolean isNullOrEmpty() {
Object[][] value = getValue();
return value == null || value.length == 0;
}
@Override
public ClickHouseNestedValue resetToDefault() {
set(ClickHouseValues.EMPTY_OBJECT_ARRAY2);
return this;
}
@Override
public ClickHouseNestedValue resetToNullOrEmpty() {
return resetToDefault();
}
@Override
public String toSqlExpression() {
Object[][] value = getValue();
if (value == null || value.length == 0) {
return ClickHouseValues.EMPTY_ARRAY_EXPR;
}
StringBuilder builder = new StringBuilder();
for (Object[] v : value) {
if (v == null || v.length == 0) {
builder.append(ClickHouseValues.EMPTY_ARRAY_EXPR);
} else {
builder.append('[');
for (Object o : v) {
builder.append(ClickHouseValues.convertToSqlExpression(o)).append(',');
}
builder.setLength(builder.length() - 1);
builder.append(']');
}
builder.append(',');
}
builder.setLength(builder.length() - 1);
return builder.toString();
}
@Override
public ClickHouseNestedValue update(boolean value) {
set(new Object[][] { new Byte[] { value ? (byte) 1 : (byte) 0 } });
return this;
}
@Override
public ClickHouseNestedValue update(boolean[] value) {
int len = value == null ? 0 : value.length;
Byte[] v = new Byte[len];
if (len > 0) {
int index = 0;
for (boolean b : value) {
v[index++] = b ? (byte) 1 : (byte) 0;
}
}
set(new Object[][] { v });
return this;
}
@Override
public ClickHouseNestedValue update(char value) {
set(new Object[][] { new Integer[] { (int) value } });
return this;
}
@Override
public ClickHouseNestedValue update(char[] value) {
int len = value == null ? 0 : value.length;
Integer[] v = new Integer[len];
if (len > 0) {
int index = 0;
for (char c : value) {
v[index++] = (int) c;
}
}
set(new Object[][] { v });
return this;
}
@Override
public ClickHouseNestedValue update(byte value) {
set(new Object[][] { new Object[] { value } });
return this;
}
@Override
public ClickHouseNestedValue update(byte[] value) {
int len = value == null ? 0 : value.length;
Byte[] v = new Byte[len];
if (len > 0) {
int index = 0;
for (byte b : value) {
v[index++] = b;
}
}
set(new Object[][] { v });
return this;
}
@Override
public ClickHouseNestedValue update(short value) {
set(new Object[][] { new Short[] { value } });
return this;
}
@Override
public ClickHouseNestedValue update(short[] value) {
int len = value == null ? 0 : value.length;
Short[] v = new Short[len];
if (len > 0) {
int index = 0;
for (short s : value) {
v[index++] = s;
}
}
set(new Object[][] { v });
return this;
}
@Override
public ClickHouseNestedValue update(int value) {
set(new Object[][] { new Integer[] { value } });
return this;
}
@Override
public ClickHouseNestedValue update(int[] value) {
int len = value == null ? 0 : value.length;
Integer[] v = new Integer[len];
if (len > 0) {
int index = 0;
for (int i : value) {
v[index++] = i;
}
}
set(new Object[][] { v });
return this;
}
@Override
public ClickHouseNestedValue update(long value) {
set(new Object[][] { new Long[] { value } });
return this;
}
@Override
public ClickHouseNestedValue update(long[] value) {
int len = value == null ? 0 : value.length;
Long[] v = new Long[len];
if (len > 0) {
int index = 0;
for (long l : value) {
v[index++] = l;
}
}
set(new Object[][] { v });
return this;
}
@Override
public ClickHouseNestedValue update(float value) {
set(new Object[][] { new Float[] { value } });
return this;
}
@Override
public ClickHouseNestedValue update(float[] value) {
int len = value == null ? 0 : value.length;
Float[] v = new Float[len];
if (len > 0) {
int index = 0;
for (float f : value) {
v[index++] = f;
}
}
set(new Object[][] { v });
return this;
}
@Override
public ClickHouseNestedValue update(double value) {
set(new Object[][] { new Double[] { value } });
return this;
}
@Override
public ClickHouseNestedValue update(double[] value) {
int len = value == null ? 0 : value.length;
Double[] v = new Double[len];
if (len > 0) {
int index = 0;
for (double d : value) {
v[index++] = d;
}
}
return set(new Object[][] { v });
}
@Override
public ClickHouseNestedValue update(BigInteger value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new BigInteger[] { value } });
}
@Override
public ClickHouseNestedValue update(BigDecimal value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new BigDecimal[] { value } });
}
@Override
public ClickHouseNestedValue update(Enum> value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new Enum[] { value } });
}
@Override
public ClickHouseNestedValue update(Inet4Address value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new Inet4Address[] { value } });
}
@Override
public ClickHouseNestedValue update(Inet6Address value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new Inet6Address[] { value } });
}
@Override
public ClickHouseNestedValue update(LocalDate value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new LocalDate[] { value } });
}
@Override
public ClickHouseNestedValue update(LocalTime value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new LocalTime[] { value } });
}
@Override
public ClickHouseNestedValue update(LocalDateTime value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new LocalDateTime[] { value } });
}
@Override
public ClickHouseNestedValue update(Collection> value) {
int size = value == null ? 0 : value.size();
if (size == 0) {
return resetToNullOrEmpty();
}
Object[] v = new Object[size];
int index = 0;
for (Object o : value) {
v[index++] = o;
}
return set(new Object[][] { v });
}
@Override
public ClickHouseNestedValue update(Enumeration> value) {
if (value == null) {
return resetToNullOrEmpty();
}
List v = new LinkedList<>();
while (value.hasMoreElements()) {
v.add(value.nextElement());
}
return set(new Object[][] { v.toArray(new Object[v.size()]) });
}
@Override
public ClickHouseNestedValue update(Map, ?> value) {
int size = value == null ? 0 : value.size();
if (size == 0) {
return resetToNullOrEmpty();
}
Object[] v = new Object[size];
int index = 0;
for (Object o : value.values()) {
v[index++] = o;
}
return set(new Object[][] { v });
}
@Override
public ClickHouseNestedValue update(String value) {
if (value == null) {
resetToNullOrEmpty();
} else if (value.isEmpty() || ClickHouseValues.EMPTY_ARRAY_EXPR.equals(value)) {
resetToDefault();
} else {
// TODO parse string
set(new Object[][] { new String[] { value } });
}
return this;
}
@Override
public ClickHouseNestedValue update(UUID value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new UUID[] { value } });
}
@Override
public ClickHouseNestedValue update(ClickHouseValue value) {
if (value == null || value.isNullOrEmpty()) {
return resetToNullOrEmpty();
} else if (value instanceof ClickHouseNestedValue) {
set(((ClickHouseNestedValue) value).getValue());
} else {
set(new Object[][] { value.asArray() });
}
return this;
}
@Override
public ClickHouseNestedValue update(Object[] value) {
if (value == null) {
return resetToNullOrEmpty();
} else if (value instanceof Object[][]) {
set((Object[][]) value);
} else {
set(new Object[][] { value });
}
return this;
}
@Override
public ClickHouseValue updateUnknown(Object value) {
if (value == null) {
return resetToNullOrEmpty();
}
return set(new Object[][] { new Object[] { value } });
}
@Override
public ClickHouseNestedValue update(Object value) {
if (value instanceof Object[][]) {
set((Object[][]) value);
} else {
super.update(value);
}
return this;
}
@Override
public boolean equals(Object obj) {
if (this == obj) { // too bad this is a mutable class :<
return true;
} else if (obj == null || getClass() != obj.getClass()) {
return false;
}
return Arrays.deepEquals(getValue(), ((ClickHouseArrayValue>) obj).getValue());
}
@Override
public int hashCode() {
return Arrays.deepHashCode(getValue());
}
}