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.builder.impl.SQLUpdateBuilderImpl; 17 18 import hunt.collection; 19 20 import hunt.sql.SQLUtils; 21 import hunt.sql.ast.SQLExpr; 22 import hunt.sql.ast.SQLStatement; 23 import hunt.sql.ast.expr.SQLBinaryOperator; 24 import hunt.sql.ast.expr.SQLIdentifierExpr; 25 import hunt.sql.ast.statement.SQLExprTableSource; 26 import hunt.sql.ast.statement.SQLUpdateSetItem; 27 import hunt.sql.ast.statement.SQLUpdateStatement; 28 import hunt.sql.builder.SQLUpdateBuilder; 29 import hunt.sql.dialect.mysql.ast.statement.MySqlUpdateStatement; 30 // import hunt.sql.dialect.oracle.ast.stmt.OracleUpdateStatement; 31 import hunt.sql.dialect.postgresql.ast.stmt.PGUpdateStatement; 32 // import hunt.sql.dialect.sqlserver.ast.stmt.SQLServerUpdateStatement; 33 import hunt.sql.util.DBType; 34 import hunt.sql.builder.impl.SQLBuilderImpl; 35 import hunt.sql.builder.SQLBuilder; 36 import hunt.sql.ast.expr.SQLBlobExpr; 37 import hunt.sql.ast.expr.SQLBooleanExpr; 38 import hunt.sql.ast.expr.SQLCharExpr; 39 import hunt.sql.ast.expr.SQLIntegerExpr; 40 import hunt.sql.ast.expr.SQLNullExpr; 41 import hunt.sql.ast.expr.SQLNumberExpr; 42 43 import hunt.Double; 44 import hunt.Exceptions; 45 import hunt.Float; 46 import hunt.Boolean; 47 import hunt.Integer; 48 import hunt.Long; 49 import hunt.Number; 50 import hunt.String; 51 import hunt.logging; 52 import hunt.Nullable; 53 54 import std.variant; 55 56 class SQLUpdateBuilderImpl : SQLUpdateBuilder { 57 58 private SQLUpdateStatement stmt; 59 private string dbType; 60 61 this(string dbType){ 62 this.dbType = dbType; 63 } 64 65 this(string sql, string dbType){ 66 List!SQLStatement stmtList = SQLUtils.parseStatements(sql, dbType); 67 68 if (stmtList.size() == 0) { 69 throw new Exception("not support empty-statement :" ~ sql); 70 } 71 72 if (stmtList.size() > 1) { 73 throw new Exception("not support multi-statement :" ~ sql); 74 } 75 76 SQLUpdateStatement stmt = cast(SQLUpdateStatement) stmtList.get(0); 77 this.stmt = stmt; 78 this.dbType = dbType; 79 } 80 81 static SQLExpr toSQLExpr(Variant obj, string dbType) { 82 // logDebug("set : ",obj.toString); 83 if (!obj.hasValue() || obj == null) { 84 return new SQLNullExpr(); 85 } 86 87 TypeInfo typeInfo = obj.type; 88 89 if (typeInfo == typeid(int)) { 90 return new SQLIntegerExpr(cast(long)obj.get!int()); 91 } 92 93 if (typeInfo == typeid(uint)) { 94 return new SQLIntegerExpr(cast(long)obj.get!uint()); 95 } 96 97 if (typeInfo == typeid(short)) { 98 return new SQLIntegerExpr(cast(long)obj.get!short()); 99 } 100 101 if (typeInfo == typeid(ushort)) { 102 return new SQLIntegerExpr(cast(long)obj.get!ushort()); 103 } 104 105 if (typeInfo == typeid(long)) { 106 return new SQLIntegerExpr(cast(long)obj.get!long()); 107 } 108 109 if (typeInfo == typeid(ulong)) { 110 return new SQLIntegerExpr(cast(long)obj.get!ulong()); 111 } 112 113 if (typeInfo == typeid(double)) { 114 Double db = new Double(obj.get!double()); 115 return new SQLNumberExpr(db); 116 } 117 118 if (typeInfo == typeid(float)) { 119 Float db = new Float(obj.get!float()); 120 return new SQLNumberExpr(db); 121 } 122 123 if (typeInfo == typeid(bool)) { 124 return new SQLBooleanExpr(obj.get!bool()); 125 } 126 127 if (typeInfo == typeid(string)) { 128 return new SQLCharExpr(obj.get!string()); 129 } 130 131 if(typeInfo == typeid(ubyte[])) { 132 ubyte[] data = obj.get!(ubyte[])(); 133 return new SQLBlobExpr(data); 134 } 135 136 137 // if (cast(Integer)(obj) !is null) { 138 // return new SQLIntegerExpr(cast(Integer) obj); 139 // } 140 141 // if (cast(Long)(obj) !is null) { 142 // return new SQLIntegerExpr(cast(int)(cast(Long) obj).longValue); 143 // } 144 145 // if (cast(Float)(obj) !is null) { 146 // return new SQLNumberExpr(cast(Float)obj); 147 // } 148 149 // if (cast(Double)(obj) !is null) { 150 // Number nm = cast(Number)obj; 151 // return new SQLNumberExpr(nm); 152 // } 153 154 // if (cast(Number)(obj) !is null) { 155 // return new SQLNumberExpr(cast(Number) obj); 156 // } 157 158 // if (cast(String)(obj) !is null) { 159 // return new SQLCharExpr(cast(String) obj); 160 // } 161 162 // if (cast(Boolean)(obj) !is null) { 163 // return new SQLBooleanExpr((cast(Boolean) obj).booleanValue); 164 // } 165 166 throw new IllegalArgumentException("unsupported : " ~ obj.type.toString()); 167 } 168 169 this(SQLUpdateStatement stmt, string dbType){ 170 this.stmt = stmt; 171 this.dbType = dbType; 172 } 173 174 override 175 SQLBuilder limit(int rowCount) { 176 throw new Exception("not implement"); 177 } 178 179 override 180 SQLBuilder limit(int rowCount, int offset) { 181 throw new Exception("not implement"); 182 } 183 184 override 185 SQLBuilder from(string table) { 186 return from(table, null); 187 } 188 189 override 190 SQLBuilder from(string table, string _alias) { 191 SQLUpdateStatement update = getSQLUpdateStatement(); 192 SQLExprTableSource from = new SQLExprTableSource(new SQLIdentifierExpr(table), _alias); 193 update.setTableSource(from); 194 return this; 195 } 196 197 override 198 SQLBuilder where(string expr) { 199 SQLUpdateStatement update = getSQLUpdateStatement(); 200 201 SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType); 202 update.setWhere(exprObj); 203 204 return this; 205 } 206 207 override 208 SQLBuilder whereAnd(string expr) { 209 SQLUpdateStatement update = getSQLUpdateStatement(); 210 211 SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType); 212 SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanAnd, exprObj, false, update.getWhere()); 213 update.setWhere(newCondition); 214 215 return this; 216 } 217 218 override 219 SQLBuilder whereOr(string expr) { 220 SQLUpdateStatement update = getSQLUpdateStatement(); 221 222 SQLExpr exprObj = SQLUtils.toSQLExpr(expr, dbType); 223 SQLExpr newCondition = SQLUtils.buildCondition(SQLBinaryOperator.BooleanOr, exprObj, false, update.getWhere()); 224 update.setWhere(newCondition); 225 226 return this; 227 } 228 229 override 230 SQLUpdateBuilder set(string[] items...) { 231 SQLUpdateStatement update = getSQLUpdateStatement(); 232 foreach (string item ; items) { 233 SQLUpdateSetItem updateSetItem = SQLUtils.toUpdateSetItem(item, dbType); 234 update.addItem(updateSetItem); 235 } 236 237 return this; 238 } 239 240 SQLUpdateBuilderImpl setValue(Map!(string, Variant) values) { 241 foreach (string k, Variant v ; values) { 242 setValue(k, v); 243 } 244 245 return this; 246 } 247 248 SQLUpdateBuilderImpl setValue(string column, Variant value) { 249 SQLUpdateStatement update = getSQLUpdateStatement(); 250 251 SQLExpr columnExpr = SQLUtils.toSQLExpr(column, dbType); 252 SQLExpr valueExpr = toSQLExpr(value, dbType); 253 254 SQLUpdateSetItem item = new SQLUpdateSetItem(); 255 item.setColumn(columnExpr); 256 item.setValue(valueExpr); 257 update.addItem(item); 258 259 return this; 260 } 261 262 SQLUpdateStatement getSQLUpdateStatement() { 263 if (stmt is null) { 264 stmt = createSQLUpdateStatement(); 265 } 266 return stmt; 267 } 268 269 SQLUpdateStatement createSQLUpdateStatement() { 270 if (DBType.MYSQL.name == dbType) { 271 return new MySqlUpdateStatement(); 272 } 273 274 // if (DBType.ORACLE.name == dbType) { 275 // return new OracleUpdateStatement(); 276 // } 277 278 if (DBType.POSTGRESQL.name == dbType) { 279 return new PGUpdateStatement(); 280 } 281 282 // if (DBType.SQL_SERVER.name == dbType) { 283 // return new SQLServerUpdateStatement(); 284 // } 285 286 return new SQLUpdateStatement(); 287 } 288 289 override string toString() { 290 return SQLUtils.toSQLString(stmt, dbType); 291 } 292 293 string toString(FormatOption option) { 294 return SQLUtils.toSQLString(stmt, dbType, option); 295 } 296 }