All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.datastax.oss.driver.api.core.type.codec.ExtraTypeCodecs Maven / Gradle / Ivy

The newest version!
/*
 * 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.type.codec;

import com.datastax.oss.driver.api.core.session.SessionBuilder;
import com.datastax.oss.driver.api.core.type.DataTypes;
import com.datastax.oss.driver.api.core.type.codec.registry.MutableCodecRegistry;
import com.datastax.oss.driver.api.core.type.reflect.GenericType;
import com.datastax.oss.driver.internal.core.type.DefaultVectorType;
import com.datastax.oss.driver.internal.core.type.codec.SimpleBlobCodec;
import com.datastax.oss.driver.internal.core.type.codec.TimestampCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.OptionalCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.BooleanListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.ByteListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.DoubleListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.FloatListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.IntListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.LongListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.ObjectListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.array.ShortListToArrayCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.enums.EnumNameCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.enums.EnumOrdinalCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.json.JsonCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.time.LocalTimestampCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.time.PersistentZonedTimestampCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.time.TimestampMillisCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.time.ZonedTimestampCodec;
import com.datastax.oss.driver.internal.core.type.codec.extras.vector.FloatVectorToArrayCodec;
import com.datastax.oss.driver.shaded.fasterxml.jackson.databind.ObjectMapper;
import edu.umd.cs.findbugs.annotations.NonNull;
import java.nio.ByteBuffer;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Optional;

/**
 * Additional codecs that can be registered to handle different type mappings.
 *
 * @see SessionBuilder#addTypeCodecs(TypeCodec[])
 * @see MutableCodecRegistry#register(TypeCodec)
 */
public class ExtraTypeCodecs {

  /**
   * A codec that maps CQL type {@code timestamp} to Java's {@link Instant}, using the UTC time zone
   * to parse and format CQL literals.
   *
   * 

This codec uses {@link ZoneOffset#UTC} as its source of time zone information when * formatting values as CQL literals, or parsing CQL literals that do not have any time zone * indication. Note that this only applies to the {@link TypeCodec#format(Object)} and {@link * TypeCodec#parse(String)} methods; regular encoding and decoding, like setting a value on a * bound statement or reading a column from a row, are not affected by the time zone. * *

If you need a different time zone, consider other constants in this class, or call {@link * ExtraTypeCodecs#timestampAt(ZoneId)} instead. * * @see TypeCodecs#TIMESTAMP * @see ExtraTypeCodecs#timestampAt(ZoneId) */ public static final TypeCodec TIMESTAMP_UTC = new TimestampCodec(ZoneOffset.UTC); /** * A codec that maps CQL type {@code timestamp} to Java's {@code long}, representing the number of * milliseconds since the Epoch, using the system's default time zone to parse and format CQL * literals. * *

This codec uses the system's {@linkplain ZoneId#systemDefault() default time zone} as its * source of time zone information when formatting values as CQL literals, or parsing CQL literals * that do not have any time zone indication. Note that this only applies to the {@link * TypeCodec#format(Object)} and {@link TypeCodec#parse(String)} methods; regular encoding and * decoding, like setting a value on a bound statement or reading a column from a row, are not * affected by the time zone. * *

If you need a different time zone, consider other constants in this class, or call {@link * #timestampMillisAt(ZoneId)} instead. * *

This codec can serve as a replacement for the driver's built-in {@linkplain * TypeCodecs#TIMESTAMP timestamp} codec, when application code prefers to deal with raw * milliseconds than with {@link Instant} instances. * * @see #TIMESTAMP_MILLIS_UTC * @see #timestampMillisAt(ZoneId) */ public static final PrimitiveLongCodec TIMESTAMP_MILLIS_SYSTEM = new TimestampMillisCodec(); /** * A codec that maps CQL type {@code timestamp} to Java's {@code long}, representing the number of * milliseconds since the Epoch, using the UTC time zone to parse and format CQL literals. * *

This codec uses {@link ZoneOffset#UTC} as its source of time zone information when * formatting values as CQL literals, or parsing CQL literals that do not have any time zone * indication. Note that this only applies to the {@link TypeCodec#format(Object)} and {@link * TypeCodec#parse(String)} methods; regular encoding and decoding, like setting a value on a * bound statement or reading a column from a row, are not affected by the time zone. * *

If you need a different time zone, consider other constants in this class, or call {@link * #timestampMillisAt(ZoneId)} instead. * *

This codec can serve as a replacement for the driver's built-in {@linkplain * TypeCodecs#TIMESTAMP timestamp} codec, when application code prefers to deal with raw * milliseconds than with {@link Instant} instances. * * @see #TIMESTAMP_MILLIS_SYSTEM * @see #timestampMillisAt(ZoneId) */ public static final PrimitiveLongCodec TIMESTAMP_MILLIS_UTC = new TimestampMillisCodec(ZoneOffset.UTC); /** * A codec that maps CQL type {@code timestamp} to Java's {@link ZonedDateTime}, using the * system's default time zone. * *

This codec uses the system's {@linkplain ZoneId#systemDefault() default time zone} as its * source of time zone information when encoding or decoding. If you need a different time zone, * consider using other constants in this class, or call {@link #zonedTimestampAt(ZoneId)} * instead. * *

Note that CQL type {@code timestamp} type does not store any time zone; this codec is * provided merely as a convenience for users that need to deal with zoned timestamps in their * applications. * * @see #ZONED_TIMESTAMP_UTC * @see #ZONED_TIMESTAMP_PERSISTED * @see #zonedTimestampAt(ZoneId) */ public static final TypeCodec ZONED_TIMESTAMP_SYSTEM = new ZonedTimestampCodec(); /** * A codec that maps CQL type {@code timestamp} to Java's {@link ZonedDateTime}, using the UTC * time zone. * *

This codec uses {@link ZoneOffset#UTC} as its source of time zone information when encoding * or decoding. If you need a different time zone, consider using other constants in this class, * or call {@link #zonedTimestampAt(ZoneId)} instead. * *

Note that CQL type {@code timestamp} type does not store any time zone; this codec is * provided merely as a convenience for users that need to deal with zoned timestamps in their * applications. * * @see #ZONED_TIMESTAMP_SYSTEM * @see #ZONED_TIMESTAMP_PERSISTED * @see #zonedTimestampAt(ZoneId) */ public static final TypeCodec ZONED_TIMESTAMP_UTC = new ZonedTimestampCodec(ZoneOffset.UTC); /** * A codec that maps CQL type {@code tuple} to Java's {@link ZonedDateTime}, * providing a pattern for maintaining timezone information in Cassandra. * *

Since CQL type {@code timestamp} does not store any time zone, it is persisted separately in * the {@code text} field of the tuple, and so when the value is read back the original timezone * it was written with is preserved. * * @see #ZONED_TIMESTAMP_SYSTEM * @see #ZONED_TIMESTAMP_UTC * @see #zonedTimestampAt(ZoneId) */ public static final TypeCodec ZONED_TIMESTAMP_PERSISTED = new PersistentZonedTimestampCodec(); /** * A codec that maps CQL type {@code timestamp} to Java's {@link LocalDateTime}, using the * system's default time zone. * *

This codec uses the system's {@linkplain ZoneId#systemDefault() default time zone} as its * source of time zone information when encoding or decoding. If you need a different time zone, * consider using other constants in this class, or call {@link #localTimestampAt(ZoneId)} * instead. * *

Note that CQL type {@code timestamp} does not store any time zone; this codec is provided * merely as a convenience for users that need to deal with local date-times in their * applications. * * @see #LOCAL_TIMESTAMP_UTC * @see #localTimestampAt(ZoneId) */ public static final TypeCodec LOCAL_TIMESTAMP_SYSTEM = new LocalTimestampCodec(); /** * A codec that maps CQL type {@code timestamp} to Java's {@link LocalDateTime}, using the UTC * time zone. * *

This codec uses {@link ZoneOffset#UTC} as its source of time zone information when encoding * or decoding. If you need a different time zone, consider using other constants in this class, * or call {@link #localTimestampAt(ZoneId)} instead. * *

Note that CQL type {@code timestamp} does not store any time zone; this codec is provided * merely as a convenience for users that need to deal with local date-times in their * applications. * * @see #LOCAL_TIMESTAMP_SYSTEM * @see #localTimestampAt(ZoneId) */ public static final TypeCodec LOCAL_TIMESTAMP_UTC = new LocalTimestampCodec(ZoneOffset.UTC); /** * A codec that maps CQL type {@code blob} to Java's {@code byte[]}. * *

If you are looking for a codec mapping CQL type {@code blob} to the Java type {@link * ByteBuffer}, you should use {@link TypeCodecs#BLOB} instead. * *

If you are looking for a codec mapping CQL type {@code list BLOB_TO_ARRAY = new SimpleBlobCodec(); /** * A codec that maps CQL type {@code list} to Java's {@code boolean[]}. * *

Note that this codec is designed for performance and converts CQL lists directly to * {@code boolean[]}, thus avoiding any unnecessary boxing and unboxing of Java primitive {@code * boolean} values; it also instantiates arrays without the need for an intermediary Java {@code * List} object. */ public static final TypeCodec BOOLEAN_LIST_TO_ARRAY = new BooleanListToArrayCodec(); /** * A codec that maps CQL type {@code list} to Java's {@code byte[]}. * *

This codec is not suitable for reading CQL blobs as byte arrays. If you are looking for a * codec for the CQL type {@code blob}, you should use {@link TypeCodecs#BLOB} or {@link * ExtraTypeCodecs#BLOB_TO_ARRAY} instead. * *

Note that this codec is designed for performance and converts CQL lists directly to * {@code byte[]}, thus avoiding any unnecessary boxing and unboxing of Java primitive {@code * byte} values; it also instantiates arrays without the need for an intermediary Java {@code * List} object. * * @see TypeCodecs#BLOB * @see ExtraTypeCodecs#BLOB_TO_ARRAY */ public static final TypeCodec BYTE_LIST_TO_ARRAY = new ByteListToArrayCodec(); /** * A codec that maps CQL type {@code list} to Java's {@code short[]}. * *

Note that this codec is designed for performance and converts CQL lists directly to * {@code short[]}, thus avoiding any unnecessary boxing and unboxing of Java primitive {@code * short} values; it also instantiates arrays without the need for an intermediary Java {@code * List} object. */ public static final TypeCodec SHORT_LIST_TO_ARRAY = new ShortListToArrayCodec(); /** * A codec that maps CQL type {@code list} to Java's {@code int[]}. * *

Note that this codec is designed for performance and converts CQL lists directly to * {@code int[]}, thus avoiding any unnecessary boxing and unboxing of Java primitive {@code int} * values; it also instantiates arrays without the need for an intermediary Java {@code List} * object. */ public static final TypeCodec INT_LIST_TO_ARRAY = new IntListToArrayCodec(); /** * A codec that maps CQL type {@code list} to Java's {@code long[]}. * *

Note that this codec is designed for performance and converts CQL lists directly to * {@code long[]}, thus avoiding any unnecessary boxing and unboxing of Java primitive {@code * long} values; it also instantiates arrays without the need for an intermediary Java {@code * List} object. */ public static final TypeCodec LONG_LIST_TO_ARRAY = new LongListToArrayCodec(); /** * A codec that maps CQL type {@code list} to Java's {@code float[]}. * *

Note that this codec is designed for performance and converts CQL lists directly to * {@code float[]}, thus avoiding any unnecessary boxing and unboxing of Java primitive {@code * float} values; it also instantiates arrays without the need for an intermediary Java {@code * List} object. */ public static final TypeCodec FLOAT_LIST_TO_ARRAY = new FloatListToArrayCodec(); /** * A codec that maps CQL type {@code list} to Java's {@code double[]}. * *

Note that this codec is designed for performance and converts CQL lists directly to * {@code double[]}, thus avoiding any unnecessary boxing and unboxing of Java primitive {@code * double} values; it also instantiates arrays without the need for an intermediary Java {@code * List} object. */ public static final TypeCodec DOUBLE_LIST_TO_ARRAY = new DoubleListToArrayCodec(); /** * Builds a new codec that maps CQL type {@code timestamp} to Java's {@link Instant}, using the * given time zone to parse and format CQL literals. * *

This codec uses the supplied {@link ZoneId} as its source of time zone information when * formatting values as CQL literals, or parsing CQL literals that do not have any time zone * indication. Note that this only applies to the {@link TypeCodec#format(Object)} and {@link * TypeCodec#parse(String)} methods; regular encoding and decoding, like setting a value on a * bound statement or reading a column from a row, are not affected by the time zone. * * @see TypeCodecs#TIMESTAMP * @see ExtraTypeCodecs#TIMESTAMP_UTC */ @NonNull public static TypeCodec timestampAt(@NonNull ZoneId timeZone) { return new TimestampCodec(timeZone); } /** * Builds a new codec that maps CQL type {@code timestamp} to Java's {@code long}, representing * the number of milliseconds since the Epoch, using the given time zone to parse and format CQL * literals. * *

This codec uses the supplied {@link ZoneId} as its source of time zone information when * formatting values as CQL literals, or parsing CQL literals that do not have any time zone * indication. Note that this only applies to the {@link TypeCodec#format(Object)} and {@link * TypeCodec#parse(String)} methods; regular encoding and decoding, like setting a value on a * bound statement or reading a column from a row, are not affected by the time zone. * *

This codec can serve as a replacement for the driver's built-in {@linkplain * TypeCodecs#TIMESTAMP timestamp} codec, when application code prefers to deal with raw * milliseconds than with {@link Instant} instances. * * @see ExtraTypeCodecs#TIMESTAMP_MILLIS_SYSTEM * @see ExtraTypeCodecs#TIMESTAMP_MILLIS_UTC */ @NonNull public static PrimitiveLongCodec timestampMillisAt(@NonNull ZoneId timeZone) { return new TimestampMillisCodec(timeZone); } /** * Builds a new codec that maps CQL type {@code timestamp} to Java's {@link ZonedDateTime}. * *

This codec uses the supplied {@link ZoneId} as its source of time zone information when * encoding or decoding. * *

Note that CQL type {@code timestamp} does not store any time zone; the codecs created by * this method are provided merely as a convenience for users that need to deal with zoned * timestamps in their applications. * * @see ExtraTypeCodecs#ZONED_TIMESTAMP_SYSTEM * @see ExtraTypeCodecs#ZONED_TIMESTAMP_UTC * @see ExtraTypeCodecs#ZONED_TIMESTAMP_PERSISTED */ @NonNull public static TypeCodec zonedTimestampAt(@NonNull ZoneId timeZone) { return new ZonedTimestampCodec(timeZone); } /** * Builds a new codec that maps CQL type {@code timestamp} to Java's {@link LocalDateTime}. * *

This codec uses the supplied {@link ZoneId} as its source of time zone information when * encoding or decoding. * *

Note that CQL type {@code timestamp} does not store any time zone; the codecs created by * this method are provided merely as a convenience for users that need to deal with local * date-times in their applications. * * @see ExtraTypeCodecs#LOCAL_TIMESTAMP_UTC * @see #localTimestampAt(ZoneId) */ @NonNull public static TypeCodec localTimestampAt(@NonNull ZoneId timeZone) { return new LocalTimestampCodec(timeZone); } /** * Builds a new codec that maps a CQL list to a Java array. Encoding and decoding of elements in * the array is delegated to the provided element codec. * *

This method is not suitable for Java primitive arrays. Use {@link * ExtraTypeCodecs#BOOLEAN_LIST_TO_ARRAY}, {@link ExtraTypeCodecs#BYTE_LIST_TO_ARRAY}, {@link * ExtraTypeCodecs#SHORT_LIST_TO_ARRAY}, {@link ExtraTypeCodecs#INT_LIST_TO_ARRAY}, {@link * ExtraTypeCodecs#LONG_LIST_TO_ARRAY}, {@link ExtraTypeCodecs#FLOAT_LIST_TO_ARRAY} or {@link * ExtraTypeCodecs#DOUBLE_LIST_TO_ARRAY} instead. */ @NonNull public static TypeCodec listToArrayOf(@NonNull TypeCodec elementCodec) { return new ObjectListToArrayCodec<>(elementCodec); } /** * Builds a new codec that maps CQL type {@code int} to a Java Enum, according to its constants' * {@linkplain Enum#ordinal() ordinals} (STRONGLY discouraged, see explanations below). * *

This method is provided for compatibility with driver 3, but we strongly recommend against * it. Relying on enum ordinals is a bad practice: any reordering of the enum constants, or * insertion of a new constant before the end, will change the ordinals. The codec will keep * working, but start inserting different codes and corrupting your data. * *

{@link #enumNamesOf(Class)} is a safer alternative, as it is not dependent on the constant * order. If you still want to use integer codes for storage efficiency, we recommend implementing * an explicit mapping (for example with a {@code toCode()} method on your enum type). It is then * fairly straightforward to implement a codec with {@link MappingCodec}, using {@link * TypeCodecs#INT} as the "inner" codec. */ @NonNull public static > TypeCodec enumOrdinalsOf( @NonNull Class enumClass) { return new EnumOrdinalCodec<>(enumClass); } /** * Builds a new codec that maps CQL type {@code text} to a Java Enum, according to its constants' * programmatic {@linkplain Enum#name() names}. * * @see #enumOrdinalsOf(Class) */ @NonNull public static > TypeCodec enumNamesOf( @NonNull Class enumClass) { return new EnumNameCodec<>(enumClass); } /** * Builds a new codec that wraps another codec's Java type into {@link Optional} instances * (mapping CQL null to {@link Optional#empty()}). */ @NonNull public static TypeCodec> optionalOf(@NonNull TypeCodec innerCodec) { return new OptionalCodec<>(innerCodec); } /** * Builds a new codec that maps CQL type {@code text} to the given Java type, using JSON * serialization with a default Jackson mapper. * * @see Jackson JSON Library */ @NonNull public static TypeCodec json(@NonNull GenericType javaType) { return new JsonCodec<>(javaType); } /** * Builds a new codec that maps CQL type {@code text} to the given Java type, using JSON * serialization with a default Jackson mapper. * * @see Jackson JSON Library */ @NonNull public static TypeCodec json(@NonNull Class javaType) { return new JsonCodec<>(javaType); } /** * Builds a new codec that maps CQL type {@code text} to the given Java type, using JSON * serialization with the provided Jackson mapper. * * @see Jackson JSON Library */ @NonNull public static TypeCodec json( @NonNull GenericType javaType, @NonNull ObjectMapper objectMapper) { return new JsonCodec<>(javaType, objectMapper); } /** * Builds a new codec that maps CQL type {@code text} to the given Java type, using JSON * serialization with the provided Jackson mapper. * * @see Jackson JSON Library */ @NonNull public static TypeCodec json( @NonNull Class javaType, @NonNull ObjectMapper objectMapper) { return new JsonCodec<>(javaType, objectMapper); } /** Builds a new codec that maps CQL float vectors of the specified size to an array of floats. */ public static TypeCodec floatVectorToArray(int dimensions) { return new FloatVectorToArrayCodec(new DefaultVectorType(DataTypes.FLOAT, dimensions)); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy