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