001/*
002 *  Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.query;
017
018import com.mybatisflex.core.constant.SqlConnector;
019import com.mybatisflex.core.exception.FlexExceptions;
020import com.mybatisflex.core.util.CollectionUtil;
021import com.mybatisflex.core.util.ObjectUtil;
022
023import java.util.*;
024
025@SuppressWarnings({"unchecked", "unused"})
026public class BaseQueryWrapper<T extends BaseQueryWrapper<T>> implements CloneSupport<T> {
027
028
029    protected With with;
030    protected List<QueryTable> queryTables;
031    protected String dataSource;
032    protected String hint;
033
034    protected List<QueryColumn> selectColumns;
035    protected List<Join> joins;
036    protected List<QueryTable> joinTables;
037    protected QueryCondition whereQueryCondition;
038    protected List<QueryColumn> groupByColumns;
039    protected QueryCondition havingQueryCondition;
040    protected List<QueryOrderBy> orderBys;
041
042    protected List<UnionWrapper> unions;
043
044    protected Long limitOffset;
045    protected Long limitRows;
046
047    protected List<String> endFragments;
048
049    protected Map<String, Object> context;
050
051//    protected boolean ignoreBlankStrings = false;
052
053    /**
054     * <p>Title: clear. </p>
055     * <p>Description: Default QueryWrapper values. </p>
056     * <p>Notice: When adding new attributes, it is necessary to supplement here. </p>
057     *
058     * @author dragon
059     */
060    public void clear() {
061        this.with = null;
062        this.queryTables = null;
063        this.dataSource = null;
064        this.hint = null;
065        this.selectColumns = null;
066        this.joins = null;
067        this.joinTables = null;
068        this.whereQueryCondition = null;
069        this.groupByColumns = null;
070        this.havingQueryCondition = null;
071        this.orderBys = null;
072        this.unions = null;
073        this.limitOffset = null;
074        this.limitRows = null;
075        this.endFragments = null;
076        this.context = null;
077    }
078
079    protected T addSelectColumn(QueryColumn queryColumn) {
080        if (selectColumns == null) {
081            selectColumns = new ArrayList<>();
082        }
083
084        selectColumns.add(queryColumn);
085        return (T) this;
086    }
087
088
089    protected T addJoin(Join join) {
090        if (joins == null) {
091            joins = new ArrayList<>();
092        }
093        joins.add(join);
094        return (T) this;
095    }
096
097
098    protected T setWhereQueryCondition(QueryCondition queryCondition) {
099        if (queryCondition != null) {
100            if (whereQueryCondition != null) {
101                queryCondition.connect(whereQueryCondition, SqlConnector.AND);
102            }
103            whereQueryCondition = queryCondition;
104        }
105        return (T) this;
106    }
107
108
109    protected T addWhereQueryCondition(QueryCondition queryCondition, SqlConnector connector) {
110        if (queryCondition != null) {
111            if (whereQueryCondition == null) {
112                whereQueryCondition = queryCondition;
113            } else {
114                whereQueryCondition.connect(queryCondition, connector);
115            }
116        }
117        return (T) this;
118    }
119
120
121    protected T addGroupByColumns(QueryColumn queryColumn) {
122        if (groupByColumns == null) {
123            groupByColumns = new ArrayList<>();
124        }
125        groupByColumns.add(queryColumn);
126        return (T) this;
127    }
128
129
130    protected T addHavingQueryCondition(QueryCondition queryCondition, SqlConnector connector) {
131        if (havingQueryCondition == null) {
132            havingQueryCondition = queryCondition;
133        } else {
134            havingQueryCondition.connect(queryCondition, connector);
135        }
136        return (T) this;
137    }
138
139
140    protected T addOrderBy(QueryOrderBy queryOrderBy) {
141        if (orderBys == null) {
142            orderBys = new LinkedList<>();
143        }
144        orderBys.add(queryOrderBy);
145        return (T) this;
146    }
147
148
149    protected void addJoinTable(QueryTable queryTable) {
150        if (joinTables == null) {
151            joinTables = new ArrayList<>();
152        }
153        joinTables.add(queryTable);
154    }
155
156    protected void addEndFragment(String fragment) {
157        if (endFragments == null) {
158            endFragments = new ArrayList<>();
159        }
160        endFragments.add(fragment);
161    }
162
163
164    protected List<QueryTable> getQueryTables() {
165        return queryTables;
166    }
167
168    protected void setQueryTables(List<QueryTable> queryTables) {
169        this.queryTables = queryTables;
170    }
171
172    protected String getDataSource() {
173        return dataSource;
174    }
175
176    protected void setDataSource(String dataSource) {
177        this.dataSource = dataSource;
178    }
179
180    protected String getHint() {
181        return hint;
182    }
183
184    protected void setHint(String hint) {
185        this.hint = hint;
186    }
187
188    protected List<QueryColumn> getSelectColumns() {
189        return selectColumns;
190    }
191
192    protected void setSelectColumns(List<QueryColumn> selectColumns) {
193        this.selectColumns = selectColumns;
194    }
195
196    protected List<Join> getJoins() {
197        return joins;
198    }
199
200    protected void setJoins(List<Join> joins) {
201        this.joins = joins;
202    }
203
204    protected List<QueryTable> getJoinTables() {
205        return joinTables;
206    }
207
208    protected void setJoinTables(List<QueryTable> joinTables) {
209        this.joinTables = joinTables;
210    }
211
212    protected QueryCondition getWhereQueryCondition() {
213        return whereQueryCondition;
214    }
215
216    protected List<QueryColumn> getGroupByColumns() {
217        return groupByColumns;
218    }
219
220    protected void setGroupByColumns(List<QueryColumn> groupByColumns) {
221        this.groupByColumns = groupByColumns;
222    }
223
224    protected QueryCondition getHavingQueryCondition() {
225        return havingQueryCondition;
226    }
227
228    protected void setHavingQueryCondition(QueryCondition havingQueryCondition) {
229        this.havingQueryCondition = havingQueryCondition;
230    }
231
232    protected List<QueryOrderBy> getOrderBys() {
233        return orderBys;
234    }
235
236    protected void setOrderBys(List<QueryOrderBy> orderBys) {
237        this.orderBys = orderBys;
238    }
239
240    protected List<UnionWrapper> getUnions() {
241        return unions;
242    }
243
244    protected void setUnions(List<UnionWrapper> unions) {
245        this.unions = unions;
246    }
247
248    protected Long getLimitOffset() {
249        return limitOffset;
250    }
251
252    protected void setLimitOffset(Long limitOffset) {
253        this.limitOffset = limitOffset;
254    }
255
256    protected Long getLimitRows() {
257        return limitRows;
258    }
259
260    protected void setLimitRows(Long limitRows) {
261        this.limitRows = limitRows;
262    }
263
264    protected List<String> getEndFragments() {
265        return endFragments;
266    }
267
268    protected void setEndFragments(List<String> endFragments) {
269        this.endFragments = endFragments;
270    }
271
272    protected Map<String, Object> getContext() {
273        return context;
274    }
275
276    protected void setContext(Map<String, Object> context) {
277        this.context = context;
278    }
279
280    protected void putContext(String key, Object value) {
281        if (context == null) {
282            context = new HashMap<>();
283        }
284        context.put(key, value);
285    }
286
287    protected <R> R getContext(String key) {
288        return context == null ? null : (R) context.get(key);
289    }
290
291    @Override
292    public T clone() {
293        try {
294            T clone = (T) super.clone();
295            // deep clone ...
296            clone.with = ObjectUtil.clone(this.with);
297            clone.queryTables = CollectionUtil.cloneArrayList(this.queryTables);
298            clone.selectColumns = CollectionUtil.cloneArrayList(this.selectColumns);
299            clone.joins = CollectionUtil.cloneArrayList(this.joins);
300            clone.joinTables = CollectionUtil.cloneArrayList(this.joinTables);
301            clone.whereQueryCondition = ObjectUtil.clone(this.whereQueryCondition);
302            clone.groupByColumns = CollectionUtil.cloneArrayList(this.groupByColumns);
303            clone.havingQueryCondition = ObjectUtil.clone(this.havingQueryCondition);
304            clone.orderBys = CollectionUtil.cloneArrayList(this.orderBys);
305            clone.unions = CollectionUtil.cloneArrayList(this.unions);
306            // copy List if necessary ...
307            if (this.endFragments != null) {
308                clone.endFragments = CollectionUtil.newArrayList(this.endFragments);
309            }
310            // copy Map if necessary ...
311            if (this.context != null) {
312                clone.context = CollectionUtil.newHashMap(this.context);
313            }
314            return clone;
315        } catch (CloneNotSupportedException e) {
316            throw FlexExceptions.wrap(e);
317        }
318    }
319
320}