Skip to content

Commit 32f1770

Browse files
mp911deschauder
authored andcommitted
#55 - Reuse Dialect support provided by Spring Data Relational.
We now reuse the existing Dialect infrastructure provided by Spring Data Relational to enhance it for R2DBC specifics such as bind markers. Original pull request: #125.
1 parent 4608214 commit 32f1770

19 files changed

+81
-440
lines changed

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

+10-10
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import org.springframework.data.r2dbc.core.DefaultReactiveDataAccessStrategy;
3535
import org.springframework.data.r2dbc.core.ReactiveDataAccessStrategy;
3636
import org.springframework.data.r2dbc.dialect.Database;
37-
import org.springframework.data.r2dbc.dialect.Dialect;
37+
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
3838
import org.springframework.data.r2dbc.support.R2dbcExceptionSubclassTranslator;
3939
import org.springframework.data.r2dbc.support.R2dbcExceptionTranslator;
4040
import org.springframework.data.r2dbc.support.SqlStateR2dbcExceptionTranslator;
@@ -78,15 +78,15 @@ public void setApplicationContext(ApplicationContext applicationContext) throws
7878
public abstract ConnectionFactory connectionFactory();
7979

8080
/**
81-
* Return a {@link Dialect} for the given {@link ConnectionFactory}. This method attempts to resolve a {@link Dialect}
82-
* from {@link io.r2dbc.spi.ConnectionFactoryMetadata}. Override this method to specify a dialect instead of
83-
* attempting to resolve one.
81+
* Return a {@link R2dbcDialect} for the given {@link ConnectionFactory}. This method attempts to resolve a
82+
* {@link R2dbcDialect} from {@link io.r2dbc.spi.ConnectionFactoryMetadata}. Override this method to specify a dialect
83+
* instead of attempting to resolve one.
8484
*
8585
* @param connectionFactory the configured {@link ConnectionFactory}.
86-
* @return the resolved {@link Dialect}.
87-
* @throws UnsupportedOperationException if the {@link Dialect} cannot be determined.
86+
* @return the resolved {@link R2dbcDialect}.
87+
* @throws UnsupportedOperationException if the {@link R2dbcDialect} cannot be determined.
8888
*/
89-
public Dialect getDialect(ConnectionFactory connectionFactory) {
89+
public R2dbcDialect getDialect(ConnectionFactory connectionFactory) {
9090

9191
return Database.findDatabase(connectionFactory)
9292
.orElseThrow(() -> new UnsupportedOperationException(
@@ -172,13 +172,13 @@ public R2dbcCustomConversions r2dbcCustomConversions() {
172172
}
173173

174174
/**
175-
* Returns the {@link Dialect}-specific {@link StoreConversions}.
175+
* Returns the {@link R2dbcDialect}-specific {@link StoreConversions}.
176176
*
177-
* @return the {@link Dialect}-specific {@link StoreConversions}.
177+
* @return the {@link R2dbcDialect}-specific {@link StoreConversions}.
178178
*/
179179
protected StoreConversions getStoreConversions() {
180180

181-
Dialect dialect = getDialect(lookupConnectionFactory());
181+
R2dbcDialect dialect = getDialect(lookupConnectionFactory());
182182
return StoreConversions.of(dialect.getSimpleTypeHolder(), R2dbcCustomConversions.STORE_CONVERTERS);
183183
}
184184

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,11 @@
3838
import org.springframework.data.mapping.context.MappingContext;
3939
import org.springframework.data.mapping.model.ConvertingPropertyAccessor;
4040
import org.springframework.data.mapping.model.ParameterValueProvider;
41-
import org.springframework.data.r2dbc.dialect.ArrayColumns;
4241
import org.springframework.data.r2dbc.mapping.OutboundRow;
4342
import org.springframework.data.r2dbc.mapping.SettableValue;
4443
import org.springframework.data.relational.core.conversion.BasicRelationalConverter;
4544
import org.springframework.data.relational.core.conversion.RelationalConverter;
45+
import org.springframework.data.relational.core.dialect.ArrayColumns;
4646
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
4747
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
4848
import org.springframework.data.util.ClassTypeInformation;
@@ -84,7 +84,7 @@ public MappingR2dbcConverter(
8484
// Entity reading
8585
// ----------------------------------
8686

87-
/*
87+
/*
8888
* (non-Javadoc)
8989
* @see org.springframework.data.convert.EntityReader#read(java.lang.Class, S)
9090
*/
@@ -93,7 +93,7 @@ public <R> R read(Class<R> type, Row row) {
9393
return read(type, row, null);
9494
}
9595

96-
/*
96+
/*
9797
* (non-Javadoc)
9898
* @see org.springframework.data.r2dbc.convert.R2dbcConverter#read(java.lang.Class, io.r2dbc.spi.Row, io.r2dbc.spi.RowMetadata)
9999
*/
@@ -233,7 +233,7 @@ private <S> S createInstance(Row row, String prefix, RelationalPersistentEntity<
233233
// Entity writing
234234
// ----------------------------------
235235

236-
/*
236+
/*
237237
* (non-Javadoc)
238238
* @see org.springframework.data.convert.EntityWriter#write(java.lang.Object, java.lang.Object)
239239
*/
@@ -337,7 +337,7 @@ private Object getPotentiallyConvertedSimpleWrite(@Nullable Object value) {
337337
return Enum.class.isAssignableFrom(value.getClass()) ? ((Enum<?>) value).name() : value;
338338
}
339339

340-
/*
340+
/*
341341
* (non-Javadoc)
342342
* @see org.springframework.data.r2dbc.convert.R2dbcConverter#getArrayValue(org.springframework.data.r2dbc.dialect.ArrayColumns, org.springframework.data.relational.core.mapping.RelationalPersistentProperty, java.lang.Object)
343343
*/

src/main/java/org/springframework/data/r2dbc/convert/R2dbcConverter.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
import org.springframework.data.convert.EntityReader;
2525
import org.springframework.data.convert.EntityWriter;
2626
import org.springframework.data.mapping.context.MappingContext;
27-
import org.springframework.data.r2dbc.dialect.ArrayColumns;
2827
import org.springframework.data.r2dbc.mapping.OutboundRow;
2928
import org.springframework.data.relational.core.conversion.RelationalConverter;
29+
import org.springframework.data.relational.core.dialect.ArrayColumns;
3030
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
3131
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
3232

src/main/java/org/springframework/data/r2dbc/core/DefaultDatabaseClientBuilder.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
import org.springframework.data.r2dbc.core.DatabaseClient.Builder;
2424
import org.springframework.data.r2dbc.dialect.Database;
25-
import org.springframework.data.r2dbc.dialect.Dialect;
25+
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
2626
import org.springframework.data.r2dbc.support.R2dbcExceptionSubclassTranslator;
2727
import org.springframework.data.r2dbc.support.R2dbcExceptionTranslator;
2828
import org.springframework.lang.Nullable;
@@ -121,7 +121,7 @@ public DatabaseClient build() {
121121

122122
if (accessStrategy == null) {
123123

124-
Dialect dialect = Database.findDatabase(this.connectionFactory)
124+
R2dbcDialect dialect = Database.findDatabase(this.connectionFactory)
125125
.orElseThrow(() -> new UnsupportedOperationException(
126126
"Cannot determine a Dialect. Configure the dialect by providing DefaultReactiveDataAccessStrategy(Dialect)"))
127127
.defaultDialect();

src/main/java/org/springframework/data/r2dbc/core/DefaultReactiveDataAccessStrategy.java

+17-46
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,27 @@
2323
import java.util.Collections;
2424
import java.util.List;
2525
import java.util.function.BiFunction;
26-
import java.util.function.Function;
2726

28-
import org.springframework.core.annotation.AnnotatedElementUtils;
2927
import org.springframework.dao.InvalidDataAccessResourceUsageException;
3028
import org.springframework.data.convert.CustomConversions.StoreConversions;
3129
import org.springframework.data.mapping.context.MappingContext;
3230
import org.springframework.data.r2dbc.convert.EntityRowMapper;
3331
import org.springframework.data.r2dbc.convert.MappingR2dbcConverter;
3432
import org.springframework.data.r2dbc.convert.R2dbcConverter;
3533
import org.springframework.data.r2dbc.convert.R2dbcCustomConversions;
36-
import org.springframework.data.r2dbc.dialect.ArrayColumns;
3734
import org.springframework.data.r2dbc.dialect.BindMarkersFactory;
38-
import org.springframework.data.r2dbc.dialect.Dialect;
35+
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
3936
import org.springframework.data.r2dbc.mapping.OutboundRow;
4037
import org.springframework.data.r2dbc.mapping.SettableValue;
4138
import org.springframework.data.r2dbc.query.UpdateMapper;
42-
import org.springframework.data.relational.core.mapping.NamingStrategy;
39+
import org.springframework.data.relational.core.dialect.ArrayColumns;
40+
import org.springframework.data.relational.core.dialect.RenderContextFactory;
4341
import org.springframework.data.relational.core.mapping.RelationalMappingContext;
4442
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
4543
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
46-
import org.springframework.data.relational.core.mapping.Table;
47-
import org.springframework.data.relational.core.sql.Select;
48-
import org.springframework.data.relational.core.sql.render.NamingStrategies;
49-
import org.springframework.data.relational.core.sql.render.RenderContext;
50-
import org.springframework.data.relational.core.sql.render.RenderNamingStrategy;
51-
import org.springframework.data.relational.core.sql.render.SelectRenderContext;
5244
import org.springframework.lang.Nullable;
5345
import org.springframework.util.Assert;
5446
import org.springframework.util.ClassUtils;
55-
import org.springframework.util.StringUtils;
5647

5748
/**
5849
* Default {@link ReactiveDataAccessStrategy} implementation.
@@ -61,36 +52,36 @@
6152
*/
6253
public class DefaultReactiveDataAccessStrategy implements ReactiveDataAccessStrategy {
6354

64-
private final Dialect dialect;
55+
private final R2dbcDialect dialect;
6556
private final R2dbcConverter converter;
6657
private final UpdateMapper updateMapper;
6758
private final MappingContext<RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> mappingContext;
6859
private final StatementMapper statementMapper;
6960

7061
/**
71-
* Creates a new {@link DefaultReactiveDataAccessStrategy} given {@link Dialect} and optional
62+
* Creates a new {@link DefaultReactiveDataAccessStrategy} given {@link R2dbcDialect} and optional
7263
* {@link org.springframework.core.convert.converter.Converter}s.
7364
*
74-
* @param dialect the {@link Dialect} to use.
65+
* @param dialect the {@link R2dbcDialect} to use.
7566
*/
76-
public DefaultReactiveDataAccessStrategy(Dialect dialect) {
67+
public DefaultReactiveDataAccessStrategy(R2dbcDialect dialect) {
7768
this(dialect, Collections.emptyList());
7869
}
7970

8071
/**
81-
* Creates a new {@link DefaultReactiveDataAccessStrategy} given {@link Dialect} and optional
72+
* Creates a new {@link DefaultReactiveDataAccessStrategy} given {@link R2dbcDialect} and optional
8273
* {@link org.springframework.core.convert.converter.Converter}s.
8374
*
84-
* @param dialect the {@link Dialect} to use.
75+
* @param dialect the {@link R2dbcDialect} to use.
8576
* @param converters custom converters to register, must not be {@literal null}.
8677
* @see R2dbcCustomConversions
8778
* @see org.springframework.core.convert.converter.Converter
8879
*/
89-
public DefaultReactiveDataAccessStrategy(Dialect dialect, Collection<?> converters) {
80+
public DefaultReactiveDataAccessStrategy(R2dbcDialect dialect, Collection<?> converters) {
9081
this(dialect, createConverter(dialect, converters));
9182
}
9283

93-
private static R2dbcConverter createConverter(Dialect dialect, Collection<?> converters) {
84+
private static R2dbcConverter createConverter(R2dbcDialect dialect, Collection<?> converters) {
9485

9586
Assert.notNull(dialect, "Dialect must not be null");
9687
Assert.notNull(converters, "Converters must not be null");
@@ -105,13 +96,13 @@ private static R2dbcConverter createConverter(Dialect dialect, Collection<?> con
10596
}
10697

10798
/**
108-
* Creates a new {@link DefaultReactiveDataAccessStrategy} given {@link Dialect} and {@link R2dbcConverter}.
99+
* Creates a new {@link DefaultReactiveDataAccessStrategy} given {@link R2dbcDialect} and {@link R2dbcConverter}.
109100
*
110-
* @param dialect the {@link Dialect} to use.
101+
* @param dialect the {@link R2dbcDialect} to use.
111102
* @param converter must not be {@literal null}.
112103
*/
113104
@SuppressWarnings("unchecked")
114-
public DefaultReactiveDataAccessStrategy(Dialect dialect, R2dbcConverter converter) {
105+
public DefaultReactiveDataAccessStrategy(R2dbcDialect dialect, R2dbcConverter converter) {
115106

116107
Assert.notNull(dialect, "Dialect must not be null");
117108
Assert.notNull(converter, "RelationalConverter must not be null");
@@ -122,29 +113,9 @@ public DefaultReactiveDataAccessStrategy(Dialect dialect, R2dbcConverter convert
122113
.getMappingContext();
123114
this.dialect = dialect;
124115

125-
RenderContext renderContext = new RenderContext() {
126-
@Override
127-
public RenderNamingStrategy getNamingStrategy() {
128-
return NamingStrategies.asIs();
129-
}
130-
131-
@Override
132-
public SelectRenderContext getSelect() {
133-
return new SelectRenderContext() {
134-
@Override
135-
public Function<Select, ? extends CharSequence> afterSelectList() {
136-
return it -> "";
137-
}
138-
139-
@Override
140-
public Function<Select, ? extends CharSequence> afterOrderBy(boolean hasOrderBy) {
141-
return it -> "";
142-
}
143-
};
144-
}
145-
};
146-
147-
this.statementMapper = new DefaultStatementMapper(dialect, renderContext, this.updateMapper, this.mappingContext);
116+
RenderContextFactory factory = new RenderContextFactory(dialect);
117+
this.statementMapper = new DefaultStatementMapper(dialect, factory.createRenderContext(), this.updateMapper,
118+
this.mappingContext);
148119
}
149120

150121
/*

src/main/java/org/springframework/data/r2dbc/core/DefaultStatementMapper.java

+6-32
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,21 @@
2020
import java.util.ArrayList;
2121
import java.util.Collection;
2222
import java.util.List;
23-
import java.util.OptionalLong;
2423

2524
import org.springframework.data.domain.Pageable;
2625
import org.springframework.data.domain.Sort;
2726
import org.springframework.data.mapping.context.MappingContext;
2827
import org.springframework.data.r2dbc.dialect.BindMarkers;
2928
import org.springframework.data.r2dbc.dialect.BindTarget;
3029
import org.springframework.data.r2dbc.dialect.Bindings;
31-
import org.springframework.data.r2dbc.dialect.Dialect;
30+
import org.springframework.data.r2dbc.dialect.R2dbcDialect;
3231
import org.springframework.data.r2dbc.query.BoundAssignments;
3332
import org.springframework.data.r2dbc.query.BoundCondition;
3433
import org.springframework.data.r2dbc.query.UpdateMapper;
35-
import org.springframework.data.r2dbc.support.StatementRenderUtil;
3634
import org.springframework.data.relational.core.mapping.RelationalPersistentEntity;
3735
import org.springframework.data.relational.core.mapping.RelationalPersistentProperty;
38-
import org.springframework.data.relational.core.sql.AssignValue;
39-
import org.springframework.data.relational.core.sql.Assignment;
40-
import org.springframework.data.relational.core.sql.Column;
41-
import org.springframework.data.relational.core.sql.Delete;
42-
import org.springframework.data.relational.core.sql.DeleteBuilder;
43-
import org.springframework.data.relational.core.sql.Insert;
44-
import org.springframework.data.relational.core.sql.InsertBuilder;
36+
import org.springframework.data.relational.core.sql.*;
4537
import org.springframework.data.relational.core.sql.InsertBuilder.InsertValuesWithBuild;
46-
import org.springframework.data.relational.core.sql.OrderByField;
47-
import org.springframework.data.relational.core.sql.Select;
48-
import org.springframework.data.relational.core.sql.SelectBuilder;
49-
import org.springframework.data.relational.core.sql.StatementBuilder;
50-
import org.springframework.data.relational.core.sql.Table;
51-
import org.springframework.data.relational.core.sql.Update;
52-
import org.springframework.data.relational.core.sql.UpdateBuilder;
5338
import org.springframework.data.relational.core.sql.render.RenderContext;
5439
import org.springframework.data.relational.core.sql.render.SqlRenderer;
5540
import org.springframework.lang.Nullable;
@@ -63,7 +48,7 @@
6348
@RequiredArgsConstructor
6449
class DefaultStatementMapper implements StatementMapper {
6550

66-
private final Dialect dialect;
51+
private final R2dbcDialect dialect;
6752
private final RenderContext renderContext;
6853
private final UpdateMapper updateMapper;
6954
private final MappingContext<RelationalPersistentEntity<?>, ? extends RelationalPersistentProperty> mappingContext;
@@ -116,26 +101,15 @@ private PreparedOperation<Select> getMappedObject(SelectSpec selectSpec,
116101
selectBuilder.orderBy(createOrderByFields(table, mappedSort));
117102
}
118103

119-
OptionalLong limit;
120-
OptionalLong offset;
121-
122104
if (selectSpec.getPage().isPaged()) {
123105

124106
Pageable page = selectSpec.getPage();
125-
limit = OptionalLong.of(page.getPageSize());
126-
offset = OptionalLong.of(page.getOffset());
127-
} else {
128-
limit = OptionalLong.empty();
129-
offset = OptionalLong.empty();
107+
108+
selectBuilder.limitOffset(page.getPageSize(), page.getOffset());
130109
}
131110

132111
Select select = selectBuilder.build();
133-
return new DefaultPreparedOperation<Select>(select, this.renderContext, bindings) {
134-
@Override
135-
public String toQuery() {
136-
return StatementRenderUtil.render(select, limit, offset, DefaultStatementMapper.this.dialect);
137-
}
138-
};
112+
return new DefaultPreparedOperation<>(select, this.renderContext, bindings);
139113
}
140114

141115
private Collection<? extends OrderByField> createOrderByFields(Table table, Sort sortToUse) {

src/main/java/org/springframework/data/r2dbc/core/ReactiveDataAccessStrategy.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323

2424
import org.springframework.data.r2dbc.convert.R2dbcConverter;
2525
import org.springframework.data.r2dbc.dialect.BindMarkersFactory;
26-
import org.springframework.data.r2dbc.dialect.Dialect;
2726
import org.springframework.data.r2dbc.mapping.OutboundRow;
2827
import org.springframework.data.r2dbc.mapping.SettableValue;
2928

@@ -67,9 +66,9 @@ public interface ReactiveDataAccessStrategy {
6766
String getTableName(Class<?> type);
6867

6968
/**
70-
* Returns the {@link Dialect}-specific {@link StatementMapper}.
69+
* Returns the {@link org.springframework.data.r2dbc.dialect.R2dbcDialect}-specific {@link StatementMapper}.
7170
*
72-
* @return the {@link Dialect}-specific {@link StatementMapper}.
71+
* @return the {@link org.springframework.data.r2dbc.dialect.R2dbcDialect}-specific {@link StatementMapper}.
7372
*/
7473
StatementMapper getStatementMapper();
7574

src/main/java/org/springframework/data/r2dbc/core/StatementMapper.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@
2525
import org.springframework.data.domain.Pageable;
2626
import org.springframework.data.domain.Sort;
2727
import org.springframework.data.r2dbc.dialect.BindMarkers;
28-
import org.springframework.data.r2dbc.dialect.Dialect;
2928
import org.springframework.data.r2dbc.mapping.SettableValue;
3029
import org.springframework.data.r2dbc.query.Criteria;
3130
import org.springframework.data.r2dbc.query.Update;
3231
import org.springframework.lang.Nullable;
3332

3433
/**
3534
* Mapper for statement specifications to {@link PreparedOperation}. Statement mapping applies a
36-
* {@link Dialect}-specific transformation considering {@link BindMarkers} and vendor-specific SQL differences.
35+
* {@link org.springframework.data.r2dbc.dialect.R2dbcDialect}-specific transformation considering {@link BindMarkers}
36+
* and vendor-specific SQL differences.
3737
*
3838
* @author Mark Paluch
3939
*/

0 commit comments

Comments
 (0)