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.statement.SQLUpdateStatement; 17 18 19 import hunt.collection; 20 21 import hunt.sql.SQLUtils; 22 import hunt.sql.ast; 23 import hunt.sql.ast.expr.SQLBinaryOpExpr; 24 import hunt.sql.ast.expr.SQLBinaryOpExprGroup; 25 import hunt.sql.ast.expr.SQLBinaryOperator; 26 import hunt.sql.visitor.SQLASTOutputVisitor; 27 import hunt.sql.visitor.SQLASTVisitor; 28 import hunt.sql.ast.statement.SQLExprTableSource; 29 import hunt.sql.ast.statement.SQLTableSource; 30 import hunt.sql.ast.statement.SQLWithSubqueryClause; 31 import hunt.sql.ast.statement.SQLUpdateSetItem; 32 import hunt.sql.ast.statement.SQLJoinTableSource; 33 import hunt.util.StringBuilder; 34 35 public class SQLUpdateStatement : SQLStatementImpl , SQLReplaceable { 36 protected SQLWithSubqueryClause _with; // for pg 37 38 protected List!SQLUpdateSetItem items; 39 protected SQLExpr where; 40 protected SQLTableSource from; 41 42 protected SQLTableSource tableSource; 43 protected List!SQLExpr returning; 44 45 protected List!SQLHint hints; 46 47 // for mysql 48 protected SQLOrderBy orderBy; 49 50 public this(){ 51 items = new ArrayList!SQLUpdateSetItem(); 52 } 53 54 public this(string dbType){ 55 items = new ArrayList!SQLUpdateSetItem(); 56 super (dbType); 57 } 58 59 public SQLTableSource getTableSource() { 60 return tableSource; 61 } 62 63 public void setTableSource(SQLExpr expr) { 64 this.setTableSource(new SQLExprTableSource(expr)); 65 } 66 67 public void setTableSource(SQLTableSource tableSource) { 68 if (tableSource !is null) { 69 tableSource.setParent(this); 70 } 71 this.tableSource = tableSource; 72 } 73 74 public SQLName getTableName() { 75 if (cast(SQLExprTableSource)(tableSource) !is null ) { 76 return (cast(SQLExprTableSource) tableSource).getName(); 77 } 78 79 if (cast(SQLJoinTableSource)(tableSource) !is null ) { 80 SQLTableSource left = (cast(SQLJoinTableSource) tableSource).getLeft(); 81 if (cast(SQLExprTableSource)(left) !is null ) { 82 return (cast(SQLExprTableSource) left).getName(); 83 } 84 } 85 return null; 86 } 87 88 public SQLExpr getWhere() { 89 return where; 90 } 91 92 public void setWhere(SQLExpr where) { 93 if (where !is null) { 94 where.setParent(this); 95 } 96 this.where = where; 97 } 98 99 public List!SQLUpdateSetItem getItems() { 100 return items; 101 } 102 103 public void addItem(SQLUpdateSetItem item) { 104 this.items.add(item); 105 item.setParent(this); 106 } 107 108 public List!SQLExpr getReturning() { 109 if (returning is null) { 110 returning = new ArrayList!SQLExpr(2); 111 } 112 113 return returning; 114 } 115 116 public SQLTableSource getFrom() { 117 return from; 118 } 119 120 public void setFrom(SQLTableSource from) { 121 if (from !is null) { 122 from.setParent(this); 123 } 124 this.from = from; 125 } 126 127 public int getHintsSize() { 128 if (hints is null) { 129 return 0; 130 } 131 132 return hints.size(); 133 } 134 135 public List!SQLHint getHints() { 136 if (hints is null) { 137 hints = new ArrayList!SQLHint(2); 138 } 139 return hints; 140 } 141 142 public void setHints(List!SQLHint hints) { 143 this.hints = hints; 144 } 145 146 override public void output(StringBuilder buf) { 147 SQLASTOutputVisitor visitor = SQLUtils.createOutputVisitor(buf, dbType); 148 this.accept(visitor); 149 } 150 151 152 override protected void accept0(SQLASTVisitor visitor) { 153 if (visitor.visit(this)) { 154 acceptChild(visitor, tableSource); 155 acceptChild(visitor, from); 156 acceptChild!SQLUpdateSetItem(visitor, items); 157 acceptChild(visitor, where); 158 acceptChild(visitor, orderBy); 159 acceptChild!SQLHint(visitor, hints); 160 } 161 visitor.endVisit(this); 162 } 163 164 override public List!SQLObject getChildren() { 165 List!SQLObject children = new ArrayList!SQLObject(); 166 if (tableSource !is null) { 167 children.add(tableSource); 168 } 169 if (from !is null) { 170 children.add(from); 171 } 172 children.addAll(cast(List!SQLObject)(this.items)); 173 if (where !is null) { 174 children.add(where); 175 } 176 if (orderBy !is null) { 177 children.add(orderBy); 178 } 179 return children; 180 } 181 182 override 183 public bool replace(SQLExpr expr, SQLExpr target) { 184 if (where == expr) { 185 setWhere(target); 186 return true; 187 } 188 return false; 189 } 190 191 192 public SQLOrderBy getOrderBy() { 193 return orderBy; 194 } 195 196 public void setOrderBy(SQLOrderBy orderBy) { 197 if (orderBy !is null) { 198 orderBy.setParent(this); 199 } 200 this.orderBy = orderBy; 201 } 202 203 public SQLWithSubqueryClause getWith() { 204 return _with; 205 } 206 207 public void setWith(SQLWithSubqueryClause _with) { 208 if (_with !is null) { 209 _with.setParent(this); 210 } 211 this._with = _with; 212 } 213 214 public void addCondition(string conditionSql) { 215 if (conditionSql is null || conditionSql.length == 0) { 216 return; 217 } 218 219 SQLExpr condition = SQLUtils.toSQLExpr(conditionSql, dbType); 220 addCondition(condition); 221 } 222 223 public void addCondition(SQLExpr expr) { 224 if (expr is null) { 225 return; 226 } 227 228 this.setWhere(SQLBinaryOpExpr.and(where, expr)); 229 } 230 231 public bool removeCondition(string conditionSql) { 232 if (conditionSql is null || conditionSql.length == 0) { 233 return false; 234 } 235 236 SQLExpr condition = SQLUtils.toSQLExpr(conditionSql, dbType); 237 238 return removeCondition(condition); 239 } 240 241 public bool removeCondition(SQLExpr condition) { 242 if (condition is null) { 243 return false; 244 } 245 246 if (cast(SQLBinaryOpExprGroup)(where) !is null ) { 247 SQLBinaryOpExprGroup group = cast(SQLBinaryOpExprGroup) where; 248 249 int removedCount = 0; 250 List!SQLExpr items = group.getItems(); 251 for (int i = items.size() - 1; i >= 0; i--) { 252 if ((cast(Object)(items.get(i))).opEquals(cast(Object)(condition))) { 253 items.removeAt(i); 254 removedCount++; 255 } 256 } 257 if (items.size() == 0) { 258 where = null; 259 } 260 261 return removedCount > 0; 262 } 263 264 if (cast(SQLBinaryOpExpr)(where) !is null ) { 265 SQLBinaryOpExpr binaryOpWhere = cast(SQLBinaryOpExpr) where; 266 SQLBinaryOperator operator = binaryOpWhere.getOperator(); 267 if (operator == SQLBinaryOperator.BooleanAnd || operator == SQLBinaryOperator.BooleanOr) { 268 List!SQLExpr items = SQLBinaryOpExpr.split(binaryOpWhere); 269 270 int removedCount = 0; 271 for (int i = items.size() - 1; i >= 0; i--) { 272 SQLExpr item = items.get(i); 273 if ((cast(Object)(item)).opEquals(cast(Object)(condition))) { 274 if (SQLUtils.replaceInParent(item, null)) { 275 removedCount++; 276 } 277 } 278 } 279 280 return removedCount > 0; 281 } 282 } 283 284 if ((cast(Object)(condition)).opEquals(cast(Object)(where))) { 285 where = null; 286 return true; 287 } 288 289 return false; 290 } 291 292 override 293 public bool opEquals(Object o) { 294 if (this == o) return true; 295 if (o is null || typeid(this) != typeid(o)) return false; 296 297 SQLUpdateStatement that = cast(SQLUpdateStatement) o; 298 299 if (_with !is null ? !(cast(Object)(_with)).opEquals(cast(Object)(that._with)) : that._with !is null) return false; 300 if (items !is null ? !(cast(Object)(items)).opEquals(cast(Object)(that.items)) : that.items !is null) return false; 301 if (where !is null ? !(cast(Object)(where)).opEquals(cast(Object)(that.where)) : that.where !is null) return false; 302 if (from !is null ? !(cast(Object)(from)).opEquals(cast(Object)(that.from)) : that.from !is null) return false; 303 if (hints !is null ? !(cast(Object)(hints)).opEquals(cast(Object)(that.hints)) : that.hints !is null) return false; 304 if (tableSource !is null ? !(cast(Object)(tableSource)).opEquals(cast(Object)(that.tableSource)) : that.tableSource !is null) return false; 305 if (returning !is null ? !(cast(Object)(returning)).opEquals(cast(Object)(that.returning)) : that.returning !is null) return false; 306 return orderBy !is null ? (cast(Object)(orderBy)).opEquals(cast(Object)(that.orderBy)) : that.orderBy is null; 307 } 308 309 override 310 public size_t toHash() @trusted nothrow { 311 size_t result = _with !is null ? (cast(Object)_with).toHash() : 0; 312 result = 31 * result + (items !is null ? (cast(Object)items).toHash() : 0); 313 result = 31 * result + (where !is null ? (cast(Object)where).toHash() : 0); 314 result = 31 * result + (from !is null ? (cast(Object)from).toHash() : 0); 315 result = 31 * result + (tableSource !is null ? (cast(Object)tableSource).toHash() : 0); 316 result = 31 * result + (returning !is null ? (cast(Object)returning).toHash() : 0); 317 result = 31 * result + (orderBy !is null ? (cast(Object)orderBy).toHash() : 0); 318 result = 31 * result + (hints !is null ? (cast(Object)hints).toHash() : 0); 319 return result; 320 } 321 322 public bool addWhere(SQLExpr where) { 323 if (where is null) { 324 return false; 325 } 326 327 this.addCondition(where); 328 return true; 329 } 330 }