Skip to content

Commit e50451f

Browse files
committed
#220 - Refactor StatementMapper.
Use limit/offset instead of Page and accept Expression objects to declare a select list.
1 parent 0d77c93 commit e50451f

File tree

2 files changed

+117
-24
lines changed

2 files changed

+117
-24
lines changed

Diff for: src/main/java/org/springframework/data/r2dbc/core/DefaultStatementMapper.java

+24-8
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Collection;
2020
import java.util.List;
2121

22-
import org.springframework.data.domain.Pageable;
2322
import org.springframework.data.domain.Sort;
2423
import org.springframework.data.mapping.context.MappingContext;
2524
import org.springframework.data.r2dbc.dialect.BindMarkers;
@@ -84,9 +83,9 @@ public PreparedOperation<?> getMappedObject(SelectSpec selectSpec) {
8483
private PreparedOperation<Select> getMappedObject(SelectSpec selectSpec,
8584
@Nullable RelationalPersistentEntity<?> entity) {
8685

87-
Table table = Table.create(selectSpec.getTable());
88-
List<Column> columns = table.columns(selectSpec.getProjectedFields());
89-
SelectBuilder.SelectFromAndJoin selectBuilder = StatementBuilder.select(columns).from(table);
86+
Table table = selectSpec.getTable();
87+
SelectBuilder.SelectFromAndJoin selectBuilder = StatementBuilder.select(getSelectList(selectSpec, entity))
88+
.from(table);
9089

9190
BindMarkers bindMarkers = this.dialect.getBindMarkersFactory().create();
9291
Bindings bindings = Bindings.empty();
@@ -106,17 +105,34 @@ private PreparedOperation<Select> getMappedObject(SelectSpec selectSpec,
106105
selectBuilder.orderBy(createOrderByFields(table, mappedSort));
107106
}
108107

109-
if (selectSpec.getPage().isPaged()) {
110-
111-
Pageable page = selectSpec.getPage();
108+
if (selectSpec.getLimit() > 0) {
109+
selectBuilder.limit(selectSpec.getLimit());
110+
}
112111

113-
selectBuilder.limitOffset(page.getPageSize(), page.getOffset());
112+
if (selectSpec.getOffset() > 0) {
113+
selectBuilder.offset(selectSpec.getOffset());
114114
}
115115

116116
Select select = selectBuilder.build();
117117
return new DefaultPreparedOperation<>(select, this.renderContext, bindings);
118118
}
119119

120+
protected List<Expression> getSelectList(SelectSpec selectSpec, @Nullable RelationalPersistentEntity<?> entity) {
121+
122+
if (entity == null) {
123+
return selectSpec.getSelectList();
124+
}
125+
126+
List<Expression> selectList = selectSpec.getSelectList();
127+
List<Expression> mapped = new ArrayList<>(selectList.size());
128+
129+
for (Expression expression : selectList) {
130+
mapped.add(updateMapper.getMappedObject(expression, entity));
131+
}
132+
133+
return mapped;
134+
}
135+
120136
private Collection<? extends OrderByField> createOrderByFields(Table table, Sort sortToUse) {
121137

122138
List<OrderByField> fields = new ArrayList<>();

Diff for: src/main/java/org/springframework/data/r2dbc/core/StatementMapper.java

+93-16
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,23 @@
1616
package org.springframework.data.r2dbc.core;
1717

1818
import java.util.ArrayList;
19+
import java.util.Arrays;
1920
import java.util.Collection;
2021
import java.util.Collections;
2122
import java.util.LinkedHashMap;
2223
import java.util.List;
2324
import java.util.Map;
25+
import java.util.function.BiFunction;
2426

2527
import org.springframework.data.domain.Pageable;
2628
import org.springframework.data.domain.Sort;
2729
import org.springframework.data.r2dbc.dialect.BindMarkers;
2830
import org.springframework.data.r2dbc.mapping.SettableValue;
2931
import org.springframework.data.r2dbc.query.Criteria;
3032
import org.springframework.data.r2dbc.query.Update;
33+
import org.springframework.data.relational.core.sql.Column;
34+
import org.springframework.data.relational.core.sql.Expression;
35+
import org.springframework.data.relational.core.sql.Table;
3136
import org.springframework.lang.Nullable;
3237

3338
/**
@@ -132,19 +137,23 @@ default DeleteSpec createDelete(String table) {
132137
*/
133138
class SelectSpec {
134139

135-
private final String table;
140+
private final Table table;
136141
private final List<String> projectedFields;
142+
private final List<Expression> selectList;
137143
private final @Nullable Criteria criteria;
138144
private final Sort sort;
139-
private final Pageable page;
145+
private final long offset;
146+
private final int limit;
140147

141-
protected SelectSpec(String table, List<String> projectedFields, @Nullable Criteria criteria, Sort sort,
142-
Pageable page) {
148+
protected SelectSpec(Table table, List<String> projectedFields, List<Expression> selectList,
149+
@Nullable Criteria criteria, Sort sort, int limit, long offset) {
143150
this.table = table;
144151
this.projectedFields = projectedFields;
152+
this.selectList = selectList;
145153
this.criteria = criteria;
146154
this.sort = sort;
147-
this.page = page;
155+
this.offset = offset;
156+
this.limit = limit;
148157
}
149158

150159
/**
@@ -154,7 +163,23 @@ protected SelectSpec(String table, List<String> projectedFields, @Nullable Crite
154163
* @return the {@link SelectSpec}.
155164
*/
156165
public static SelectSpec create(String table) {
157-
return new SelectSpec(table, Collections.emptyList(), null, Sort.unsorted(), Pageable.unpaged());
166+
return new SelectSpec(Table.create(table), Collections.emptyList(), Collections.emptyList(), null,
167+
Sort.unsorted(), -1, -1);
168+
}
169+
170+
public SelectSpec doWithTable(BiFunction<Table, SelectSpec, SelectSpec> function) {
171+
return function.apply(getTable(), this);
172+
}
173+
174+
/**
175+
* Associate {@code projectedFields} with the select and create a new {@link SelectSpec}.
176+
*
177+
* @param projectedFields
178+
* @return the {@link SelectSpec}.
179+
* @since 1.1
180+
*/
181+
public SelectSpec withProjection(String... projectedFields) {
182+
return withProjection(Arrays.asList(projectedFields));
158183
}
159184

160185
/**
@@ -168,7 +193,25 @@ public SelectSpec withProjection(Collection<String> projectedFields) {
168193
List<String> fields = new ArrayList<>(this.projectedFields);
169194
fields.addAll(projectedFields);
170195

171-
return new SelectSpec(this.table, fields, this.criteria, this.sort, this.page);
196+
List<Expression> selectList = new ArrayList<>(this.selectList);
197+
projectedFields.stream().map(s -> Column.create(s, table)).forEach(selectList::add);
198+
199+
return new SelectSpec(this.table, fields, selectList, this.criteria, this.sort, this.limit, this.offset);
200+
}
201+
202+
/**
203+
* Associate {@code expressions} with the select list and create a new {@link SelectSpec}.
204+
*
205+
* @param expressions
206+
* @return the {@link SelectSpec}.
207+
* @since 1.1
208+
*/
209+
public SelectSpec withProjection(Expression... expressions) {
210+
211+
List<Expression> selectList = new ArrayList<>(this.selectList);
212+
selectList.addAll(Arrays.asList(expressions));
213+
214+
return new SelectSpec(this.table, projectedFields, selectList, this.criteria, this.sort, this.limit, this.offset);
172215
}
173216

174217
/**
@@ -178,7 +221,8 @@ public SelectSpec withProjection(Collection<String> projectedFields) {
178221
* @return the {@link SelectSpec}.
179222
*/
180223
public SelectSpec withCriteria(Criteria criteria) {
181-
return new SelectSpec(this.table, this.projectedFields, criteria, this.sort, this.page);
224+
return new SelectSpec(this.table, this.projectedFields, this.selectList, criteria, this.sort, this.limit,
225+
this.offset);
182226
}
183227

184228
/**
@@ -190,10 +234,12 @@ public SelectSpec withCriteria(Criteria criteria) {
190234
public SelectSpec withSort(Sort sort) {
191235

192236
if (sort.isSorted()) {
193-
return new SelectSpec(this.table, this.projectedFields, this.criteria, sort, this.page);
237+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, sort, this.limit,
238+
this.offset);
194239
}
195240

196-
return new SelectSpec(this.table, this.projectedFields, this.criteria, this.sort, this.page);
241+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, this.limit,
242+
this.offset);
197243
}
198244

199245
/**
@@ -208,21 +254,48 @@ public SelectSpec withPage(Pageable page) {
208254

209255
Sort sort = page.getSort();
210256

211-
return new SelectSpec(this.table, this.projectedFields, this.criteria, sort.isSorted() ? sort : this.sort,
212-
page);
257+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria,
258+
sort.isSorted() ? sort : this.sort, page.getPageSize(), page.getOffset());
213259
}
214260

215-
return new SelectSpec(this.table, this.projectedFields, this.criteria, this.sort, page);
261+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, this.limit,
262+
this.offset);
216263
}
217264

218-
public String getTable() {
265+
/**
266+
* Associate a result offset with the select and create a new {@link SelectSpec}.
267+
*
268+
* @param page
269+
* @return the {@link SelectSpec}.
270+
*/
271+
public SelectSpec offset(long offset) {
272+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, this.limit,
273+
offset);
274+
}
275+
276+
/**
277+
* Associate a result limit with the select and create a new {@link SelectSpec}.
278+
*
279+
* @param page
280+
* @return the {@link SelectSpec}.
281+
*/
282+
public SelectSpec limit(int limit) {
283+
return new SelectSpec(this.table, this.projectedFields, this.selectList, this.criteria, this.sort, limit,
284+
this.offset);
285+
}
286+
287+
public Table getTable() {
219288
return this.table;
220289
}
221290

222291
public List<String> getProjectedFields() {
223292
return Collections.unmodifiableList(this.projectedFields);
224293
}
225294

295+
public List<Expression> getSelectList() {
296+
return Collections.unmodifiableList(selectList);
297+
}
298+
226299
@Nullable
227300
public Criteria getCriteria() {
228301
return this.criteria;
@@ -232,8 +305,12 @@ public Sort getSort() {
232305
return this.sort;
233306
}
234307

235-
public Pageable getPage() {
236-
return this.page;
308+
public long getOffset() {
309+
return this.offset;
310+
}
311+
312+
public int getLimit() {
313+
return this.limit;
237314
}
238315
}
239316

0 commit comments

Comments
 (0)