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