Skip to content

Commit af5e770

Browse files
committed
adding codecs for multiple java 8 data types - pgjdbcgh-591
1 parent 543f5cc commit af5e770

16 files changed

+1056
-143
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.r2dbc.postgresql.codec;
18+
19+
import io.netty.buffer.ByteBufAllocator;
20+
21+
import java.time.DayOfWeek;
22+
23+
final class DayOfWeekCodec extends IntegerCodecDelegate<DayOfWeek> {
24+
25+
DayOfWeekCodec(ByteBufAllocator byteBufAllocator) {
26+
super(DayOfWeek.class, byteBufAllocator, DayOfWeek::getValue, DayOfWeek::of);
27+
}
28+
}

src/main/java/io/r2dbc/postgresql/codec/DefaultCodecs.java

+119-113
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@
4444
*/
4545
public final class DefaultCodecs implements Codecs, CodecRegistry {
4646

47-
private final List<Codec<?>> codecs;
48-
4947
private final CodecLookup codecLookup;
5048

49+
private final List<Codec<?>> codecs;
50+
5151
/**
5252
* Create a new instance of {@link DefaultCodecs} preferring detached (copied buffers).
5353
*
@@ -96,97 +96,6 @@ public DefaultCodecs(ByteBufAllocator byteBufAllocator, boolean preferAttachedBu
9696
this.codecLookup.afterCodecAdded();
9797
}
9898

99-
@SuppressWarnings({"unchecked", "rawtypes"})
100-
private static List<Codec<?>> getDefaultCodecs(ByteBufAllocator byteBufAllocator, boolean preferAttachedBuffers, CodecConfiguration configuration) {
101-
102-
List<Codec<?>> codecs = new CopyOnWriteArrayList<>(Arrays.asList(
103-
104-
// Prioritized Codecs
105-
new StringCodec(byteBufAllocator),
106-
new InstantCodec(byteBufAllocator, configuration::getZoneId),
107-
new ZonedDateTimeCodec(byteBufAllocator),
108-
new BinaryByteBufferCodec(byteBufAllocator),
109-
new BinaryByteArrayCodec(byteBufAllocator),
110-
111-
new BigDecimalCodec(byteBufAllocator),
112-
new BigIntegerCodec(byteBufAllocator),
113-
new BooleanCodec(byteBufAllocator),
114-
new CharacterCodec(byteBufAllocator),
115-
new DoubleCodec(byteBufAllocator),
116-
new FloatCodec(byteBufAllocator),
117-
new InetAddressCodec(byteBufAllocator),
118-
new IntegerCodec(byteBufAllocator),
119-
new IntervalCodec(byteBufAllocator),
120-
new LocalDateCodec(byteBufAllocator),
121-
new LocalDateTimeCodec(byteBufAllocator, configuration::getZoneId),
122-
new LocalTimeCodec(byteBufAllocator),
123-
new LongCodec(byteBufAllocator),
124-
new OffsetDateTimeCodec(byteBufAllocator),
125-
new OffsetTimeCodec(byteBufAllocator),
126-
new ShortCodec(byteBufAllocator),
127-
new UriCodec(byteBufAllocator),
128-
new UrlCodec(byteBufAllocator),
129-
new UuidCodec(byteBufAllocator),
130-
new ZoneIdCodec(byteBufAllocator),
131-
132-
// JSON
133-
new JsonCodec(byteBufAllocator, preferAttachedBuffers),
134-
new JsonByteArrayCodec(byteBufAllocator),
135-
new JsonByteBufCodec(byteBufAllocator),
136-
new JsonByteBufferCodec(byteBufAllocator),
137-
new JsonInputStreamCodec(byteBufAllocator),
138-
new JsonStringCodec(byteBufAllocator),
139-
140-
// Fallback for Object.class
141-
new ByteCodec(byteBufAllocator),
142-
new DateCodec(byteBufAllocator, configuration::getZoneId),
143-
144-
new BlobCodec(byteBufAllocator),
145-
new ClobCodec(byteBufAllocator),
146-
RefCursorCodec.INSTANCE,
147-
RefCursorNameCodec.INSTANCE,
148-
149-
// Array
150-
new StringArrayCodec(byteBufAllocator),
151-
152-
// Geometry
153-
new CircleCodec(byteBufAllocator),
154-
new PointCodec(byteBufAllocator),
155-
new BoxCodec(byteBufAllocator),
156-
new LineCodec(byteBufAllocator),
157-
new LsegCodec(byteBufAllocator),
158-
new PathCodec(byteBufAllocator),
159-
new PolygonCodec(byteBufAllocator)
160-
));
161-
162-
List<Codec<?>> defaultArrayCodecs = new ArrayList<>();
163-
164-
for (Codec<?> codec : codecs) {
165-
166-
if (codec instanceof ArrayCodecDelegate<?>) {
167-
168-
Assert.requireType(codec, AbstractCodec.class, "Codec " + codec + " must be a subclass of AbstractCodec to be registered as generic array codec");
169-
ArrayCodecDelegate<?> delegate = (ArrayCodecDelegate<?>) codec;
170-
Class<?> componentType = delegate.type();
171-
172-
if (codec instanceof BoxCodec) {
173-
// BOX[] uses a ';' as a delimiter (i.e. "{(3.7,4.6),(1.9,2.8);(5,7),(1.5,3.3)}")
174-
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate.getArrayDataType(), delegate, componentType, (byte) ';'));
175-
} else if (codec instanceof AbstractNumericCodec) {
176-
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.NUMERIC_ARRAY_TYPES));
177-
} else if (codec instanceof AbstractTemporalCodec) {
178-
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.DATE_ARRAY_TYPES));
179-
} else {
180-
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate, componentType));
181-
}
182-
}
183-
}
184-
185-
codecs.addAll(defaultArrayCodecs);
186-
187-
return codecs;
188-
}
189-
19099
@Override
191100
public void addFirst(Codec<?> codec) {
192101
Assert.requireNonNull(codec, "codec must not be null");
@@ -264,6 +173,35 @@ public EncodedParameter encode(Object value) {
264173
return encodeParameterValue(value, dataType, parameterValue);
265174
}
266175

176+
@Override
177+
public EncodedParameter encodeNull(Class<?> type) {
178+
Assert.requireNonNull(type, "type must not be null");
179+
180+
Codec<?> codec = this.codecLookup.findEncodeNullCodec(type);
181+
if (codec != null) {
182+
return codec.encodeNull();
183+
}
184+
185+
throw new IllegalArgumentException(String.format("Cannot encode null parameter of type %s", type.getName()));
186+
}
187+
188+
@Override
189+
public Iterator<Codec<?>> iterator() {
190+
return Collections.unmodifiableList(new ArrayList<>(this.codecs)).iterator();
191+
}
192+
193+
@Override
194+
public Class<?> preferredType(int dataType, Format format) {
195+
Assert.requireNonNull(format, "format must not be null");
196+
197+
Codec<?> codec = this.codecLookup.findDecodeCodec(dataType, format, Object.class);
198+
if (codec instanceof CodecMetadata) {
199+
return ((CodecMetadata) codec).type();
200+
}
201+
202+
return null;
203+
}
204+
267205
EncodedParameter encodeParameterValue(Object value, @Nullable PostgresTypeIdentifier dataType, @Nullable Object parameterValue) {
268206
if (dataType == null) {
269207

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

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

297-
Codec<?> codec = this.codecLookup.findEncodeNullCodec(type);
298-
if (codec != null) {
299-
return codec.encodeNull();
300-
}
234+
List<Codec<?>> codecs = new CopyOnWriteArrayList<>(Arrays.asList(
301235

302-
throw new IllegalArgumentException(String.format("Cannot encode null parameter of type %s", type.getName()));
303-
}
236+
// Prioritized Codecs
237+
new StringCodec(byteBufAllocator),
238+
new InstantCodec(byteBufAllocator, configuration::getZoneId),
239+
new ZonedDateTimeCodec(byteBufAllocator),
240+
new BinaryByteBufferCodec(byteBufAllocator),
241+
new BinaryByteArrayCodec(byteBufAllocator),
304242

305-
@Override
306-
public Class<?> preferredType(int dataType, Format format) {
307-
Assert.requireNonNull(format, "format must not be null");
243+
new BigDecimalCodec(byteBufAllocator),
244+
new BigIntegerCodec(byteBufAllocator),
245+
new BooleanCodec(byteBufAllocator),
246+
new CharacterCodec(byteBufAllocator),
247+
new DoubleCodec(byteBufAllocator),
248+
new FloatCodec(byteBufAllocator),
249+
new InetAddressCodec(byteBufAllocator),
250+
new IntegerCodec(byteBufAllocator),
251+
new IntervalCodec(byteBufAllocator),
252+
new LocalDateCodec(byteBufAllocator),
253+
new LocalDateTimeCodec(byteBufAllocator, configuration::getZoneId),
254+
new LocalTimeCodec(byteBufAllocator),
255+
new LongCodec(byteBufAllocator),
256+
new OffsetDateTimeCodec(byteBufAllocator),
257+
new OffsetTimeCodec(byteBufAllocator),
258+
new ShortCodec(byteBufAllocator),
259+
new UriCodec(byteBufAllocator),
260+
new UrlCodec(byteBufAllocator),
261+
new UuidCodec(byteBufAllocator),
262+
new ZoneIdCodec(byteBufAllocator),
263+
new DayOfWeekCodec(byteBufAllocator),
264+
new MonthCodec(byteBufAllocator),
265+
new MonthDayCodec(byteBufAllocator),
266+
new PeriodCodec(byteBufAllocator),
267+
new YearCodec(byteBufAllocator),
268+
new YearMonthCodec(byteBufAllocator),
308269

309-
Codec<?> codec = this.codecLookup.findDecodeCodec(dataType, format, Object.class);
310-
if (codec instanceof CodecMetadata) {
311-
return ((CodecMetadata) codec).type();
270+
// JSON
271+
new JsonCodec(byteBufAllocator, preferAttachedBuffers),
272+
new JsonByteArrayCodec(byteBufAllocator),
273+
new JsonByteBufCodec(byteBufAllocator),
274+
new JsonByteBufferCodec(byteBufAllocator),
275+
new JsonInputStreamCodec(byteBufAllocator),
276+
new JsonStringCodec(byteBufAllocator),
277+
278+
// Fallback for Object.class
279+
new ByteCodec(byteBufAllocator),
280+
new DateCodec(byteBufAllocator, configuration::getZoneId),
281+
282+
new BlobCodec(byteBufAllocator),
283+
new ClobCodec(byteBufAllocator),
284+
RefCursorCodec.INSTANCE,
285+
RefCursorNameCodec.INSTANCE,
286+
287+
// Array
288+
new StringArrayCodec(byteBufAllocator),
289+
290+
// Geometry
291+
new CircleCodec(byteBufAllocator),
292+
new PointCodec(byteBufAllocator),
293+
new BoxCodec(byteBufAllocator),
294+
new LineCodec(byteBufAllocator),
295+
new LsegCodec(byteBufAllocator),
296+
new PathCodec(byteBufAllocator),
297+
new PolygonCodec(byteBufAllocator)
298+
));
299+
300+
List<Codec<?>> defaultArrayCodecs = new ArrayList<>();
301+
302+
for (Codec<?> codec : codecs) {
303+
304+
if (codec instanceof ArrayCodecDelegate<?>) {
305+
306+
Assert.requireType(codec, AbstractCodec.class, "Codec " + codec + " must be a subclass of AbstractCodec to be registered as generic array codec");
307+
ArrayCodecDelegate<?> delegate = (ArrayCodecDelegate<?>) codec;
308+
Class<?> componentType = delegate.type();
309+
310+
if (codec instanceof BoxCodec) {
311+
// BOX[] uses a ';' as a delimiter (i.e. "{(3.7,4.6),(1.9,2.8);(5,7),(1.5,3.3)}")
312+
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate.getArrayDataType(), delegate, componentType, (byte) ';'));
313+
} else if (codec instanceof AbstractNumericCodec) {
314+
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.NUMERIC_ARRAY_TYPES));
315+
} else if (codec instanceof AbstractTemporalCodec) {
316+
defaultArrayCodecs.add(new ConvertingArrayCodec(byteBufAllocator, delegate, componentType, ConvertingArrayCodec.DATE_ARRAY_TYPES));
317+
} else {
318+
defaultArrayCodecs.add(new ArrayCodec(byteBufAllocator, delegate, componentType));
319+
}
320+
}
312321
}
313322

314-
return null;
315-
}
323+
codecs.addAll(defaultArrayCodecs);
316324

317-
@Override
318-
public Iterator<Codec<?>> iterator() {
319-
return Collections.unmodifiableList(new ArrayList<>(this.codecs)).iterator();
325+
return codecs;
320326
}
321327

322328
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Copyright 2017 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.r2dbc.postgresql.codec;
18+
19+
import io.netty.buffer.ByteBuf;
20+
import io.netty.buffer.ByteBufAllocator;
21+
import io.r2dbc.postgresql.client.EncodedParameter;
22+
import io.r2dbc.postgresql.message.Format;
23+
import io.r2dbc.postgresql.util.Assert;
24+
25+
import java.util.function.Function;
26+
27+
class IntegerCodecDelegate<T> extends AbstractCodec<T> {
28+
29+
private final IntegerCodec delegate;
30+
private final Function<T, Integer> toIntegerConverter;
31+
private final Function<Integer, T> fromIntegerConverter;
32+
33+
IntegerCodecDelegate(Class<T> type, ByteBufAllocator byteBufAllocator, Function<T,Integer> toIntegerConverter, Function<Integer, T> fromIntegerConverter) {
34+
super(type);
35+
this.delegate = new IntegerCodec(byteBufAllocator);
36+
this.toIntegerConverter = toIntegerConverter;
37+
this.fromIntegerConverter = fromIntegerConverter;
38+
}
39+
40+
@Override
41+
boolean doCanDecode(PostgresqlObjectId type, Format format) {
42+
return delegate.doCanDecode(type, format);
43+
}
44+
45+
@Override
46+
T doDecode(ByteBuf buffer, PostgresTypeIdentifier dataType, Format format, Class<? extends T> type) {
47+
final Integer number = delegate.doDecode(buffer, dataType, format, Integer.TYPE);
48+
return fromIntegerConverter.apply(number);
49+
}
50+
51+
@Override
52+
EncodedParameter doEncode(T value) {
53+
Assert.requireNonNull(value, "value must not be null");
54+
return delegate.doEncode(toIntegerConverter.apply(value));
55+
}
56+
57+
@Override
58+
EncodedParameter doEncode(T value, PostgresTypeIdentifier dataType) {
59+
Assert.requireNonNull(value, "value must not be null");
60+
Assert.requireNonNull(dataType, "dataType must not be null");
61+
return delegate.doEncode(toIntegerConverter.apply(value), dataType);
62+
}
63+
64+
@Override
65+
public Iterable<? extends PostgresTypeIdentifier> getDataTypes() {
66+
return delegate.getDataTypes();
67+
}
68+
69+
@Override
70+
public EncodedParameter encodeNull() {
71+
return delegate.encodeNull();
72+
}
73+
}

0 commit comments

Comments
 (0)