001/*
002 *  Copyright (c) 2022-2025, 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.FlexConsts;
019import com.mybatisflex.core.dialect.IDialect;
020import com.mybatisflex.core.exception.FlexExceptions;
021import com.mybatisflex.core.util.ArrayUtil;
022import com.mybatisflex.core.util.CollectionUtil;
023
024import java.util.ArrayList;
025import java.util.List;
026
027import static com.mybatisflex.core.constant.SqlConsts.*;
028
029public class With implements CloneSupport<With> {
030
031    private boolean recursive;
032    private List<WithItem> withItems;
033
034    public With() {
035    }
036
037    public With(boolean recursive) {
038        this.recursive = recursive;
039    }
040
041    public boolean isRecursive() {
042        return recursive;
043    }
044
045    public void setRecursive(boolean recursive) {
046        this.recursive = recursive;
047    }
048
049    public List<WithItem> getWithItems() {
050        return withItems;
051    }
052
053    public void setWithItems(List<WithItem> withItems) {
054        this.withItems = withItems;
055    }
056
057    public void addWithItem(WithItem withItem) {
058        if (withItems == null) {
059            withItems = new ArrayList<>();
060        }
061        withItems.add(withItem);
062    }
063
064    public String toSql(IDialect dialect) {
065        StringBuilder sql = new StringBuilder(WITH);
066        if (recursive) {
067            sql.append(RECURSIVE);
068        }
069        for (int i = 0; i < withItems.size(); i++) {
070            sql.append(withItems.get(i).toSql(dialect));
071            if (i != withItems.size() - 1) {
072                sql.append(DELIMITER);
073            }
074        }
075        return sql.append(BLANK).toString();
076    }
077
078    public Object[] getParamValues() {
079        Object[] paramValues = FlexConsts.EMPTY_ARRAY;
080        for (WithItem withItem : withItems) {
081            paramValues = ArrayUtil.concat(paramValues, withItem.getParamValues());
082        }
083        return paramValues;
084    }
085
086    @Override
087    public With clone() {
088        try {
089            With clone = (With) super.clone();
090            // deep clone ...
091            clone.withItems = CollectionUtil.cloneArrayList(this.withItems);
092            return clone;
093        } catch (CloneNotSupportedException e) {
094            throw FlexExceptions.wrap(e);
095        }
096    }
097
098}