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