16
16
package org .springframework .data .r2dbc .core ;
17
17
18
18
import java .util .ArrayList ;
19
+ import java .util .Arrays ;
19
20
import java .util .Collection ;
20
21
import java .util .Collections ;
21
22
import java .util .LinkedHashMap ;
22
23
import java .util .List ;
23
24
import java .util .Map ;
25
+ import java .util .function .BiFunction ;
24
26
25
27
import org .springframework .data .domain .Pageable ;
26
28
import org .springframework .data .domain .Sort ;
27
29
import org .springframework .data .r2dbc .dialect .BindMarkers ;
28
30
import org .springframework .data .r2dbc .mapping .SettableValue ;
29
31
import org .springframework .data .r2dbc .query .Criteria ;
30
32
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 ;
31
36
import org .springframework .lang .Nullable ;
32
37
33
38
/**
@@ -132,19 +137,23 @@ default DeleteSpec createDelete(String table) {
132
137
*/
133
138
class SelectSpec {
134
139
135
- private final String table ;
140
+ private final Table table ;
136
141
private final List <String > projectedFields ;
142
+ private final List <Expression > selectList ;
137
143
private final @ Nullable Criteria criteria ;
138
144
private final Sort sort ;
139
- private final Pageable page ;
145
+ private final long offset ;
146
+ private final int limit ;
140
147
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 ) {
143
150
this .table = table ;
144
151
this .projectedFields = projectedFields ;
152
+ this .selectList = selectList ;
145
153
this .criteria = criteria ;
146
154
this .sort = sort ;
147
- this .page = page ;
155
+ this .offset = offset ;
156
+ this .limit = limit ;
148
157
}
149
158
150
159
/**
@@ -154,7 +163,23 @@ protected SelectSpec(String table, List<String> projectedFields, @Nullable Crite
154
163
* @return the {@link SelectSpec}.
155
164
*/
156
165
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 ));
158
183
}
159
184
160
185
/**
@@ -168,7 +193,25 @@ public SelectSpec withProjection(Collection<String> projectedFields) {
168
193
List <String > fields = new ArrayList <>(this .projectedFields );
169
194
fields .addAll (projectedFields );
170
195
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 );
172
215
}
173
216
174
217
/**
@@ -178,7 +221,8 @@ public SelectSpec withProjection(Collection<String> projectedFields) {
178
221
* @return the {@link SelectSpec}.
179
222
*/
180
223
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 );
182
226
}
183
227
184
228
/**
@@ -190,10 +234,12 @@ public SelectSpec withCriteria(Criteria criteria) {
190
234
public SelectSpec withSort (Sort sort ) {
191
235
192
236
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 );
194
239
}
195
240
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 );
197
243
}
198
244
199
245
/**
@@ -208,21 +254,48 @@ public SelectSpec withPage(Pageable page) {
208
254
209
255
Sort sort = page .getSort ();
210
256
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 () );
213
259
}
214
260
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 );
216
263
}
217
264
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 () {
219
288
return this .table ;
220
289
}
221
290
222
291
public List <String > getProjectedFields () {
223
292
return Collections .unmodifiableList (this .projectedFields );
224
293
}
225
294
295
+ public List <Expression > getSelectList () {
296
+ return Collections .unmodifiableList (selectList );
297
+ }
298
+
226
299
@ Nullable
227
300
public Criteria getCriteria () {
228
301
return this .criteria ;
@@ -232,8 +305,12 @@ public Sort getSort() {
232
305
return this .sort ;
233
306
}
234
307
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 ;
237
314
}
238
315
}
239
316
0 commit comments