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     * @author dragon
058     */
059    public void clear() {
060        this.with = null;
061        this.queryTables = null;
062        this.dataSource = null;
063        this.hint = null;
064        this.selectColumns = null;
065        this.joins = null;
066        this.joinTables = null;
067        this.whereQueryCondition = null;
068        this.groupByColumns = null;
069        this.havingQueryCondition = null;
070        this.orderBys = null;
071        this.unions = null;
072        this.limitOffset = null;
073        this.limitRows = null;
074        this.endFragments = null;
075        this.context = null;
076    }
077
078    protected T addSelectColumn(QueryColumn queryColumn) {
079        if (selectColumns == null) {
080            selectColumns = new ArrayList<>();
081        }
082
083        selectColumns.add(queryColumn);
084        return (T) this;
085    }
086
087
088    protected T addJoin(Join join) {
089        if (joins == null) {
090            joins = new ArrayList<>();
091        }
092        joins.add(join);
093        return (T) this;
094    }
095
096
097    protected T setWhereQueryCondition(QueryCondition queryCondition) {
098        if (whereQueryCondition != null) {
099            queryCondition.connect(whereQueryCondition, SqlConnector.AND);
100        }
101
102        whereQueryCondition = queryCondition;
103        return (T) this;
104    }
105
106
107    protected T addWhereQueryCondition(QueryCondition queryCondition, SqlConnector connector) {
108        if (queryCondition != null) {
109            if (whereQueryCondition == null) {
110                whereQueryCondition = queryCondition;
111            } else {
112                whereQueryCondition.connect(queryCondition, connector);
113            }
114        }
115        return (T) this;
116    }
117
118
119    protected T addGroupByColumns(QueryColumn queryColumn) {
120        if (groupByColumns == null) {
121            groupByColumns = new ArrayList<>();
122        }
123
124        groupByColumns.add(queryColumn);
125        return (T) this;
126    }
127
128
129    protected T addHavingQueryCondition(QueryCondition queryCondition, SqlConnector connector) {
130        if (havingQueryCondition == null) {
131            havingQueryCondition = queryCondition;
132        } else {
133            havingQueryCondition.connect(queryCondition, connector);
134        }
135        return (T) this;
136    }
137
138
139    protected T addOrderBy(QueryOrderBy queryOrderBy) {
140        if (orderBys == null) {
141            orderBys = new LinkedList<>();
142        }
143        orderBys.add(queryOrderBy);
144        return (T) this;
145    }
146
147
148    protected void addJoinTable(QueryTable queryTable) {
149        if (joinTables == null) {
150            joinTables = new ArrayList<>();
151        }
152        joinTables.add(queryTable);
153    }
154
155    protected void addEndFragment(String fragment) {
156        if (endFragments == null) {
157            endFragments = new ArrayList<>();
158        }
159        endFragments.add(fragment);
160    }
161
162
163    protected List<QueryTable> getQueryTables() {
164        return queryTables;
165    }
166
167    protected void setQueryTables(List<QueryTable> queryTables) {
168        this.queryTables = queryTables;
169    }
170
171    protected String getDataSource() {
172        return dataSource;
173    }
174
175    protected void setDataSource(String dataSource) {
176        this.dataSource = dataSource;
177    }
178
179    protected String getHint() {
180        return hint;
181    }
182
183    protected void setHint(String hint) {
184        this.hint = hint;
185    }
186
187    protected List<QueryColumn> getSelectColumns() {
188        return selectColumns;
189    }
190
191    protected void setSelectColumns(List<QueryColumn> selectColumns) {
192        this.selectColumns = selectColumns;
193    }
194
195    protected List<Join> getJoins() {
196        return joins;
197    }
198
199    protected void setJoins(List<Join> joins) {
200        this.joins = joins;
201    }
202
203    protected List<QueryTable> getJoinTables() {
204        return joinTables;
205    }
206
207    protected void setJoinTables(List<QueryTable> joinTables) {
208        this.joinTables = joinTables;
209    }
210
211    protected QueryCondition getWhereQueryCondition() {
212        return whereQueryCondition;
213    }
214
215    protected List<QueryColumn> getGroupByColumns() {
216        return groupByColumns;
217    }
218
219    protected void setGroupByColumns(List<QueryColumn> groupByColumns) {
220        this.groupByColumns = groupByColumns;
221    }
222
223    protected QueryCondition getHavingQueryCondition() {
224        return havingQueryCondition;
225    }
226
227    protected void setHavingQueryCondition(QueryCondition havingQueryCondition) {
228        this.havingQueryCondition = havingQueryCondition;
229    }
230
231    protected List<QueryOrderBy> getOrderBys() {
232        return orderBys;
233    }
234
235    protected void setOrderBys(List<QueryOrderBy> orderBys) {
236        this.orderBys = orderBys;
237    }
238
239    protected List<UnionWrapper> getUnions() {
240        return unions;
241    }
242
243    protected void setUnions(List<UnionWrapper> unions) {
244        this.unions = unions;
245    }
246
247    protected Long getLimitOffset() {
248        return limitOffset;
249    }
250
251    protected void setLimitOffset(Long limitOffset) {
252        this.limitOffset = limitOffset;
253    }
254
255    protected Long getLimitRows() {
256        return limitRows;
257    }
258
259    protected void setLimitRows(Long limitRows) {
260        this.limitRows = limitRows;
261    }
262
263    protected List<String> getEndFragments() {
264        return endFragments;
265    }
266
267    protected void setEndFragments(List<String> endFragments) {
268        this.endFragments = endFragments;
269    }
270
271    protected Map<String, Object> getContext() {
272        return context;
273    }
274
275    protected void setContext(Map<String, Object> context) {
276        this.context = context;
277    }
278
279    protected void putContext(String key, Object value) {
280        if (context == null) {
281            context = new HashMap<>();
282        }
283        context.put(key, value);
284    }
285
286    protected <R> R getContext(String key) {
287        return context == null ? null : (R) context.get(key);
288    }
289
290    @Override
291    public T clone() {
292        try {
293            T clone = (T) super.clone();
294            // deep clone ...
295            clone.with = ObjectUtil.clone(this.with);
296            clone.queryTables = CollectionUtil.cloneArrayList(this.queryTables);
297            clone.selectColumns = CollectionUtil.cloneArrayList(this.selectColumns);
298            clone.joins = CollectionUtil.cloneArrayList(this.joins);
299            clone.joinTables = CollectionUtil.cloneArrayList(this.joinTables);
300            clone.whereQueryCondition = ObjectUtil.clone(this.whereQueryCondition);
301            clone.groupByColumns = CollectionUtil.cloneArrayList(this.groupByColumns);
302            clone.havingQueryCondition = ObjectUtil.clone(this.havingQueryCondition);
303            clone.orderBys = CollectionUtil.cloneArrayList(this.orderBys);
304            clone.unions = CollectionUtil.cloneArrayList(this.unions);
305            // copy List if necessary ...
306            if (this.endFragments != null) {
307                clone.endFragments = CollectionUtil.newArrayList(this.endFragments);
308            }
309            // copy Map if necessary ...
310            if (this.context != null) {
311                clone.context = CollectionUtil.newHashMap(this.context);
312            }
313            return clone;
314        } catch (CloneNotSupportedException e) {
315            throw FlexExceptions.wrap(e);
316        }
317    }
318
319}