Skip to content

Commit ad45656

Browse files
authored
Merge pull request #96 from jeffgbutler/master
Add Support for Fetch First Based Paging
2 parents 1e3d5af + b4658d9 commit ad45656

16 files changed

+735
-76
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,13 +138,13 @@
138138
<dependency>
139139
<groupId>org.hsqldb</groupId>
140140
<artifactId>hsqldb</artifactId>
141-
<version>2.4.1</version>
141+
<version>2.5.0</version>
142142
<scope>test</scope>
143143
</dependency>
144144
<dependency>
145145
<groupId>org.springframework</groupId>
146146
<artifactId>spring-jdbc</artifactId>
147-
<version>5.1.7.RELEASE</version>
147+
<version>5.1.8.RELEASE</version>
148148
<scope>test</scope>
149149
</dependency>
150150
<dependency>

src/main/java/org/mybatis/dynamic/sql/SqlTable.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,17 @@ protected SqlTable(Supplier<Optional<String>> schemaSupplier, String tableName)
4040
this(Optional::empty, schemaSupplier, tableName);
4141
}
4242

43-
protected SqlTable(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, String tableName) {
43+
protected SqlTable(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier,
44+
String tableName) {
4445
Objects.requireNonNull(catalogSupplier);
4546
Objects.requireNonNull(schemaSupplier);
4647
Objects.requireNonNull(tableName);
4748

4849
this.nameSupplier = () -> compose(catalogSupplier, schemaSupplier, tableName);
4950
}
5051

51-
private String compose(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier, String tableName) {
52+
private String compose(Supplier<Optional<String>> catalogSupplier, Supplier<Optional<String>> schemaSupplier,
53+
String tableName) {
5254
return catalogSupplier.get().map(c -> compose(c, schemaSupplier, tableName))
5355
.orElse(compose(schemaSupplier, tableName));
5456
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright 2016-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.mybatis.dynamic.sql.select;
17+
18+
import java.util.Optional;
19+
20+
public class FetchFirstPagingModel implements PagingModel {
21+
22+
private Long fetchFirstRows;
23+
private Long offset;
24+
25+
private FetchFirstPagingModel(Builder builder) {
26+
this.fetchFirstRows = builder.fetchFirstRows;
27+
this.offset = builder.offset;
28+
}
29+
30+
public Optional<Long> fetchFirstRows() {
31+
return Optional.ofNullable(fetchFirstRows);
32+
}
33+
34+
public Optional<Long> offset() {
35+
return Optional.ofNullable(offset);
36+
}
37+
38+
@Override
39+
public <R> R accept(PagingModelVisitor<R> visitor) {
40+
return visitor.visit(this);
41+
}
42+
43+
public static class Builder {
44+
private Long fetchFirstRows;
45+
private Long offset;
46+
47+
public Builder withFetchFirstRows(Long fetchFirstRows) {
48+
this.fetchFirstRows = fetchFirstRows;
49+
return this;
50+
}
51+
52+
public Builder withOffset(Long offset) {
53+
this.offset = offset;
54+
return this;
55+
}
56+
57+
public FetchFirstPagingModel build() {
58+
return new FetchFirstPagingModel(this);
59+
}
60+
}
61+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* Copyright 2016-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.mybatis.dynamic.sql.select;
17+
18+
import java.util.Optional;
19+
20+
public class LimitAndOffsetPagingModel implements PagingModel {
21+
22+
private Long limit;
23+
private Long offset;
24+
25+
private LimitAndOffsetPagingModel(Builder builder) {
26+
this.limit = builder.limit;
27+
this.offset = builder.offset;
28+
}
29+
30+
public Optional<Long> limit() {
31+
return Optional.ofNullable(limit);
32+
}
33+
34+
public Optional<Long> offset() {
35+
return Optional.ofNullable(offset);
36+
}
37+
38+
@Override
39+
public <R> R accept(PagingModelVisitor<R> visitor) {
40+
return visitor.visit(this);
41+
}
42+
43+
public static class Builder {
44+
private Long limit;
45+
private Long offset;
46+
47+
public Builder withLimit(Long limit) {
48+
this.limit = limit;
49+
return this;
50+
}
51+
52+
public Builder withOffset(Long offset) {
53+
this.offset = offset;
54+
return this;
55+
}
56+
57+
public LimitAndOffsetPagingModel build() {
58+
return new LimitAndOffsetPagingModel(this);
59+
}
60+
}
61+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright 2016-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.mybatis.dynamic.sql.select;
17+
18+
public interface PagingModel {
19+
<R> R accept(PagingModelVisitor<R> visitor);
20+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Copyright 2016-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.mybatis.dynamic.sql.select;
17+
18+
public interface PagingModelVisitor<R> {
19+
R visit(LimitAndOffsetPagingModel pagingModel);
20+
21+
R visit(FetchFirstPagingModel pagingModel);
22+
}

src/main/java/org/mybatis/dynamic/sql/select/QueryExpressionDSL.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,16 @@ public SelectDSL<R>.LimitFinisher limit(long limit) {
149149
return selectDSL.limit(limit);
150150
}
151151

152-
public SelectDSL<R>.OffsetFinisher offset(long offset) {
152+
public SelectDSL<R>.OffsetFirstFinisher offset(long offset) {
153153
selectDSL.addQueryExpression(buildModel());
154154
return selectDSL.offset(offset);
155155
}
156156

157+
public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) {
158+
selectDSL.addQueryExpression(buildModel());
159+
return selectDSL.fetchFirst(fetchFirstRows);
160+
}
161+
157162
public static class FromGatherer<R> {
158163
private FromGathererBuilder<R> builder;
159164
private Map<SqlTable, String> tableAliasMap = new HashMap<>();
@@ -250,12 +255,18 @@ public SelectDSL<R>.LimitFinisher limit(long limit) {
250255
return selectDSL.limit(limit);
251256
}
252257

253-
public SelectDSL<R>.OffsetFinisher offset(long offset) {
258+
public SelectDSL<R>.OffsetFirstFinisher offset(long offset) {
254259
whereModel = buildWhereModel();
255260
selectDSL.addQueryExpression(buildModel());
256261
return selectDSL.offset(offset);
257262
}
258263

264+
public SelectDSL<R>.FetchFirstFinisher fetchFirst(long fetchFirstRows) {
265+
whereModel = buildWhereModel();
266+
selectDSL.addQueryExpression(buildModel());
267+
return selectDSL.fetchFirst(fetchFirstRows);
268+
}
269+
259270
@Override
260271
public R build() {
261272
whereModel = buildWhereModel();
@@ -413,7 +424,7 @@ public SelectDSL<R>.LimitFinisher limit(long limit) {
413424
return selectDSL.limit(limit);
414425
}
415426

416-
public SelectDSL<R>.OffsetFinisher offset(long offset) {
427+
public SelectDSL<R>.OffsetFirstFinisher offset(long offset) {
417428
joinModel = buildJoinModel();
418429
selectDSL.addQueryExpression(buildModel());
419430
return selectDSL.offset(offset);
@@ -435,7 +446,7 @@ public SelectDSL<R>.LimitFinisher limit(long limit) {
435446
return selectDSL.limit(limit);
436447
}
437448

438-
public SelectDSL<R>.OffsetFinisher offset(long offset) {
449+
public SelectDSL<R>.OffsetFirstFinisher offset(long offset) {
439450
return selectDSL.offset(offset);
440451
}
441452
}

src/main/java/org/mybatis/dynamic/sql/select/SelectDSL.java

Lines changed: 87 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,7 @@ public class SelectDSL<R> implements Buildable<R> {
3838
private Function<SelectModel, R> adapterFunction;
3939
private List<QueryExpressionModel> queryExpressions = new ArrayList<>();
4040
private OrderByModel orderByModel;
41-
private Long limit;
42-
private Long offset;
41+
private PagingModel pagingModel;
4342

4443
private SelectDSL(Function<SelectModel, R> adapterFunction) {
4544
this.adapterFunction = Objects.requireNonNull(adapterFunction);
@@ -100,39 +99,116 @@ void setOrderByModel(OrderByModel orderByModel) {
10099
}
101100

102101
public LimitFinisher limit(long limit) {
103-
this.limit = limit;
104-
return new LimitFinisher();
102+
return new LimitFinisher(limit);
105103
}
106104

107-
public OffsetFinisher offset(long offset) {
108-
this.offset = offset;
109-
return new OffsetFinisher();
105+
public OffsetFirstFinisher offset(long offset) {
106+
return new OffsetFirstFinisher(offset);
107+
}
108+
109+
public FetchFirstFinisher fetchFirst(long fetchFirstRows) {
110+
return new FetchFirstFinisher(fetchFirstRows);
110111
}
111112

112113
@Override
113114
public R build() {
114115
SelectModel selectModel = SelectModel.withQueryExpressions(queryExpressions)
115116
.withOrderByModel(orderByModel)
116-
.withLimit(limit)
117-
.withOffset(offset)
117+
.withPagingModel(pagingModel)
118118
.build();
119119
return adapterFunction.apply(selectModel);
120120
}
121121

122122
public class LimitFinisher implements Buildable<R> {
123-
public OffsetFinisher offset(int offset) {
124-
return SelectDSL.this.offset(offset);
123+
private long limit;
124+
125+
public LimitFinisher(long limit) {
126+
this.limit = limit;
127+
}
128+
129+
public OffsetFinisher offset(long offset) {
130+
return new OffsetFinisher(limit, offset);
125131
}
126132

127133
@Override
128134
public R build() {
135+
SelectDSL.this.pagingModel = new LimitAndOffsetPagingModel.Builder()
136+
.withLimit(limit)
137+
.build();
129138
return SelectDSL.this.build();
130139
}
131140
}
132141

133142
public class OffsetFinisher implements Buildable<R> {
143+
private LimitAndOffsetPagingModel pagingModel;
144+
145+
public OffsetFinisher(long limit, long offset) {
146+
pagingModel = new LimitAndOffsetPagingModel.Builder()
147+
.withLimit(limit)
148+
.withOffset(offset)
149+
.build();
150+
}
151+
152+
@Override
153+
public R build() {
154+
SelectDSL.this.pagingModel = pagingModel;
155+
return SelectDSL.this.build();
156+
}
157+
}
158+
159+
public class OffsetFirstFinisher implements Buildable<R> {
160+
private long offset;
161+
162+
public OffsetFirstFinisher(long offset) {
163+
this.offset = offset;
164+
}
165+
166+
public FetchFirstFinisher fetchFirst(long fetchFirstRows) {
167+
return new FetchFirstFinisher(offset, fetchFirstRows);
168+
}
169+
170+
@Override
171+
public R build() {
172+
SelectDSL.this.pagingModel = new LimitAndOffsetPagingModel.Builder()
173+
.withOffset(offset)
174+
.build();
175+
return SelectDSL.this.build();
176+
}
177+
}
178+
179+
public class FetchFirstFinisher {
180+
private Long offset;
181+
private Long fetchFirstRows;
182+
183+
public FetchFirstFinisher(long fetchFirstRows) {
184+
this.fetchFirstRows = fetchFirstRows;
185+
}
186+
187+
public FetchFirstFinisher(long offset, long fetchFirstRows) {
188+
this.offset = offset;
189+
this.fetchFirstRows = fetchFirstRows;
190+
}
191+
192+
public RowsOnlyFinisher rowsOnly() {
193+
return new RowsOnlyFinisher(offset, fetchFirstRows);
194+
}
195+
}
196+
197+
public class RowsOnlyFinisher implements Buildable<R> {
198+
private Long offset;
199+
private Long fetchFirstRows;
200+
201+
public RowsOnlyFinisher(Long offset, Long fetchFirstRows) {
202+
this.offset = offset;
203+
this.fetchFirstRows = fetchFirstRows;
204+
}
205+
134206
@Override
135207
public R build() {
208+
SelectDSL.this.pagingModel = new FetchFirstPagingModel.Builder()
209+
.withOffset(offset)
210+
.withFetchFirstRows(fetchFirstRows)
211+
.build();
136212
return SelectDSL.this.build();
137213
}
138214
}

0 commit comments

Comments
 (0)