1 /* 2 * Copyright 2015-2018 HuntLabs.cn 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 module hunt.sql.ast.expr.SQLCaseExpr; 17 18 19 import hunt.sql.SQLUtils; 20 import hunt.sql.ast; 21 import hunt.sql.visitor.SQLASTOutputVisitor; 22 import hunt.sql.visitor.SQLASTVisitor; 23 import hunt.collection; 24 import hunt.util.StringBuilder; 25 26 public class SQLCaseExpr : SQLExprImpl , SQLReplaceable//, Serializable 27 { 28 29 private List!Item items; 30 private SQLExpr valueExpr; 31 private SQLExpr elseExpr; 32 33 public this(){ 34 items = new ArrayList!Item(); 35 } 36 37 public SQLExpr getValueExpr() { 38 return this.valueExpr; 39 } 40 41 public void setValueExpr(SQLExpr valueExpr) { 42 if (valueExpr !is null) { 43 valueExpr.setParent(this); 44 } 45 this.valueExpr = valueExpr; 46 } 47 48 public SQLExpr getElseExpr() { 49 return this.elseExpr; 50 } 51 52 public void setElseExpr(SQLExpr elseExpr) { 53 if (elseExpr !is null) { 54 elseExpr.setParent(this); 55 } 56 this.elseExpr = elseExpr; 57 } 58 59 public List!Item getItems() { 60 return this.items; 61 } 62 63 public void addItem(Item item) { 64 if (item !is null) { 65 item.setParent(this); 66 this.items.add(item); 67 } 68 } 69 70 override protected void accept0(SQLASTVisitor visitor) { 71 if (visitor.visit(this)) { 72 acceptChild(visitor, this.valueExpr); 73 acceptChild!(SQLCaseExpr.Item)(visitor, this.items); 74 acceptChild(visitor, this.elseExpr); 75 } 76 visitor.endVisit(this); 77 } 78 79 override 80 public List!SQLObject getChildren() { 81 List!SQLObject children = new ArrayList!SQLObject(); 82 if (valueExpr !is null) { 83 children.add(this.valueExpr); 84 } 85 children.addAll(cast(List!SQLObject)(this.items)); 86 if (elseExpr !is null) { 87 children.add(this.elseExpr); 88 } 89 return children; 90 } 91 92 override 93 public bool replace(SQLExpr expr, SQLExpr target) { 94 if (valueExpr == expr) { 95 setValueExpr(target); 96 return true; 97 } 98 99 if (elseExpr == expr) { 100 setElseExpr(target); 101 return true; 102 } 103 104 return false; 105 } 106 107 public static class Item : SQLObjectImpl , SQLReplaceable//, Serializable 108 { 109 private SQLExpr conditionExpr; 110 private SQLExpr valueExpr; 111 112 public this(){ 113 114 } 115 116 public this(SQLExpr conditionExpr, SQLExpr valueExpr){ 117 118 setConditionExpr(conditionExpr); 119 setValueExpr(valueExpr); 120 } 121 122 public SQLExpr getConditionExpr() { 123 return this.conditionExpr; 124 } 125 126 public void setConditionExpr(SQLExpr conditionExpr) { 127 if (conditionExpr !is null) { 128 conditionExpr.setParent(this); 129 } 130 this.conditionExpr = conditionExpr; 131 } 132 133 public SQLExpr getValueExpr() { 134 return this.valueExpr; 135 } 136 137 public void setValueExpr(SQLExpr valueExpr) { 138 if (valueExpr !is null) { 139 valueExpr.setParent(this); 140 } 141 this.valueExpr = valueExpr; 142 } 143 144 override protected void accept0(SQLASTVisitor visitor) { 145 if (visitor.visit(this)) { 146 acceptChild(visitor, this.conditionExpr); 147 acceptChild(visitor, this.valueExpr); 148 } 149 visitor.endVisit(this); 150 } 151 152 override 153 public size_t toHash() @trusted nothrow { 154 int prime = 31; 155 size_t result = 1; 156 result = prime * result + ((conditionExpr is null) ? 0 : (cast(Object)conditionExpr).toHash()); 157 result = prime * result + ((valueExpr is null) ? 0 : (cast(Object)valueExpr).toHash()); 158 return result; 159 } 160 161 override 162 public bool opEquals(Object obj) { 163 if (this is obj) return true; 164 if (obj is null) return false; 165 if (typeid(this) != typeid(obj)) return false; 166 Item other = cast(Item) obj; 167 if (conditionExpr is null) { 168 if (other.conditionExpr !is null) return false; 169 } else if (!(cast(Object)(conditionExpr)).opEquals(cast(Object)(other.conditionExpr))) return false; 170 if (valueExpr is null) { 171 if (other.valueExpr !is null) return false; 172 } else if (!(cast(Object)(valueExpr)).opEquals(cast(Object)(other.valueExpr))) return false; 173 return true; 174 } 175 176 177 override public Item clone() { 178 Item x = new Item(); 179 if (conditionExpr !is null) { 180 x.setConditionExpr(conditionExpr.clone()); 181 } 182 if (valueExpr !is null) { 183 x.setValueExpr(valueExpr.clone()); 184 } 185 return x; 186 } 187 188 override public void output(StringBuilder buf) { 189 new SQLASTOutputVisitor(buf).visit(this); 190 } 191 192 override 193 public bool replace(SQLExpr expr, SQLExpr target) { 194 if (valueExpr == expr) { 195 setValueExpr(target); 196 return true; 197 } 198 199 if (conditionExpr == expr) { 200 setConditionExpr(target); 201 return true; 202 } 203 204 return false; 205 } 206 } 207 208 override 209 public size_t toHash() @trusted nothrow { 210 int prime = 31; 211 size_t result = 1; 212 result = prime * result + ((elseExpr is null) ? 0 : (cast(Object)elseExpr).toHash()); 213 result = prime * result + ((items is null) ? 0 : (cast(Object)items).toHash()); 214 result = prime * result + ((valueExpr is null) ? 0 : (cast(Object)valueExpr).toHash()); 215 return result; 216 } 217 218 override 219 public bool opEquals(Object obj) { 220 if (this is obj) { 221 return true; 222 } 223 if (obj is null) { 224 return false; 225 } 226 if (typeid(this) != typeid(obj)) { 227 return false; 228 } 229 SQLCaseExpr other = cast(SQLCaseExpr) obj; 230 if (elseExpr is null) { 231 if (other.elseExpr !is null) { 232 return false; 233 } 234 } else if (!(cast(Object)(elseExpr)).opEquals(cast(Object)(other.elseExpr))) { 235 return false; 236 } 237 if (items is null) { 238 if (other.items !is null) { 239 return false; 240 } 241 } else if (!(cast(Object)(items)).opEquals(cast(Object)(other.items))) { 242 return false; 243 } 244 if (valueExpr is null) { 245 if (other.valueExpr !is null) { 246 return false; 247 } 248 } else if (!(cast(Object)(valueExpr)).opEquals(cast(Object)(other.valueExpr))) { 249 return false; 250 } 251 return true; 252 } 253 254 255 override public SQLCaseExpr clone() { 256 SQLCaseExpr x = new SQLCaseExpr(); 257 258 foreach (Item item ; items) { 259 x.addItem(item.clone()); 260 } 261 262 if (valueExpr !is null) { 263 x.setValueExpr(valueExpr.clone()); 264 } 265 266 if (elseExpr !is null) { 267 x.setElseExpr(elseExpr.clone()); 268 } 269 270 return x; 271 } 272 273 override public SQLDataType computeDataType() { 274 foreach (Item item ; items) { 275 SQLExpr expr = item.getValueExpr(); 276 if (expr !is null) { 277 SQLDataType dataType = expr.computeDataType(); 278 if (dataType !is null) { 279 return dataType; 280 } 281 } 282 } 283 284 if(elseExpr !is null) { 285 return elseExpr.computeDataType(); 286 } 287 288 return null; 289 } 290 291 override public string toString() { 292 return SQLUtils.toSQLString(this, null); 293 } 294 }