Skip to content

Commit 3695222

Browse files
committed
#41 - Polishing.
Rename RowDataConverter to R2dbcConverters. Introduce R2dbcSimpleTypeHolder. Apply custom conversions check in MappingR2dbcConverter. Extend tests. Original pull request: #65.
1 parent 455e9a5 commit 3695222

13 files changed

+529
-350
lines changed

src/main/java/org/springframework/data/r2dbc/config/AbstractR2dbcConfiguration.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import io.r2dbc.spi.ConnectionFactory;
1919

20-
import java.util.Collections;
2120
import java.util.Optional;
2221

2322
import org.springframework.context.annotation.Bean;
@@ -153,7 +152,7 @@ public R2dbcCustomConversions r2dbcCustomConversions() {
153152

154153
Dialect dialect = getDialect(connectionFactory());
155154
StoreConversions storeConversions = StoreConversions.of(dialect.getSimpleTypeHolder());
156-
return new R2dbcCustomConversions(storeConversions, Collections.emptyList());
155+
return new R2dbcCustomConversions(storeConversions, R2dbcCustomConversions.STORE_CONVERTERS);
157156
}
158157

159158
/**

src/main/java/org/springframework/data/r2dbc/dialect/Dialect.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import java.util.Collection;
44
import java.util.Collections;
55
import java.util.HashSet;
6+
import java.util.Set;
67

78
import org.springframework.data.mapping.model.SimpleTypeHolder;
89
import org.springframework.data.r2dbc.dialect.ArrayColumns.Unsupported;
@@ -40,7 +41,11 @@ default Collection<? extends Class<?>> getSimpleTypes() {
4041
* @see #getSimpleTypes()
4142
*/
4243
default SimpleTypeHolder getSimpleTypeHolder() {
43-
return new SimpleTypeHolder(new HashSet<>(getSimpleTypes()), true);
44+
45+
Set<Class<?>> simpleTypes = new HashSet<>(getSimpleTypes());
46+
simpleTypes.addAll(R2dbcSimpleTypeHolder.R2DBC_SIMPLE_TYPES);
47+
48+
return new SimpleTypeHolder(simpleTypes, true);
4449
}
4550

4651
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2019 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+
* http://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+
package org.springframework.data.r2dbc.dialect;
17+
18+
import io.r2dbc.spi.Row;
19+
20+
import java.util.Collections;
21+
import java.util.Set;
22+
23+
import org.springframework.data.mapping.model.SimpleTypeHolder;
24+
25+
/**
26+
* Simple constant holder for a {@link SimpleTypeHolder} enriched with R2DBC specific simple types.
27+
*
28+
* @author Mark Paluch
29+
*/
30+
public class R2dbcSimpleTypeHolder extends SimpleTypeHolder {
31+
32+
/**
33+
* Set of R2DBC simple types.
34+
*/
35+
public static final Set<Class<?>> R2DBC_SIMPLE_TYPES = Collections.singleton(Row.class);
36+
37+
public static final SimpleTypeHolder HOLDER = new R2dbcSimpleTypeHolder();
38+
39+
/**
40+
* Create a new {@link R2dbcSimpleTypeHolder} instance.
41+
*/
42+
private R2dbcSimpleTypeHolder() {
43+
super(R2DBC_SIMPLE_TYPES, true);
44+
}
45+
46+
}

src/main/java/org/springframework/data/r2dbc/function/convert/MappingR2dbcConverter.java

+15-1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.springframework.data.relational.core.conversion.RelationalConverter;
4343
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
4444
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
45+
import org.springframework.data.util.ClassTypeInformation;
4546
import org.springframework.data.util.TypeInformation;
4647
import org.springframework.lang.Nullable;
4748
import org.springframework.util.Assert;
@@ -61,7 +62,7 @@ public class MappingR2dbcConverter extends BasicRelationalConverter implements R
6162
*/
6263
public MappingR2dbcConverter(
6364
MappingContext<? extends RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> context) {
64-
super(context, new R2dbcCustomConversions(CustomConversions.StoreConversions.NONE, Collections.emptyList()));
65+
super(context, new R2dbcCustomConversions(Collections.emptyList()));
6566
}
6667

6768
/**
@@ -81,6 +82,19 @@ public MappingR2dbcConverter(
8182

8283
@Override
8384
public <R> R read(Class<R> type, Row row) {
85+
86+
TypeInformation<? extends R> typeInfo = ClassTypeInformation.from(type);
87+
Class<? extends R> rawType = typeInfo.getType();
88+
89+
if (Row.class.isAssignableFrom(rawType)) {
90+
return type.cast(row);
91+
}
92+
93+
if (getConversions().hasCustomReadTarget(Row.class, rawType)
94+
|| getConversionService().canConvert(Row.class, rawType)) {
95+
return getConversionService().convert(row, rawType);
96+
}
97+
8498
return read(getRequiredPersistentEntity(type), row);
8599
}
86100

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
/*
2+
* Copyright 2019 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+
* http://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 org.springframework.data.r2dbc.function.convert;
18+
19+
import io.r2dbc.spi.Row;
20+
21+
import java.time.LocalDate;
22+
import java.time.LocalDateTime;
23+
import java.time.LocalTime;
24+
import java.time.OffsetDateTime;
25+
import java.time.ZonedDateTime;
26+
import java.util.ArrayList;
27+
import java.util.Collection;
28+
import java.util.List;
29+
import java.util.UUID;
30+
31+
import org.springframework.core.convert.converter.Converter;
32+
import org.springframework.core.convert.converter.ConverterFactory;
33+
import org.springframework.data.r2dbc.function.convert.R2dbcConverters.RowToNumberConverterFactory.RowToOffsetDateTimeConverter;
34+
import org.springframework.data.r2dbc.function.convert.R2dbcConverters.RowToNumberConverterFactory.RowToStringConverter;
35+
import org.springframework.data.r2dbc.function.convert.R2dbcConverters.RowToNumberConverterFactory.RowToUuidConverter;
36+
import org.springframework.data.r2dbc.function.convert.R2dbcConverters.RowToNumberConverterFactory.RowToZonedDateTimeConverter;
37+
import org.springframework.util.Assert;
38+
import org.springframework.util.NumberUtils;
39+
40+
/**
41+
* Wrapper class to contain useful converters for the usage with R2DBC.
42+
*
43+
* @author Hebert Coelho
44+
* @author Mark Paluch
45+
*/
46+
abstract class R2dbcConverters {
47+
48+
private R2dbcConverters() {}
49+
50+
/**
51+
* @return A list of the registered converters
52+
*/
53+
public static Collection<Object> getConvertersToRegister() {
54+
55+
List<Object> converters = new ArrayList<>();
56+
57+
converters.add(RowToBooleanConverter.INSTANCE);
58+
converters.add(RowToNumberConverterFactory.INSTANCE);
59+
converters.add(RowToLocalDateConverter.INSTANCE);
60+
converters.add(RowToLocalDateTimeConverter.INSTANCE);
61+
converters.add(RowToLocalTimeConverter.INSTANCE);
62+
converters.add(RowToOffsetDateTimeConverter.INSTANCE);
63+
converters.add(RowToStringConverter.INSTANCE);
64+
converters.add(RowToUuidConverter.INSTANCE);
65+
converters.add(RowToZonedDateTimeConverter.INSTANCE);
66+
67+
return converters;
68+
}
69+
70+
/**
71+
* Simple singleton to convert {@link Row}s to their {@link Boolean} representation.
72+
*
73+
* @author Hebert Coelho
74+
*/
75+
public enum RowToBooleanConverter implements Converter<Row, Boolean> {
76+
77+
INSTANCE;
78+
79+
@Override
80+
public Boolean convert(Row row) {
81+
return row.get(0, Boolean.class);
82+
}
83+
}
84+
85+
/**
86+
* Simple singleton to convert {@link Row}s to their {@link LocalDate} representation.
87+
*
88+
* @author Hebert Coelho
89+
*/
90+
public enum RowToLocalDateConverter implements Converter<Row, LocalDate> {
91+
92+
INSTANCE;
93+
94+
@Override
95+
public LocalDate convert(Row row) {
96+
return row.get(0, LocalDate.class);
97+
}
98+
}
99+
100+
/**
101+
* Simple singleton to convert {@link Row}s to their {@link LocalDateTime} representation.
102+
*
103+
* @author Hebert Coelho
104+
*/
105+
public enum RowToLocalDateTimeConverter implements Converter<Row, LocalDateTime> {
106+
107+
INSTANCE;
108+
109+
@Override
110+
public LocalDateTime convert(Row row) {
111+
return row.get(0, LocalDateTime.class);
112+
}
113+
}
114+
115+
/**
116+
* Simple singleton to convert {@link Row}s to their {@link LocalTime} representation.
117+
*
118+
* @author Hebert Coelho
119+
*/
120+
public enum RowToLocalTimeConverter implements Converter<Row, LocalTime> {
121+
122+
INSTANCE;
123+
124+
@Override
125+
public LocalTime convert(Row row) {
126+
return row.get(0, LocalTime.class);
127+
}
128+
}
129+
130+
/**
131+
* Singleton converter factory to convert the first column of a {@link Row} to a {@link Number}.
132+
* <p>
133+
* Support Number classes including Byte, Short, Integer, Float, Double, Long, BigInteger, BigDecimal. This class
134+
* delegates to {@link NumberUtils#convertNumberToTargetClass(Number, Class)} to perform the conversion.
135+
*
136+
* @see Byte
137+
* @see Short
138+
* @see Integer
139+
* @see Long
140+
* @see java.math.BigInteger
141+
* @see Float
142+
* @see Double
143+
* @see java.math.BigDecimal
144+
* @author Hebert Coelho
145+
*/
146+
public enum RowToNumberConverterFactory implements ConverterFactory<Row, Number> {
147+
148+
INSTANCE;
149+
150+
@Override
151+
public <T extends Number> Converter<Row, T> getConverter(Class<T> targetType) {
152+
Assert.notNull(targetType, "Target type must not be null");
153+
return new RowToNumber<>(targetType);
154+
}
155+
156+
static class RowToNumber<T extends Number> implements Converter<Row, T> {
157+
158+
private final Class<T> targetType;
159+
160+
RowToNumber(Class<T> targetType) {
161+
this.targetType = targetType;
162+
}
163+
164+
@Override
165+
public T convert(Row source) {
166+
167+
Object object = source.get(0, targetType);
168+
169+
return (object != null ? NumberUtils.convertNumberToTargetClass((Number) object, this.targetType) : null);
170+
}
171+
}
172+
173+
/**
174+
* Simple singleton to convert {@link Row}s to their {@link OffsetDateTime} representation.
175+
*
176+
* @author Hebert Coelho
177+
*/
178+
public enum RowToOffsetDateTimeConverter implements Converter<Row, OffsetDateTime> {
179+
180+
INSTANCE;
181+
182+
@Override
183+
public OffsetDateTime convert(Row row) {
184+
return row.get(0, OffsetDateTime.class);
185+
}
186+
}
187+
188+
/**
189+
* Simple singleton to convert {@link Row}s to their {@link String} representation.
190+
*
191+
* @author Hebert Coelho
192+
*/
193+
public enum RowToStringConverter implements Converter<Row, String> {
194+
195+
INSTANCE;
196+
197+
@Override
198+
public String convert(Row row) {
199+
return row.get(0, String.class);
200+
}
201+
}
202+
203+
/**
204+
* Simple singleton to convert {@link Row}s to their {@link UUID} representation.
205+
*
206+
* @author Hebert Coelho
207+
*/
208+
public enum RowToUuidConverter implements Converter<Row, UUID> {
209+
210+
INSTANCE;
211+
212+
@Override
213+
public UUID convert(Row row) {
214+
return row.get(0, UUID.class);
215+
}
216+
}
217+
218+
/**
219+
* Simple singleton to convert {@link Row}s to their {@link ZonedDateTime} representation.
220+
*
221+
* @author Hebert Coelho
222+
*/
223+
public enum RowToZonedDateTimeConverter implements Converter<Row, ZonedDateTime> {
224+
225+
INSTANCE;
226+
227+
@Override
228+
public ZonedDateTime convert(Row row) {
229+
return row.get(0, ZonedDateTime.class);
230+
}
231+
}
232+
}
233+
}

0 commit comments

Comments
 (0)