com.datastax.oss.driver.api.core.data.SettableByIndex Maven / Gradle / Ivy
/*
* 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 com.datastax.oss.driver.api.core.data;
import com.datastax.oss.driver.api.core.metadata.token.Token;
import com.datastax.oss.driver.api.core.type.DataType;
import com.datastax.oss.driver.api.core.type.codec.CodecNotFoundException;
import com.datastax.oss.driver.api.core.type.codec.PrimitiveBooleanCodec;
import com.datastax.oss.driver.api.core.type.codec.PrimitiveByteCodec;
import com.datastax.oss.driver.api.core.type.codec.PrimitiveDoubleCodec;
import com.datastax.oss.driver.api.core.type.codec.PrimitiveFloatCodec;
import com.datastax.oss.driver.api.core.type.codec.PrimitiveIntCodec;
import com.datastax.oss.driver.api.core.type.codec.PrimitiveLongCodec;
import com.datastax.oss.driver.api.core.type.codec.PrimitiveShortCodec;
import com.datastax.oss.driver.api.core.type.codec.TypeCodec;
import com.datastax.oss.driver.api.core.type.reflect.GenericType;
import com.datastax.oss.driver.internal.core.metadata.token.ByteOrderedToken;
import com.datastax.oss.driver.internal.core.metadata.token.Murmur3Token;
import com.datastax.oss.driver.internal.core.metadata.token.RandomToken;
import edu.umd.cs.findbugs.annotations.CheckReturnValue;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.InetAddress;
import java.nio.ByteBuffer;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
/** A data structure that provides methods to set its values via an integer index. */
public interface SettableByIndex> extends AccessibleByIndex {
/**
* Sets the raw binary representation of the {@code i}th value.
*
* This is primarily for internal use; you'll likely want to use one of the typed setters
* instead, to pass a higher-level Java representation.
*
* @param v the raw value, or {@code null} to set the CQL value {@code NULL}. For performance
* reasons, this is the actual instance used internally. If pass in a buffer that you're going
* to modify elsewhere in your application, make sure to {@link ByteBuffer#duplicate()
* duplicate} it beforehand. If you change the buffer's index or its contents in any way,
* further usage of this data will have unpredictable results.
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
SelfT setBytesUnsafe(int i, @Nullable ByteBuffer v);
/**
* Sets the {@code i}th value to CQL {@code NULL}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setToNull(int i) {
return setBytesUnsafe(i, null);
}
/**
* Sets the {@code i}th value, using the given codec for the conversion.
*
*
This method completely bypasses the {@link #codecRegistry()}, and forces the driver to use
* the given codec instead. This can be useful if the codec would collide with a previously
* registered one, or if you want to use the codec just once without registering it.
*
*
It is the caller's responsibility to ensure that the given codec is appropriate for the
* conversion. Failing to do so will result in errors at runtime.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT set(int i, @Nullable ValueT v, @NonNull TypeCodec codec) {
return setBytesUnsafe(i, codec.encode(v, protocolVersion()));
}
/**
* Sets the {@code i}th value, converting it to the given Java type.
*
* The {@link #codecRegistry()} will be used to look up a codec to handle the conversion.
*
*
This variant is for generic Java types. If the target type is not generic, use {@link
* #set(int, Object, Class)} instead, which may perform slightly better.
*
* @throws IndexOutOfBoundsException if the index is invalid.
* @throws CodecNotFoundException if no codec can perform the conversion.
*/
@NonNull
@CheckReturnValue
default SelfT set(int i, @Nullable ValueT v, @NonNull GenericType targetType) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, targetType);
return set(i, v, codec);
}
/**
* Returns the {@code i}th value, converting it to the given Java type.
*
* The {@link #codecRegistry()} will be used to look up a codec to handle the conversion.
*
*
If the target type is generic, use {@link #set(int, Object, GenericType)} instead.
*
* @throws IndexOutOfBoundsException if the index is invalid.
* @throws CodecNotFoundException if no codec can perform the conversion.
*/
@NonNull
@CheckReturnValue
default SelfT set(int i, @Nullable ValueT v, @NonNull Class targetClass) {
// This is duplicated from the GenericType variant, because we want to give the codec registry
// a chance to process the unwrapped class directly, if it can do so in a more efficient way.
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, targetClass);
return set(i, v, codec);
}
/**
* Sets the {@code i}th value to the provided Java primitive boolean.
*
* By default, this works with CQL type {@code boolean}.
*
*
To set the value to CQL {@code NULL}, use {@link #setToNull(int)}, or {@code set(i, v,
* Boolean.class)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setBoolean(int i, boolean v) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, Boolean.class);
return (codec instanceof PrimitiveBooleanCodec)
? setBytesUnsafe(i, ((PrimitiveBooleanCodec) codec).encodePrimitive(v, protocolVersion()))
: set(i, v, codec);
}
/**
* @deprecated this method only exists to ease the transition from driver 3, it is an alias for
* {@link #setBoolean(int, boolean)}.
*/
@Deprecated
@NonNull
@CheckReturnValue
default SelfT setBool(int i, boolean v) {
return setBoolean(i, v);
}
/**
* Sets the {@code i}th value to the provided Java primitive byte.
*
* By default, this works with CQL type {@code tinyint}.
*
*
To set the value to CQL {@code NULL}, use {@link #setToNull(int)}, or {@code set(i, v,
* Boolean.class)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setByte(int i, byte v) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, Byte.class);
return (codec instanceof PrimitiveByteCodec)
? setBytesUnsafe(i, ((PrimitiveByteCodec) codec).encodePrimitive(v, protocolVersion()))
: set(i, v, codec);
}
/**
* Sets the {@code i}th value to the provided Java primitive double.
*
* By default, this works with CQL type {@code double}.
*
*
To set the value to CQL {@code NULL}, use {@link #setToNull(int)}, or {@code set(i, v,
* Double.class)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setDouble(int i, double v) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, Double.class);
return (codec instanceof PrimitiveDoubleCodec)
? setBytesUnsafe(i, ((PrimitiveDoubleCodec) codec).encodePrimitive(v, protocolVersion()))
: set(i, v, codec);
}
/**
* Sets the {@code i}th value to the provided Java primitive float.
*
* By default, this works with CQL type {@code float}.
*
*
To set the value to CQL {@code NULL}, use {@link #setToNull(int)}, or {@code set(i, v,
* Float.class)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setFloat(int i, float v) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, Float.class);
return (codec instanceof PrimitiveFloatCodec)
? setBytesUnsafe(i, ((PrimitiveFloatCodec) codec).encodePrimitive(v, protocolVersion()))
: set(i, v, codec);
}
/**
* Sets the {@code i}th value to the provided Java primitive integer.
*
* By default, this works with CQL type {@code int}.
*
*
To set the value to CQL {@code NULL}, use {@link #setToNull(int)}, or {@code set(i, v,
* Integer.class)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setInt(int i, int v) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, Integer.class);
return (codec instanceof PrimitiveIntCodec)
? setBytesUnsafe(i, ((PrimitiveIntCodec) codec).encodePrimitive(v, protocolVersion()))
: set(i, v, codec);
}
/**
* Sets the {@code i}th value to the provided Java primitive long.
*
* By default, this works with CQL types {@code bigint} and {@code counter}.
*
*
To set the value to CQL {@code NULL}, use {@link #setToNull(int)}, or {@code set(i, v,
* Long.class)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setLong(int i, long v) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, Long.class);
return (codec instanceof PrimitiveLongCodec)
? setBytesUnsafe(i, ((PrimitiveLongCodec) codec).encodePrimitive(v, protocolVersion()))
: set(i, v, codec);
}
/**
* Sets the {@code i}th value to the provided Java primitive short.
*
* By default, this works with CQL type {@code smallint}.
*
*
To set the value to CQL {@code NULL}, use {@link #setToNull(int)}, or {@code set(i, v,
* Short.class)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setShort(int i, short v) {
DataType cqlType = getType(i);
TypeCodec codec = codecRegistry().codecFor(cqlType, Short.class);
return (codec instanceof PrimitiveShortCodec)
? setBytesUnsafe(i, ((PrimitiveShortCodec) codec).encodePrimitive(v, protocolVersion()))
: set(i, v, codec);
}
/**
* Sets the {@code i}th value to the provided Java instant.
*
* By default, this works with CQL type {@code timestamp}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setInstant(int i, @Nullable Instant v) {
return set(i, v, Instant.class);
}
/**
* Sets the {@code i}th value to the provided Java local date.
*
*
By default, this works with CQL type {@code date}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setLocalDate(int i, @Nullable LocalDate v) {
return set(i, v, LocalDate.class);
}
/**
* Sets the {@code i}th value to the provided Java local time.
*
*
By default, this works with CQL type {@code time}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setLocalTime(int i, @Nullable LocalTime v) {
return set(i, v, LocalTime.class);
}
/**
* Sets the {@code i}th value to the provided Java byte buffer.
*
*
By default, this works with CQL type {@code blob}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setByteBuffer(int i, @Nullable ByteBuffer v) {
return set(i, v, ByteBuffer.class);
}
/**
* Sets the {@code i}th value to the provided Java string.
*
*
By default, this works with CQL types {@code text}, {@code varchar} and {@code ascii}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setString(int i, @Nullable String v) {
return set(i, v, String.class);
}
/**
* Sets the {@code i}th value to the provided Java big integer.
*
*
By default, this works with CQL type {@code varint}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setBigInteger(int i, @Nullable BigInteger v) {
return set(i, v, BigInteger.class);
}
/**
* Sets the {@code i}th value to the provided Java big decimal.
*
*
By default, this works with CQL type {@code decimal}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setBigDecimal(int i, @Nullable BigDecimal v) {
return set(i, v, BigDecimal.class);
}
/**
* Sets the {@code i}th value to the provided Java UUID.
*
*
By default, this works with CQL types {@code uuid} and {@code timeuuid}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setUuid(int i, @Nullable UUID v) {
return set(i, v, UUID.class);
}
/**
* Sets the {@code i}th value to the provided Java IP address.
*
*
By default, this works with CQL type {@code inet}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setInetAddress(int i, @Nullable InetAddress v) {
return set(i, v, InetAddress.class);
}
/**
* Sets the {@code i}th value to the provided duration.
*
*
By default, this works with CQL type {@code duration}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setCqlDuration(int i, @Nullable CqlDuration v) {
return set(i, v, CqlDuration.class);
}
/**
* Sets the {@code i}th value to the provided vector.
*
*
By default, this works with CQL type {@code vector}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setVector(
int i, @Nullable CqlVector v, @NonNull Class elementsClass) {
return set(i, v, GenericType.vectorOf(elementsClass));
}
/**
* Sets the {@code i}th value to the provided token.
*
* This works with the CQL type matching the partitioner in use for this cluster: {@code
* bigint} for {@code Murmur3Partitioner}, {@code blob} for {@code ByteOrderedPartitioner}, and
* {@code varint} for {@code RandomPartitioner}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setToken(int i, @NonNull Token v) {
// Simply enumerate all known implementations. This goes against the concept of TokenFactory,
// but injecting the factory here is too much of a hassle.
// The only issue is if someone uses a custom partitioner, but this is highly unlikely, and even
// then they can set the value manually as a workaround.
if (v instanceof Murmur3Token) {
return setLong(i, ((Murmur3Token) v).getValue());
} else if (v instanceof ByteOrderedToken) {
return setByteBuffer(i, ((ByteOrderedToken) v).getValue());
} else if (v instanceof RandomToken) {
return setBigInteger(i, ((RandomToken) v).getValue());
} else {
throw new IllegalArgumentException("Unsupported token type " + v.getClass());
}
}
/**
* Sets the {@code i}th value to the provided Java list.
*
*
By default, this works with CQL type {@code list}.
*
*
This method is provided for convenience when the element type is a non-generic type. For
* more complex list types, use {@link #set(int, Object, GenericType)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setList(
int i, @Nullable List v, @NonNull Class elementsClass) {
return set(i, v, GenericType.listOf(elementsClass));
}
/**
* Sets the {@code i}th value to the provided Java set.
*
* By default, this works with CQL type {@code set}.
*
*
This method is provided for convenience when the element type is a non-generic type. For
* more complex set types, use {@link #set(int, Object, GenericType)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setSet(
int i, @Nullable Set v, @NonNull Class elementsClass) {
return set(i, v, GenericType.setOf(elementsClass));
}
/**
* Sets the {@code i}th value to the provided Java map.
*
* By default, this works with CQL type {@code map}.
*
*
This method is provided for convenience when the element type is a non-generic type. For
* more complex map types, use {@link #set(int, Object, GenericType)}.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setMap(
int i,
@Nullable Map v,
@NonNull Class keyClass,
@NonNull Class valueClass) {
return set(i, v, GenericType.mapOf(keyClass, valueClass));
}
/**
* Sets the {@code i}th value to the provided user defined type value.
*
* By default, this works with CQL user-defined types.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setUdtValue(int i, @Nullable UdtValue v) {
return set(i, v, UdtValue.class);
}
/**
* Sets the {@code i}th value to the provided tuple value.
*
*
By default, this works with CQL tuples.
*
* @throws IndexOutOfBoundsException if the index is invalid.
*/
@NonNull
@CheckReturnValue
default SelfT setTupleValue(int i, @Nullable TupleValue v) {
return set(i, v, TupleValue.class);
}
}