1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.mybatis.dynamic.sql.common;
17
18 import java.util.ArrayList;
19 import java.util.Arrays;
20 import java.util.List;
21
22 import org.jspecify.annotations.Nullable;
23 import org.mybatis.dynamic.sql.AndOrCriteriaGroup;
24 import org.mybatis.dynamic.sql.BindableColumn;
25 import org.mybatis.dynamic.sql.ColumnAndConditionCriterion;
26 import org.mybatis.dynamic.sql.CriteriaGroup;
27 import org.mybatis.dynamic.sql.ExistsCriterion;
28 import org.mybatis.dynamic.sql.ExistsPredicate;
29 import org.mybatis.dynamic.sql.RenderableCondition;
30 import org.mybatis.dynamic.sql.SqlCriterion;
31 import org.mybatis.dynamic.sql.util.Validator;
32
33 public abstract class AbstractBooleanExpressionDSL<T extends AbstractBooleanExpressionDSL<T>> {
34 private @Nullable SqlCriterion initialCriterion;
35 protected final List<AndOrCriteriaGroup> subCriteria = new ArrayList<>();
36
37 public <S> T and(BindableColumn<S> column, RenderableCondition<S> condition,
38 AndOrCriteriaGroup... subCriteria) {
39 return and(column, condition, Arrays.asList(subCriteria));
40 }
41
42 public <S> T and(BindableColumn<S> column, RenderableCondition<S> condition,
43 List<AndOrCriteriaGroup> subCriteria) {
44 addSubCriteria("and", buildCriterion(column, condition), subCriteria);
45 return getThis();
46 }
47
48 public T and(ExistsPredicate existsPredicate, AndOrCriteriaGroup... subCriteria) {
49 return and(existsPredicate, Arrays.asList(subCriteria));
50 }
51
52 public T and(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCriteria) {
53 addSubCriteria("and", buildCriterion(existsPredicate), subCriteria);
54 return getThis();
55 }
56
57 public T and(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) {
58 return and(initialCriterion, Arrays.asList(subCriteria));
59 }
60
61 public T and(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) {
62 addSubCriteria("and", buildCriterion(initialCriterion), subCriteria);
63 return getThis();
64 }
65
66 public T and(List<AndOrCriteriaGroup> criteria) {
67 addSubCriteria("and", criteria);
68 return getThis();
69 }
70
71 public <S> T or(BindableColumn<S> column, RenderableCondition<S> condition,
72 AndOrCriteriaGroup... subCriteria) {
73 return or(column, condition, Arrays.asList(subCriteria));
74 }
75
76 public <S> T or(BindableColumn<S> column, RenderableCondition<S> condition,
77 List<AndOrCriteriaGroup> subCriteria) {
78 addSubCriteria("or", buildCriterion(column, condition), subCriteria);
79 return getThis();
80 }
81
82 public T or(ExistsPredicate existsPredicate, AndOrCriteriaGroup... subCriteria) {
83 return or(existsPredicate, Arrays.asList(subCriteria));
84 }
85
86 public T or(ExistsPredicate existsPredicate, List<AndOrCriteriaGroup> subCriteria) {
87 addSubCriteria("or", buildCriterion(existsPredicate), subCriteria);
88 return getThis();
89 }
90
91 public T or(SqlCriterion initialCriterion, AndOrCriteriaGroup... subCriteria) {
92 return or(initialCriterion, Arrays.asList(subCriteria));
93 }
94
95 public T or(SqlCriterion initialCriterion, List<AndOrCriteriaGroup> subCriteria) {
96 addSubCriteria("or", buildCriterion(initialCriterion), subCriteria);
97 return getThis();
98 }
99
100 public T or(List<AndOrCriteriaGroup> criteria) {
101 addSubCriteria("or", criteria);
102 return getThis();
103 }
104
105 private <R> SqlCriterion buildCriterion(BindableColumn<R> column, RenderableCondition<R> condition) {
106 return ColumnAndConditionCriterion.withColumn(column).withCondition(condition).build();
107 }
108
109 private SqlCriterion buildCriterion(ExistsPredicate existsPredicate) {
110 return new ExistsCriterion.Builder().withExistsPredicate(existsPredicate).build();
111 }
112
113 private SqlCriterion buildCriterion(SqlCriterion initialCriterion) {
114 return new CriteriaGroup.Builder().withInitialCriterion(initialCriterion).build();
115 }
116
117 private void addSubCriteria(String connector, SqlCriterion initialCriterion,
118 List<AndOrCriteriaGroup> subCriteria) {
119 this.subCriteria.add(new AndOrCriteriaGroup.Builder()
120 .withInitialCriterion(initialCriterion)
121 .withConnector(connector)
122 .withSubCriteria(subCriteria)
123 .build());
124 }
125
126 private void addSubCriteria(String connector, List<AndOrCriteriaGroup> criteria) {
127 this.subCriteria.add(new AndOrCriteriaGroup.Builder()
128 .withConnector(connector)
129 .withSubCriteria(criteria)
130 .build());
131 }
132
133 protected void setInitialCriterion(@Nullable SqlCriterion initialCriterion) {
134 this.initialCriterion = initialCriterion;
135 }
136
137 protected void setInitialCriterion(@Nullable SqlCriterion initialCriterion, StatementType statementType) {
138 Validator.assertTrue(this.initialCriterion == null, statementType.messageNumber());
139 setInitialCriterion(initialCriterion);
140 }
141
142 protected @Nullable SqlCriterion getInitialCriterion() {
143 return initialCriterion;
144 }
145
146 protected abstract T getThis();
147
148 public enum StatementType {
149 WHERE("ERROR.32"),
150 HAVING("ERROR.31");
151
152 private final String messageNumber;
153
154 public String messageNumber() {
155 return messageNumber;
156 }
157
158 StatementType(String messageNumber) {
159 this.messageNumber = messageNumber;
160 }
161 }
162 }