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.dialect.IDialect;
019import com.mybatisflex.core.util.StringUtil;
020
021import java.util.List;
022
023/**
024 * 括号
025 */
026public class Brackets extends QueryCondition {
027
028    private final QueryCondition childCondition;
029
030    public Brackets(QueryCondition childCondition) {
031        this.childCondition = childCondition;
032    }
033
034
035    @Override
036    public QueryCondition and(QueryCondition nextCondition) {
037        connectToChild(nextCondition, SqlConnector.AND);
038        return this;
039    }
040
041    @Override
042    public QueryCondition or(QueryCondition nextCondition) {
043        connectToChild(nextCondition, SqlConnector.OR);
044        return this;
045    }
046
047    protected void connectToChild(QueryCondition nextCondition, SqlConnector connector) {
048        childCondition.connect(nextCondition, connector);
049    }
050
051    @Override
052    public Object getValue() {
053        return checkEffective() ? WrapperUtil.getValues(childCondition) : null;
054    }
055
056    public QueryCondition getChildCondition() {
057        return childCondition;
058    }
059
060    @Override
061    public boolean checkEffective() {
062        boolean effective = super.checkEffective();
063        if (!effective) {
064            return false;
065        }
066        QueryCondition condition = this.childCondition;
067        while (condition != null) {
068            if (condition.checkEffective()) {
069                return true;
070            }
071            condition = condition.next;
072        }
073        return false;
074    }
075
076    @Override
077    public String toSql(List<QueryTable> queryTables, IDialect dialect) {
078
079        String sqlNext = next == null ? null : next.toSql(queryTables, dialect);
080
081        StringBuilder sql = new StringBuilder();
082        if (checkEffective()) {
083            String childSql = childCondition.toSql(queryTables, dialect);
084            if (StringUtil.isNotBlank(childSql)) {
085                QueryCondition effectiveBefore = getEffectiveBefore();
086                if (effectiveBefore != null) {
087                    childSql = effectiveBefore.connector + "(" + childSql + ")";
088                } else if (StringUtil.isNotBlank(sqlNext)) {
089                    childSql = "(" + childSql + ")";
090                }
091                sql.append(childSql);
092            } else {
093                //all child conditions is not effective
094                //fixed gitee #I6W89G
095                this.effective = false;
096            }
097        }
098
099        return sqlNext != null ? sql + sqlNext : sql.toString();
100    }
101
102
103    @Override
104    boolean containsTable(String... tables) {
105        return childCondition != null && childCondition.containsTable(tables);
106    }
107
108    @Override
109    public String toString() {
110        return "Brackets{" +
111                "childCondition=" + childCondition +
112                '}';
113    }
114}