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.caseexpression;
17  
18  import java.util.ArrayList;
19  import java.util.List;
20  import java.util.Optional;
21  import java.util.stream.Stream;
22  
23  import org.jspecify.annotations.Nullable;
24  import org.mybatis.dynamic.sql.BasicColumn;
25  import org.mybatis.dynamic.sql.SortSpecification;
26  import org.mybatis.dynamic.sql.render.RenderingContext;
27  import org.mybatis.dynamic.sql.select.render.SearchedCaseRenderer;
28  import org.mybatis.dynamic.sql.util.FragmentAndParameters;
29  import org.mybatis.dynamic.sql.util.Validator;
30  
31  public class SearchedCaseModel implements BasicColumn, SortSpecification {
32      private final List<SearchedCaseWhenCondition> whenConditions;
33      private final @Nullable BasicColumn elseValue;
34      private final @Nullable String alias;
35      private final String descendingPhrase;
36  
37      private SearchedCaseModel(Builder builder) {
38          whenConditions = builder.whenConditions;
39          alias = builder.alias;
40          elseValue = builder.elseValue;
41          descendingPhrase = builder.descendingPhrase;
42          Validator.assertNotEmpty(whenConditions, "ERROR.40"); //$NON-NLS-1$
43      }
44  
45      public Stream<SearchedCaseWhenCondition> whenConditions() {
46          return whenConditions.stream();
47      }
48  
49      public Optional<BasicColumn> elseValue() {
50          return Optional.ofNullable(elseValue);
51      }
52  
53      @Override
54      public Optional<String> alias() {
55          return Optional.ofNullable(alias);
56      }
57  
58      @Override
59      public SearchedCaseModel as(String alias) {
60          return new Builder().withWhenConditions(whenConditions)
61                  .withElseValue(elseValue)
62                  .withAlias(alias)
63                  .withDescendingPhrase(descendingPhrase)
64                  .build();
65      }
66  
67      @Override
68      public SearchedCaseModel descending() {
69          return new Builder().withWhenConditions(whenConditions)
70                  .withElseValue(elseValue)
71                  .withAlias(alias)
72                  .withDescendingPhrase(" DESC") //$NON-NLS-1$
73                  .build();
74      }
75  
76      @Override
77      public FragmentAndParameters renderForOrderBy(RenderingContext renderingContext) {
78          return render(renderingContext).mapFragment(f -> f + descendingPhrase);
79      }
80  
81      @Override
82      public FragmentAndParameters render(RenderingContext renderingContext) {
83          return new SearchedCaseRenderer(this, renderingContext).render();
84      }
85  
86      public static class Builder {
87          private final List<SearchedCaseWhenCondition> whenConditions = new ArrayList<>();
88          private @Nullable BasicColumn elseValue;
89          private @Nullable String alias;
90          private String descendingPhrase = ""; //$NON-NLS-1$
91  
92          public Builder withWhenConditions(List<SearchedCaseWhenCondition> whenConditions) {
93              this.whenConditions.addAll(whenConditions);
94              return this;
95          }
96  
97          public Builder withElseValue(@Nullable BasicColumn elseValue) {
98              this.elseValue = elseValue;
99              return this;
100         }
101 
102         public Builder withAlias(@Nullable String alias) {
103             this.alias = alias;
104             return this;
105         }
106 
107         public Builder withDescendingPhrase(String descendingPhrase) {
108             this.descendingPhrase = descendingPhrase;
109             return this;
110         }
111 
112         public SearchedCaseModel build() {
113             return new SearchedCaseModel(this);
114         }
115     }
116 }