View Javadoc
1   /*
2    *    Copyright 2016-2025 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    *       https://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.render;
17  
18  import org.mybatis.dynamic.sql.exception.InvalidSqlException;
19  import org.mybatis.dynamic.sql.render.RenderedParameterInfo;
20  import org.mybatis.dynamic.sql.render.RenderingContext;
21  import org.mybatis.dynamic.sql.select.PagingModel;
22  import org.mybatis.dynamic.sql.util.FragmentAndParameters;
23  import org.mybatis.dynamic.sql.util.InternalError;
24  import org.mybatis.dynamic.sql.util.Messages;
25  
26  public class FetchFirstPagingModelRenderer {
27      private final RenderingContext renderingContext;
28      private final PagingModel pagingModel;
29  
30      public FetchFirstPagingModelRenderer(RenderingContext renderingContext, PagingModel pagingModel) {
31          this.renderingContext = renderingContext;
32          this.pagingModel = pagingModel;
33      }
34  
35      public FragmentAndParameters render() {
36          return pagingModel.offset()
37                  .map(this::renderWithOffset)
38                  .orElseGet(this::renderFetchFirstRowsOnly);
39      }
40  
41      private FragmentAndParameters renderWithOffset(Long offset) {
42          return pagingModel.fetchFirstRows()
43                  .map(ffr -> renderOffsetAndFetchFirstRows(offset, ffr))
44                  .orElseGet(() -> renderOffsetOnly(offset));
45      }
46  
47      private FragmentAndParameters renderFetchFirstRowsOnly() {
48          return pagingModel.fetchFirstRows().map(this::renderFetchFirstRowsOnly)
49                  .orElseThrow(() ->
50                          new InvalidSqlException(Messages.getInternalErrorString(InternalError.INTERNAL_ERROR_13)));
51      }
52  
53      private FragmentAndParameters renderFetchFirstRowsOnly(Long fetchFirstRows) {
54          RenderedParameterInfo fetchFirstParameterInfo = renderingContext.calculateFetchFirstRowsParameterInfo();
55          return FragmentAndParameters
56                  .withFragment("fetch first " + fetchFirstParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
57                      + " rows only") //$NON-NLS-1$
58                  .withParameter(fetchFirstParameterInfo.parameterMapKey(), fetchFirstRows)
59                  .build();
60      }
61  
62      private FragmentAndParameters renderOffsetOnly(Long offset) {
63          RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo();
64          return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
65                  + " rows") //$NON-NLS-1$
66                  .withParameter(offsetParameterInfo.parameterMapKey(), offset)
67                  .build();
68      }
69  
70      private FragmentAndParameters renderOffsetAndFetchFirstRows(Long offset, Long fetchFirstRows) {
71          RenderedParameterInfo offsetParameterInfo = renderingContext.calculateOffsetParameterInfo();
72          RenderedParameterInfo fetchFirstParameterInfo = renderingContext.calculateFetchFirstRowsParameterInfo();
73          return FragmentAndParameters.withFragment("offset " + offsetParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
74                  + " rows fetch first " + fetchFirstParameterInfo.renderedPlaceHolder() //$NON-NLS-1$
75                  + " rows only") //$NON-NLS-1$
76                  .withParameter(offsetParameterInfo.parameterMapKey(), offset)
77                  .withParameter(fetchFirstParameterInfo.parameterMapKey(), fetchFirstRows)
78                  .build();
79      }
80  }