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.constant.SqlConsts; 020import com.mybatisflex.core.dialect.IDialect; 021import com.mybatisflex.core.util.ObjectUtil; 022import com.mybatisflex.core.util.StringUtil; 023 024import java.util.List; 025 026/** 027 * 括号 028 */ 029public class Brackets extends QueryCondition { 030 031 private QueryCondition childCondition; 032 033 public Brackets(QueryCondition childCondition) { 034 this.childCondition = childCondition; 035 } 036 037 @Override 038 public QueryColumn getColumn() { 039 return childCondition.getColumn(); 040 } 041 042 @Override 043 public void setColumn(QueryColumn column) { 044 childCondition.setColumn(column); 045 } 046 047 @Override 048 public void setValue(Object value) { 049 childCondition.setValue(value); 050 } 051 052 @Override 053 public String getLogic() { 054 return childCondition.getLogic(); 055 } 056 057 @Override 058 public void setLogic(String logic) { 059 childCondition.setLogic(logic); 060 } 061 062 @Override 063 protected QueryCondition getNextEffectiveCondition() { 064 return childCondition.getNextEffectiveCondition(); 065 } 066 067 @Override 068 public QueryCondition and(QueryCondition nextCondition) { 069 connectToChild(nextCondition, SqlConnector.AND); 070 return this; 071 } 072 073 @Override 074 public QueryCondition or(QueryCondition nextCondition) { 075 connectToChild(nextCondition, SqlConnector.OR); 076 return this; 077 } 078 079 protected void connectToChild(QueryCondition nextCondition, SqlConnector connector) { 080 childCondition.connect(nextCondition, connector); 081 } 082 083 @Override 084 public Object getValue() { 085 return checkEffective() ? WrapperUtil.getValues(childCondition) : null; 086 } 087 088 public QueryCondition getChildCondition() { 089 return childCondition; 090 } 091 092 @Override 093 public boolean checkEffective() { 094 boolean effective = super.checkEffective(); 095 if (!effective) { 096 return false; 097 } 098 QueryCondition condition = this.childCondition; 099 while (condition != null) { 100 if (condition.checkEffective()) { 101 return true; 102 } 103 condition = condition.next; 104 } 105 return false; 106 } 107 108 @Override 109 public String toSql(List<QueryTable> queryTables, IDialect dialect) { 110 111 String sqlNext = next == null ? null : next.toSql(queryTables, dialect); 112 113 StringBuilder sql = new StringBuilder(); 114 if (checkEffective()) { 115 String childSql = childCondition.toSql(queryTables, dialect); 116 if (StringUtil.isNotBlank(childSql)) { 117 QueryCondition prevEffectiveCondition = getPrevEffectiveCondition(); 118 if (prevEffectiveCondition != null && this.connector != null) { 119 childSql = this.connector + SqlConsts.BRACKET_LEFT + childSql + SqlConsts.BRACKET_RIGHT; 120 } else if (StringUtil.isNotBlank(sqlNext)) { 121 childSql = SqlConsts.BRACKET_LEFT + childSql + SqlConsts.BRACKET_RIGHT; 122 } 123 sql.append(childSql); 124 } else { 125 //all child conditions are not effective 126 //fixed gitee #I6W89G 127 this.effective = false; 128 } 129 } 130 131 return sqlNext != null ? sql + sqlNext : sql.toString(); 132 } 133 134 135 @Override 136 boolean containsTable(String... tables) { 137 if (childCondition != null && childCondition.containsTable(tables)) { 138 return true; 139 } 140 return nextContainsTable(tables); 141 } 142 143 @Override 144 public String toString() { 145 return "Brackets{" + 146 "childCondition=" + childCondition + 147 '}'; 148 } 149 150 @Override 151 public Brackets clone() { 152 Brackets clone = (Brackets) super.clone(); 153 // deep clone ... 154 clone.childCondition = ObjectUtil.clone(this.childCondition); 155 return clone; 156 } 157 158}