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.SQLColumnDefinition; 17 18 import hunt.collection; 19 20 import hunt.sql.SQLUtils; 21 import hunt.sql.ast; 22 import hunt.sql.ast.expr.SQLCharExpr; 23 import hunt.sql.ast.expr.SQLIdentifierExpr; 24 import hunt.sql.ast.expr.SQLPropertyExpr; 25 import hunt.sql.visitor.SQLASTVisitor; 26 import hunt.sql.util.DBType; 27 import hunt.sql.ast.statement.SQLTableElement; 28 import hunt.sql.ast.statement.SQLColumnConstraint; 29 import hunt.Boolean; 30 import hunt.Integer; 31 32 import hunt.sql.ast.statement.SQLNotNullConstraint; 33 import hunt.sql.ast.statement.SQLColumnPrimaryKey; 34 import hunt.sql.ast.statement.SQLCreateTableStatement; 35 import hunt.util.StringBuilder; 36 37 public class SQLColumnDefinition : SQLObjectImpl , SQLTableElement, SQLObjectWithDataType, SQLReplaceable { 38 protected string dbType; 39 40 protected SQLName name; 41 protected SQLDataType dataType; 42 protected SQLExpr defaultExpr; 43 protected List!SQLColumnConstraint constraints; 44 protected SQLExpr comment; 45 46 protected Boolean enable; 47 protected Boolean validate; 48 protected Boolean rely; 49 50 // for mysql 51 protected bool autoIncrement = false; 52 protected SQLExpr onUpdate; 53 protected SQLExpr storage; 54 protected SQLExpr charsetExpr; 55 protected SQLExpr asExpr; 56 protected bool sorted = false; 57 protected bool virtual = false; 58 59 protected Identity identity; 60 protected SQLExpr generatedAlawsAs; 61 62 public this(){ 63 constraints = new ArrayList!SQLColumnConstraint(0); 64 } 65 66 public Identity getIdentity() { 67 return identity; 68 } 69 70 // for sqlserver 71 public void setIdentity(Identity x) { 72 if (x !is null) { 73 x.setParent(this); 74 } 75 this.identity = x; 76 } 77 78 public SQLExpr getGeneratedAlawsAs() { 79 return generatedAlawsAs; 80 } 81 82 public void setGeneratedAlawsAs(SQLExpr x) { 83 if (x !is null) { 84 x.setParent(this); 85 } 86 this.generatedAlawsAs = x; 87 } 88 89 public Boolean getEnable() { 90 return enable; 91 } 92 93 public void setEnable(Boolean enable) { 94 this.enable = enable; 95 } 96 97 public Boolean getValidate() { 98 return validate; 99 } 100 101 public void setValidate(Boolean validate) { 102 this.validate = validate; 103 } 104 105 public Boolean getRely() { 106 return rely; 107 } 108 109 public void setRely(Boolean rely) { 110 this.rely = rely; 111 } 112 113 public SQLName getName() { 114 return name; 115 } 116 117 public long nameHashCode64() { 118 if (name is null) { 119 return 0; 120 } 121 122 return name.hashCode64(); 123 } 124 125 public string getNameAsString() { 126 if (name is null) { 127 return null; 128 } 129 130 return (cast(Object)(name)).toString(); 131 } 132 133 public void setName(SQLName name) { 134 this.name = name; 135 } 136 137 public void setName(string name) { 138 this.setName(new SQLIdentifierExpr(name)); 139 } 140 141 public SQLDataType getDataType() { 142 return dataType; 143 } 144 145 public void setDataType(SQLDataType dataType) { 146 if (dataType !is null) { 147 dataType.setParent(this); 148 } 149 this.dataType = dataType; 150 } 151 152 public SQLExpr getDefaultExpr() { 153 return defaultExpr; 154 } 155 156 public void setDefaultExpr(SQLExpr defaultExpr) { 157 if (defaultExpr !is null) { 158 defaultExpr.setParent(this); 159 } 160 this.defaultExpr = defaultExpr; 161 } 162 163 public List!SQLColumnConstraint getConstraints() { 164 return constraints; 165 } 166 167 public void addConstraint(SQLColumnConstraint constraint) { 168 if (constraint !is null) { 169 constraint.setParent(this); 170 } 171 this.constraints.add(constraint); 172 } 173 174 override public void output(StringBuilder buf) { 175 name.output(buf); 176 buf.append(' '); 177 this.dataType.output(buf); 178 if (defaultExpr !is null) { 179 buf.append(" DEFAULT "); 180 this.defaultExpr.output(buf); 181 } 182 } 183 184 185 override protected void accept0(SQLASTVisitor visitor) { 186 if (visitor.visit(this)) { 187 this.acceptChild(visitor, name); 188 this.acceptChild(visitor, dataType); 189 this.acceptChild(visitor, defaultExpr); 190 this.acceptChild!SQLColumnConstraint(visitor, constraints); 191 } 192 visitor.endVisit(this); 193 } 194 195 public SQLExpr getComment() { 196 return comment; 197 } 198 199 public void setComment(string comment) { 200 this.setComment(new SQLCharExpr(comment)); 201 } 202 203 public void setComment(SQLExpr comment) { 204 if (comment !is null) { 205 comment.setParent(this); 206 } 207 this.comment = comment; 208 } 209 210 public bool isVirtual() { 211 return virtual; 212 } 213 214 public void setVirtual(bool virtual) { 215 this.virtual = virtual; 216 } 217 218 public bool isSorted() { 219 return sorted; 220 } 221 222 public void setSorted(bool sorted) { 223 this.sorted = sorted; 224 } 225 226 public SQLExpr getCharsetExpr() { 227 return charsetExpr; 228 } 229 230 public void setCharsetExpr(SQLExpr charsetExpr) { 231 if (charsetExpr !is null) { 232 charsetExpr.setParent(this); 233 } 234 this.charsetExpr = charsetExpr; 235 } 236 237 public SQLExpr getAsExpr() { 238 return asExpr; 239 } 240 241 public void setAsExpr(SQLExpr asExpr) { 242 if (charsetExpr !is null) { 243 charsetExpr.setParent(this); 244 } 245 this.asExpr = asExpr; 246 } 247 248 public bool isAutoIncrement() { 249 return autoIncrement; 250 } 251 252 public void setAutoIncrement(bool autoIncrement) { 253 this.autoIncrement = autoIncrement; 254 } 255 256 public SQLExpr getOnUpdate() { 257 return onUpdate; 258 } 259 260 public void setOnUpdate(SQLExpr onUpdate) { 261 this.onUpdate = onUpdate; 262 } 263 264 public SQLExpr getStorage() { 265 return storage; 266 } 267 268 public void setStorage(SQLExpr storage) { 269 this.storage = storage; 270 } 271 272 override 273 public bool replace(SQLExpr expr, SQLExpr target) { 274 if (defaultExpr == expr) { 275 setDefaultExpr(target); 276 return true; 277 } 278 279 if (name == expr) { 280 setName(cast(SQLName) target); 281 return true; 282 } 283 284 return false; 285 } 286 287 public static class Identity : SQLObjectImpl { 288 289 private Integer seed; 290 private Integer increment; 291 292 private bool notForReplication; 293 294 public this(){ 295 296 } 297 298 public Integer getSeed() { 299 return seed; 300 } 301 302 public void setSeed(Integer seed) { 303 this.seed = seed; 304 } 305 306 public Integer getIncrement() { 307 return increment; 308 } 309 310 public void setIncrement(Integer increment) { 311 this.increment = increment; 312 } 313 314 public bool isNotForReplication() { 315 return notForReplication; 316 } 317 318 public void setNotForReplication(bool notForReplication) { 319 this.notForReplication = notForReplication; 320 } 321 322 override 323 public void accept0(SQLASTVisitor visitor) { 324 visitor.visit(this); 325 visitor.endVisit(this); 326 } 327 328 override public Identity clone () { 329 Identity x = new Identity(); 330 x.seed = seed; 331 x.increment = increment; 332 x.notForReplication = notForReplication; 333 return x; 334 } 335 } 336 337 public string computeAlias() { 338 string alias_p = null; 339 340 if (cast(SQLIdentifierExpr)(name) !is null) { 341 alias_p = (cast(SQLIdentifierExpr) name).getName(); 342 } else if (cast(SQLPropertyExpr)(name) !is null ) { 343 alias_p = (cast(SQLPropertyExpr) name).getName(); 344 } 345 346 return SQLUtils.normalize(alias_p); 347 } 348 349 override public SQLColumnDefinition clone() { 350 SQLColumnDefinition x = new SQLColumnDefinition(); 351 x.setDbType(dbType); 352 353 if(name !is null) { 354 x.setName(name.clone()); 355 } 356 357 if (dataType !is null) { 358 x.setDataType(dataType.clone()); 359 } 360 361 if (defaultExpr !is null) { 362 x.setDefaultExpr(defaultExpr.clone()); 363 } 364 365 foreach (SQLColumnConstraint item ; constraints) { 366 SQLColumnConstraint itemCloned = item.clone(); 367 itemCloned.setParent(x); 368 x.constraints.add(itemCloned); 369 } 370 371 if (comment !is null) { 372 x.setComment(comment.clone()); 373 } 374 375 x.enable = enable; 376 x.validate = validate; 377 x.rely = rely; 378 379 x.autoIncrement = autoIncrement; 380 381 if (onUpdate !is null) { 382 x.setOnUpdate(onUpdate.clone()); 383 } 384 385 if (storage !is null) { 386 x.setStorage(storage.clone()); 387 } 388 389 if (charsetExpr !is null) { 390 x.setCharsetExpr(charsetExpr.clone()); 391 } 392 393 if (asExpr !is null) { 394 x.setAsExpr(asExpr.clone()); 395 } 396 397 x.sorted = sorted; 398 x.virtual = virtual; 399 400 if (identity !is null) { 401 x.setIdentity(identity.clone()); 402 } 403 404 return x; 405 } 406 407 public string getDbType() { 408 return dbType; 409 } 410 411 public void setDbType(string dbType) { 412 this.dbType = dbType; 413 } 414 415 public void simplify() { 416 enable = Boolean.FALSE; 417 validate = Boolean.FALSE; 418 rely = Boolean.FALSE; 419 420 421 if (cast(SQLIdentifierExpr)(this.name) !is null ) { 422 SQLIdentifierExpr identExpr = cast(SQLIdentifierExpr) this.name; 423 string columnName = identExpr.getName(); 424 string normalized = SQLUtils.normalize(columnName, dbType); 425 if (normalized != columnName) { 426 this.setName(normalized); 427 } 428 } 429 } 430 431 public bool containsNotNullConstaint() { 432 foreach (SQLColumnConstraint constraint ; this.constraints) { 433 if (cast(SQLNotNullConstraint)(constraint) !is null ) { 434 return true; 435 } 436 } 437 438 return false; 439 } 440 441 public bool isPrimaryKey() { 442 foreach (SQLColumnConstraint constraint ; constraints) { 443 if (cast(SQLColumnPrimaryKey)(constraint) !is null ) { 444 return true; 445 } 446 } 447 448 if (cast(SQLCreateTableStatement)(parent) !is null ) { 449 return (cast(SQLCreateTableStatement) parent) 450 .isPrimaryColumn(nameHashCode64()); 451 } 452 453 return false; 454 } 455 456 override public string toString() { 457 return SQLUtils.toSQLString(this, dbType); 458 } 459 }