Skip to content

Commit

Permalink
adding support for Year data type - pgjdbcgh-591
Browse files Browse the repository at this point in the history
  • Loading branch information
steverigney committed Aug 13, 2023
1 parent 543f5cc commit 626efb9
Show file tree
Hide file tree
Showing 3 changed files with 254 additions and 113 deletions.
227 changes: 114 additions & 113 deletions src/main/java/io/r2dbc/postgresql/codec/DefaultCodecs.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@
*/
public final class DefaultCodecs implements Codecs, CodecRegistry {

private final List<Codec<?>> codecs;

private final CodecLookup codecLookup;

private final List<Codec<?>> codecs;

/**
* Create a new instance of {@link DefaultCodecs} preferring detached (copied buffers).
*
Expand Down Expand Up @@ -96,97 +96,6 @@ public DefaultCodecs(ByteBufAllocator byteBufAllocator, boolean preferAttachedBu
this.codecLookup.afterCodecAdded();
}

@SuppressWarnings({"unchecked", "rawtypes"})
private static List<Codec<?>> getDefaultCodecs(ByteBufAllocator byteBufAllocator, boolean preferAttachedBuffers, CodecConfiguration configuration) {

List<Codec<?>> codecs = new CopyOnWriteArrayList<>(Arrays.asList(

// Prioritized Codecs
new StringCodec(byteBufAllocator),
new InstantCodec(byteBufAllocator, configuration::getZoneId),
new ZonedDateTimeCodec(byteBufAllocator),
new BinaryByteBufferCodec(byteBufAllocator),
new BinaryByteArrayCodec(byteBufAllocator),

new BigDecimalCodec(byteBufAllocator),
new BigIntegerCodec(byteBufAllocator),
new BooleanCodec(byteBufAllocator),
new CharacterCodec(byteBufAllocator),
new DoubleCodec(byteBufAllocator),
new FloatCodec(byteBufAllocator),
new InetAddressCodec(byteBufAllocator),
new IntegerCodec(byteBufAllocator),
new IntervalCodec(byteBufAllocator),
new LocalDateCodec(byteBufAllocator),
new LocalDateTimeCodec(byteBufAllocator, configuration::getZoneId),
new LocalTimeCodec(byteBufAllocator),
new LongCodec(byteBufAllocator),
new OffsetDateTimeCodec(byteBufAllocator),
new OffsetTimeCodec(byteBufAllocator),
new ShortCodec(byteBufAllocator),
new UriCodec(byteBufAllocator),
new UrlCodec(byteBufAllocator),
new UuidCodec(byteBufAllocator),
new ZoneIdCodec(byteBufAllocator),

// JSON
new JsonCodec(byteBufAllocator, preferAttachedBuffers),
new JsonByteArrayCodec(byteBufAllocator),
new JsonByteBufCodec(byteBufAllocator),
new JsonByteBufferCodec(byteBufAllocator),
new JsonInputStreamCodec(byteBufAllocator),
new JsonStringCodec(byteBufAllocator),

// Fallback for Object.class
new ByteCodec(byteBufAllocator),
new DateCodec(byteBufAllocator, configuration::getZoneId),

new BlobCodec(byteBufAllocator),
new ClobCodec(byteBufAllocator),
RefCursorCodec.INSTANCE,
RefCursorNameCodec.INSTANCE,

// Array
new StringArrayCodec(byteBufAllocator),

// Geometry
new CircleCodec(byteBufAllocator),
new PointCodec(byteBufAllocator),
new BoxCodec(byteBufAllocator),
new LineCodec(byteBufAllocator),
new LsegCodec(byteBufAllocator),
new PathCodec(byteBufAllocator),
new PolygonCodec(byteBufAllocator)
));

List<Codec<?>> defaultArrayCodecs = new ArrayList<>();

for (Codec<?> codec : codecs) {

if (codec instanceof ArrayCodecDelegate<?>) {

Assert.requireType(codec, AbstractCodec.class, "Codec " + codec + " must be a subclass of AbstractCodec to be registered as generic array codec");
ArrayCodecDelegate<?> delegate = (ArrayCodecDelegate<?>) codec;
Class<?> componentType = delegate.type();

if (codec instanceof BoxCodec) {
// BOX[] uses a ';' as a delimiter (i.e. "{(3.7,4.6),(1.9,2.8);(5,7),(1.5,3.3)}")
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate.getArrayDataType(), delegate, componentType, (byte) ';'));
} else if (codec instanceof AbstractNumericCodec) {
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.NUMERIC_ARRAY_TYPES));
} else if (codec instanceof AbstractTemporalCodec) {
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.DATE_ARRAY_TYPES));
} else {
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate, componentType));
}
}
}

codecs.addAll(defaultArrayCodecs);

return codecs;
}

@Override
public void addFirst(Codec<?> codec) {
Assert.requireNonNull(codec, "codec must not be null");
Expand Down Expand Up @@ -264,6 +173,35 @@ public EncodedParameter encode(Object value) {
return encodeParameterValue(value, dataType, parameterValue);
}

@Override
public EncodedParameter encodeNull(Class<?> type) {
Assert.requireNonNull(type, "type must not be null");

Codec<?> codec = this.codecLookup.findEncodeNullCodec(type);
if (codec != null) {
return codec.encodeNull();
}

throw new IllegalArgumentException(String.format("Cannot encode null parameter of type %s", type.getName()));
}

@Override
public Iterator<Codec<?>> iterator() {
return Collections.unmodifiableList(new ArrayList<>(this.codecs)).iterator();
}

@Override
public Class<?> preferredType(int dataType, Format format) {
Assert.requireNonNull(format, "format must not be null");

Codec<?> codec = this.codecLookup.findDecodeCodec(dataType, format, Object.class);
if (codec instanceof CodecMetadata) {
return ((CodecMetadata) codec).type();
}

return null;
}

EncodedParameter encodeParameterValue(Object value, @Nullable PostgresTypeIdentifier dataType, @Nullable Object parameterValue) {
if (dataType == null) {

Expand All @@ -290,33 +228,96 @@ EncodedParameter encodeParameterValue(Object value, @Nullable PostgresTypeIdenti
throw new IllegalArgumentException(String.format("Cannot encode parameter of type %s (%s)", value.getClass().getName(), parameterValue));
}

@Override
public EncodedParameter encodeNull(Class<?> type) {
Assert.requireNonNull(type, "type must not be null");
@SuppressWarnings({"unchecked", "rawtypes"})
private static List<Codec<?>> getDefaultCodecs(ByteBufAllocator byteBufAllocator, boolean preferAttachedBuffers, CodecConfiguration configuration) {

Codec<?> codec = this.codecLookup.findEncodeNullCodec(type);
if (codec != null) {
return codec.encodeNull();
}
List<Codec<?>> codecs = new CopyOnWriteArrayList<>(Arrays.asList(

throw new IllegalArgumentException(String.format("Cannot encode null parameter of type %s", type.getName()));
}
// Prioritized Codecs
new StringCodec(byteBufAllocator),
new InstantCodec(byteBufAllocator, configuration::getZoneId),
new ZonedDateTimeCodec(byteBufAllocator),
new BinaryByteBufferCodec(byteBufAllocator),
new BinaryByteArrayCodec(byteBufAllocator),

@Override
public Class<?> preferredType(int dataType, Format format) {
Assert.requireNonNull(format, "format must not be null");
new BigDecimalCodec(byteBufAllocator),
new BigIntegerCodec(byteBufAllocator),
new BooleanCodec(byteBufAllocator),
new CharacterCodec(byteBufAllocator),
new DoubleCodec(byteBufAllocator),
new FloatCodec(byteBufAllocator),
new InetAddressCodec(byteBufAllocator),
new IntegerCodec(byteBufAllocator),
new IntervalCodec(byteBufAllocator),
new LocalDateCodec(byteBufAllocator),
new LocalDateTimeCodec(byteBufAllocator, configuration::getZoneId),
new LocalTimeCodec(byteBufAllocator),
new LongCodec(byteBufAllocator),
new OffsetDateTimeCodec(byteBufAllocator),
new OffsetTimeCodec(byteBufAllocator),
new ShortCodec(byteBufAllocator),
new UriCodec(byteBufAllocator),
new UrlCodec(byteBufAllocator),
new UuidCodec(byteBufAllocator),
new ZoneIdCodec(byteBufAllocator),
new YearCodec(byteBufAllocator),

Codec<?> codec = this.codecLookup.findDecodeCodec(dataType, format, Object.class);
if (codec instanceof CodecMetadata) {
return ((CodecMetadata) codec).type();
// JSON
new JsonCodec(byteBufAllocator, preferAttachedBuffers),
new JsonByteArrayCodec(byteBufAllocator),
new JsonByteBufCodec(byteBufAllocator),
new JsonByteBufferCodec(byteBufAllocator),
new JsonInputStreamCodec(byteBufAllocator),
new JsonStringCodec(byteBufAllocator),

// Fallback for Object.class
new ByteCodec(byteBufAllocator),
new DateCodec(byteBufAllocator, configuration::getZoneId),

new BlobCodec(byteBufAllocator),
new ClobCodec(byteBufAllocator),
RefCursorCodec.INSTANCE,
RefCursorNameCodec.INSTANCE,

// Array
new StringArrayCodec(byteBufAllocator),

// Geometry
new CircleCodec(byteBufAllocator),
new PointCodec(byteBufAllocator),
new BoxCodec(byteBufAllocator),
new LineCodec(byteBufAllocator),
new LsegCodec(byteBufAllocator),
new PathCodec(byteBufAllocator),
new PolygonCodec(byteBufAllocator)
));

List<Codec<?>> defaultArrayCodecs = new ArrayList<>();

for (Codec<?> codec : codecs) {

if (codec instanceof ArrayCodecDelegate<?>) {

Assert.requireType(codec, AbstractCodec.class, "Codec " + codec + " must be a subclass of AbstractCodec to be registered as generic array codec");
ArrayCodecDelegate<?> delegate = (ArrayCodecDelegate<?>) codec;
Class<?> componentType = delegate.type();

if (codec instanceof BoxCodec) {
// BOX[] uses a ';' as a delimiter (i.e. "{(3.7,4.6),(1.9,2.8);(5,7),(1.5,3.3)}")
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate.getArrayDataType(), delegate, componentType, (byte) ';'));
} else if (codec instanceof AbstractNumericCodec) {
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.NUMERIC_ARRAY_TYPES));
} else if (codec instanceof AbstractTemporalCodec) {
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.DATE_ARRAY_TYPES));
} else {
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate, componentType));
}
}
}

return null;
}
codecs.addAll(defaultArrayCodecs);

@Override
public Iterator<Codec<?>> iterator() {
return Collections.unmodifiableList(new ArrayList<>(this.codecs)).iterator();
return codecs;
}

}
28 changes: 28 additions & 0 deletions src/main/java/io/r2dbc/postgresql/codec/YearCodec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2017 the original author or authors.
*
* Licensed 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
*
* https://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 io.r2dbc.postgresql.codec;

import io.netty.buffer.ByteBufAllocator;

import java.time.Year;

final class YearCodec extends IntegerCodecDelegate<Year> {

YearCodec(ByteBufAllocator byteBufAllocator) {
super(Year.class, byteBufAllocator, Year::getValue, Year::of);
}
}
Loading

0 comments on commit 626efb9

Please sign in to comment.